为什么不指向字母C?

时间:2018-12-22 17:14:24

标签: c

我想向后读取我的字符串。我这样做了,但是我不明白我的代码的两个部分是如何工作的。

char s1[] = "ABC";
printf("%s", s1);
size_t len = strlen(s1);
printf("\n%d", len);

char *t = s1 + len - 1;
printf("\n%s\n", t);

while (t>=s1)
{
    printf("%c", *t);
    t = t - 1;
}
  • 首先:t如何指向字母C?
  • 第二:如何添加包含整数的变量len和包含文字的数组?是因为指针t通过使用指针算术来添加其地址吗?

3 个答案:

答案 0 :(得分:4)

char s1[] = "ABC";

看起来像

 0x100   0x101  0x102   0x103 . . . .Assume 0x100 is base address of s1
 --------------------------------
|   A   |   B   |   C   |   \0   |
 --------------------------------
s1

这里s1是char数组,指向基地址0x100(假设)。

  

我想反向读取我的字符串吗?

为此,您需要有人指向0x102位置,即数组的最后一个元素

size_t len = strlen(s1); /* finding length of array s1 i.e it returns 3 here */
char *t = s1 + len - 1; /* (0x100 + 3*1) - 1 i.e char pointer t points to 0x102 */

编写了两行以上的代码。现在看起来像

 0x100   0x101  0x102   0x103 . . . . 
 --------------------------------
|   A   |   B   |   C   |   \0   |
 --------------------------------
s1                  t <-- t points here

现在,当您执行*t时,它将在t位置打印char值,即在0x102处的值,即打印C,在下一个迭代中,您需要打印将一个字符返回一个位置,因此您正在做t = t - 1;

注意:此处

char *t = s1 + len - 1;

s1字符指针,而len整数变量,因此在进行指针算术它会自动增加指针指向的数据大小。对于例如

char *t = s1 + len;

评估为

t = 0x100 + 3*sizeof(*s1); ==> 0x100 + 3*1  ==> 0x103

答案 1 :(得分:2)

char s1[] = "ABC";

s1是由4个字符组成的数组char[4],值{'A','B','C','\0'}

size_t len = strlen(s1);

s1从类型数组到类型指针的“衰减”(读取:自动转换)。因此s1从4个字符的数组衰减为指向数组第一个字符的指针。

strlen在遇到空字节定界符'\0'之前先对字节数进行计数。从'A'开始,我们可以算出'A''B''C'

C中的指针是普通整数(好的,在大多数体系结构上)。您可以添加它们并减去它们,并使用len = 3将它们转换为整数。但是在不进行强制转换的情况下添加它们将使用“指针算术”,这意味着uintptr_t的值等于(int*)5 + 2

5 + 2 * sizeof(int)

char *t = s1 + len - 1;衰减到指向s1数组中第一个字符即s1的指针。我们添加'A',这意味着+ (len = 3)指向s1 + 3数组中保存'\0'的字节。然后我们减去s1 = (char[4]){'A','B','C','\0'},因此- 1现在指向在t数组中包含字符'C'的字节。

s1

开始:while (t >= s1) { ... *t ... t = t - 1; } 指向s1'A'指向t
而:'C'大于t。由两个。 s1,即。 t - s1 = 2 循环:s1 + 2 = t等于*t
减量:'C',所以现在t--将指向t
而:'B'大于t。通过onw。
循环:s1等于*t
递减:然后'B',所以现在t--将指向t
while:现在'A'等于t。两者都指向数组的第一个字符。
循环:s1等于*t
减量:然后'B',所以现在t--将指向数组之前的未知位置。作为指针
 (在大多数体系结构上)是简单的整数,您可以将其作为普通变量进行减量和增值。
同时:t现在低于t。循环终止。

注意:

  • s1是未定义的行为,并产生nasal demons。使用printf("\n%d", len);打印一个printf("\n%zu", len);变量。
  • 您可以通过使用size_t说明符并强制转换为void %p来打印指针值
  • printf("%p", (void*)t)。在数组中为数组之前的一个元素分配指针是C中的未定义行为。这发生在循环t = s1 - 1的结束条件中。更改为t = t - 1循环。

答案 2 :(得分:1)

在语言中,C数组有点奇怪。在x数组处,可以很容易地退化为x指针。例如,如果传递给另一个例程,或者如您所愿,则添加到该例程。所以你是对的,它是指针运算。 (在指针算术中,您可以添加指针和整数以获取指针。)