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
。为什么是这样?两个都不应该返回相同的内存地址吗?
答案 0 :(得分:2)
原因在于:
如果转换规范无效,行为未定义。 288)如果有任何参数是 不是相应转换规范的正确类型,行为是 未定义。
答案 1 :(得分:1)
从您的十六进制地址 -
The address of firstInt is: 0x7fff5fbff7cc
地址大小为6个字节。但是unsignedint
的大小是4个字节。当您尝试使用%u
打印地址时,它将导致未定义的行为。
因此,请始终使用%p
打印地址。
答案 2 :(得分:1)
您似乎正在使用64位计算机。所以你的指针是64位长
两者(&firstInt
和pointerFirstInt
)完全相同。但显示方式不同。
"%p"
知道指针是64位并以十六进制显示。 "%u"
显示十进制数并假设为32位。所以只显示了一部分。
如果您将1606416332
转换为十六进制,则看起来像:0x5FBFF7CC
。你看,这是64位地址的下半部分。
编辑: 进一步解释:
因为printf是var-arg函数,所以你给它的所有参数都放在堆栈上。因为你在两种情况下都放了8个字节。因为Pcs使用小端,所以首先放置较低的字节。
printf函数解析字符串并进入%[DatatypeSpecifier]
点,并从堆栈中读取与DatatypeSpecifier所需的数据类型一样多的字节。因此,在"%u"
的情况下,它只读取4个字节并忽略其他字节。由于您编写了"%u"
而不是"%x"
,因此它以十进制形式显示值,而不是十六进制格式。