【问题标题】:Difference between printing pointer address and ampersand address打印指针地址和和号地址的区别
【发布时间】:2014-09-12 09:01:42
【问题描述】:
int firstInt =10;
int *pointerFirstInt = &firstInt;


printf("The address of firstInt is: %u", &firstInt);
printf("\n");
printf("The address of firstInt is: %p", pointerFirstInt);
printf("\n");

以上代码返回如下:

The address of firstInt is: 1606416332
The address of firstInt is: 0x7fff5fbff7cc

我知道0x7fff5fbff7cc 是十六进制的,但是当我尝试将该数字转换为十进制时,它不等于1606416332。为什么是这样?两者不应该返回相同的内存地址吗?

【问题讨论】:

  • %uunsigned int 格式,长度可能为 32 位。您的指针显然大于 32 位...您应该在两次调用 printf() 时使用 %p 格式。
  • 0x7fff5fbff7cc - 1606416332 == 0x7fff5fbff7cc - 0x5fbff7cc == 0x7fff00000000

标签: objective-c c pointers memory-address


【解决方案1】:

原因就在这里:

C11:7.21.6:

如果转换规范无效,行为未定义288) 如果任何参数是 不是相应转换规范的正确类型,行为是 未定义。

【讨论】:

    【解决方案2】:

    来自您的十六进制地址-

    The address of firstInt is: 0x7fff5fbff7cc
    

    地址的大小为 6 个字节长。但是unsignedint 的大小是 4 个字节。当您尝试使用%u 打印地址时,会导致未定义的行为。

    所以总是使用%p打印地址。

    【讨论】:

    • 那么,不使用指针,这个printf("The address of firstInt is: %p", &firstInt); 是否正确?
    • @JustinO'Brien 是的!这是正确的!但是从您的问题来看,如果您想使用%lu 打印并将其转换为十六进制并查看。
    【解决方案3】:

    看来您正在使用 64 位机器。所以你的指针是 64 位长的

    两者(&firstIntpointerFirstInt)完全相同。但显示方式不同。 "%p" 知道指针是 64 位的,并以十六进制显示。 "%u" 显示十进制数并假定为 32 位。所以只显示了一部分。

    如果您将1606416332 转换为十六进制,它看起来像:0x5FBFF7CC。你看这是64位地址的下半部分。

    编辑: 进一步解释:

    因为 printf 是一个 var-arg 函数,所以你给它的所有参数都放在了堆栈上。因为你在这两种情况下都放了 8 个字节。由于PC使用小端序,因此首先将较低的字节放在上面。 printf 函数解析字符串并到达%[DatatypeSpecifier] 点并从堆栈中读取与DatatypeSpecifier 引用的数据类型所需的一样多的字节。所以在"%u" 的情况下,它只读取 4 个字节并忽略其他字节。由于您写的是"%u" 而不是"%x",它以十进制而不是十六进制形式显示值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多