为什么连续数组条目的地址不是连续的?

Why isn't the address of consecutive array entries, also consecutive?

当我运行

char * a = "string";
char * b = a;
while (*a != '[=10=]')
    printf("%p %c\n", *(a), *(a++));
printf("%p\n", *(b+2));

输出看起来像

0x73 s
0x74 t
0x72 r
0x69 i
0x6e n
0x67 g
0x72

另外,程序是如何计算出(b+2)位于0x72的。我认为它只会将 2 添加到 b 的起始地址,在本例中为 0x73.

编辑:这不是未指定行为的案例。如答案中所述,我错误地将值传递给地址格式说明符而不是指针本身。

尝试

printf("%p %c\n", (void *)a, *a);
a++;

庆幸,连续的元素实际上是连续的!

你的代码有什么问题:

  • 当你写 *(a) 时,你传递给 printf 当前字符的 而不是它的地址,然后由 printf 就好像它是一个指针;您看到的十六进制值是 "string" 字符的字符代码而不是它们的地址(请注意,从格式字符串中传递给 printf 不同的参数是未定义的行为,它产生了某种程度的事实合理的输出是偶然的);
  • 第二个 printf 也受到相同错误的影响;
  • 你会注意到,在这里我还将增量分隔在一个单独的语句中;正如 haccks 所指出的那样,正如他们最初所指出的那样,你还有 另一个 未定义行为的原因,因为函数调用不会在评估其论点;这意味着它是未定义的,首先评估哪个,因此 a 是在评估 printf 的第二个参数之前还是之后递增。
  • 不推荐使用 char * 而不是 const char * 作为指向字符串文字的指针;

您打印的不是地址,而是字符。 a 是地址,*a 是存储在该地址的值(char 类型)。 0x73是小写's'ASCII code等。

如果您想打印地址,那么您的代码应该如下所示:

char * a = "string";
char * b = a;
while (*a != '[=10=]') {
    printf("%p %c\n", a, *a));       // address and value (char)
    a ++;
}

此外,printf("%p\n", *(b+2)); 打印 b[2] 的小写值 'r' (ASCII code 0x72)