我想打印存储变量的位置。我谷歌它,我发现了这个:
int *p;
printf("memory location of ptr: %p\n", (void *)p);
如果我写这个,是不是?
printf("memory location of ptr: %p\n", &p);
我编译了它,但没有收到任何错误或警告。但是,上面两个命令没有返回相同的值!
答案 0 :(得分:7)
让我们说你有这些声明:
int i;
int *p = &i;
在内存中看起来像这样:
+---+ +---+ | p | --> | i | +---+ +---+
如果你然后使用&p
,你会得到一个指向p
的指针,所以你有这个:
+----+ +---+ +---+ | &p | --> | p | --> | i | +----+ +---+ +---+
因此p
的值是i
的地址,而&p
的值是p
的地址。这就是为什么你得到不同的价值观。
答案 1 :(得分:3)
如果我写这个,是不是?
没有。这个不对。对于%p
说明符,您必须将其强制转换为void *
。你的编译器应该给出warning这个:
warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int **’ [-Werror=format=]
阅读此answer。它说:
%p
格式需要void*
类型的参数。如果类型int*
和int(*)[10]
的指针具有与void*
相同的表示,并以相同的方式作为参数传递,就像大多数实现的情况一样,它可能会起作用,但它是不保证。您应该明确地将指针转换为void*
p参数应该是指向
void
的指针。指针的值是 转换为一系列打印字符,在实现定义中 方式。
但如果我将这两个语句都放在程序中,则这两个语句不会返回相同的值。
是的,它不会返回相同的值。 P
将为您提供变量p
的地址值(指向者),而&p
将为您提供指针p
本身的地址值。将&p
投射到void *
。
printf("memory location of ptr: %p\n", (void *)&p);
答案 2 :(得分:1)
如果您使用“&”在指针上运算符,您创建指针指针。因此,您的案例结果将是一个int **。
printf 在使用%p说明符时需要void *,因此第一种方法是正确的。
答案 3 :(得分:0)
正如你所发现的那样,两者并没有做同样的事情。
第一个将打印存储在p
中的值。你通常会认为这是int
的地址(尽管人们做的事情最多)。
第二个将打印p
的地址。但是,出于可移植性原因,您需要向void *
添加强制转换,因此第二个应该读取
printf("memory location of ptr: %p\n", (void *)&p);
我想打印存储变量的位置。
所以你问题的答案取决于你所关注的变量?对于int
p
指向您要使用的第一个p
。对于变量{{1}}本身,您想要使用第二个。
答案 4 :(得分:0)
#include <stdio.h>
int main()
{
int i;
int *x = &i;
i = 8;
printf("value of i is %d\n",i);
printf("value of x is %d\n", *x);
printf("address of x is %p\n",x);
printf("address of i is %p\n",&i);
}
输出:
〜/ workspace / C $ ./test
i的值是8
x的值是8
x的地址是0x7fff793b09c4
i的地址是0x7fff793b09c4