【问题标题】:Why isn't the address of consecutive array entries, also consecutive?为什么连续数组条目的地址也不连续?
【发布时间】:2016-02-06 17:18:03
【问题描述】:

当我跑步时

char * a = "string";
char * b = a;
while (*a != '\0')
    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。我以为它只是将 b 的起始地址加 2,在本例中为 0x73。

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

【问题讨论】:

  • ...这可能是因为未定义的行为!
  • @Olaf;不完全是。它有一些新的东西。
  • @hacks:太糟糕了,我们只能显示一个副本。随意在格式字符串中为错误的类型说明符添加 UB :-)
  • 查看ASCII-table 并与您显示的输出进行比较。注意到什么了吗?

标签: c arrays pointers pointer-arithmetic


【解决方案1】:

试试

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

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

你的代码出了什么问题:

  • 当您编写*(a) 时,您将当前字符的 而不是其地址传递给printf,然后printf 将其打印为指针;您看到的十六进制值是"string" 字符的字符代码,而不是它们的地址(请注意,将格式字符串中预期的不同参数传递给printf 是未定义的行为,它产生了一些合理的输出这一事实是偶然的);
  • 第二个printf也受到同样的错误影响;
  • 您会注意到,这里我还在单独的语句中分隔了增量;正如 hacks 所指出的,因为它们最初是你也有 another 未定义行为的原因,因为函数调用不会在其参数的评估之间引入序列点;这意味着不确定首先评估哪个,因此评估 a 是否在 printf 的第二个参数之前或之后递增。
  • 不推荐使用char * 而不是const char * 指向字符串字面量的指针;

【讨论】:

  • @hacks:对不起,我一开始错过了。感谢您指出。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 2019-11-23
    • 2013-01-14
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    相关资源
    最近更新 更多