这是一个例子
#include <stdio.h>
int main()
{
int a;
printf("%d\n",&a);
printf("%p\n",&a);
return 0;
}
======输出=======
-2054871028
0x7ffd8585280c
这两个地址是否指向RAM中的相同地址?
我如何通过使用它们中的每一个,特别是第二个来获得价值。
答案 0 :(得分:3)
%d
格式说明符用于输出带符号的十进制整数。
来自C标准#7.21.6.1p8
d,i
int参数将以[-] dddd格式转换为带符号的十进制。精度指定出现的最小位数;如果要转换的值可以用较少的数字表示,则将其扩展为前导零。默认精度为1。精度为零的零值转换结果为无字符。
%p
打印指针。
来自C标准#7.21.6.1p8
p
该参数应为指向void的指针。指针的值以实现定义的方式转换为一系列打印字符。 [强调我的]
此声明
printf("%d\n",&a);
导致不确定的行为,因为%d
对于打印指针无效。
来自C标准#7.21.6.1p9
如果转换规范无效,则行为是不确定的。282)如果任何参数不是对应转换规范的正确类型,则行为是不确定的。
答案 1 :(得分:1)
当您通过编写a
来获取变量&a
的地址时,您实际上所做的就是生成指向a
的 pointer 。
%p
设计用于打印指针。您应该使用%p
打印指针。
%d
不适用于打印指针。它尝试将其值打印为带符号的十进制数,这可能会造成混淆(如您所见),并且在指针大于整数的机器上,它可能不会打印完整的值。 (例如,如果您尝试在大多数“ 64位”环境中使用%d打印指针,则可能会得到更奇怪的结果-这可能是此处发生的情况的一部分。)
这是一个容易犯的错误。好的编译器应该警告您。我的话说:“警告:格式指定类型为'int',但参数类型为'int *'”。
但是,是的,0x7ffd8585280c
和-2054871028
都“指向RAM中的相同地址”,因为它们都是相同的数字,相同的地址。 (好吧,他们试图成为相同的地址。请参见下面的脚注。)
我不确定您的意思是“以及如何获得价值”。您是要获取指针的值还是指针指向的值?
您已经有了指针的值-它是地址0x7ffd8585280c
。并且由于我们知道它指向变量a
,所以我们也知道它指向的值。如果这样做,事情将会更加清楚:
int a = 5;
int *ip = &a;
printf("value of pointer: %p\n", ip);
printf("pointed-to value: %d\n", *ip);
没有显式指针变量ip
,我们可以编写
int a = 5;
printf("value of pointer: %p\n", &a);
printf("pointed-to value: %d\n", *&a);
但这很愚蠢,因为最后一行等效于更直接的
printf("pointed-to value: %d\n", a);
(使用&
来获取变量的地址,然后使用*
来获取指针的内容是没有操作的:这很像编写a + 1 - 1
。)< / p>
脚注:我说过0x7ffd8585280c
和-2054871028
是相同的数字,但它们不是,只是想成为。 0x7ffd8585280c
实际上是-140748133160948
,而-2054871028
实际上是0x8585280c
,是0x7ffd8585280c
的低8位数字。看来您机器上的%p
默认情况下将指针打印为48位值。令我感到惊讶的是,但是后来我意识到我的Mac也做同样的事情。不知何故我从来没有注意到。