&p 和 p 有什么区别

What is the difference between &p and p

如果我有一个指向整数的指针,例如:

int num = 12;
int *p = #

然后打印地址所以

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

上一个和这个有什么区别:

printf("%p\n", (void*)&p);

(void*)&p 表示 p.

地址

(void*)p 表示 p 的 contents(在本例中是 numaddress)。

(void*)*p表示变量p指向的内容(12)(value[= num 的 32=]。

有关地址运算符的更多详细信息,请参阅http://www.c4learn.com/c-programming/c-pointer-address-operator/

对于"%p"格式,仅使用普通p将打印变量p的内容,即指针变量p指向的地址.

当你使用 &p 时,你会得到变量 p 的地址,即指向 p 的指针(在你的类型 int ** 的情况下)并打印它指针。

你可以这样看:

+----+    +---+    +-----+
| &p | -> | p | -> | num |
+----+    +---+    +-----+

换句话说,&p指向p,后者指向num


如果您继续并尝试使用 *p,那将不会像您预期的那样工作。它将取消引用指针 p,即它会导致 p 所在位置的值是指针(在这种特定情况下,变量 num 及其值)。 *p 是类型 int 的值,尝试使用格式 "%p" 打印它会导致 未定义的行为 ,因为 *p 不是一个指针而是一个值,"%p" 格式需要一个指针。

很可能不会发生任何坏事,并且在指针大小与 int 大小相同的系统上(这是大多数 32 位系统)然后声明

printf("%p", (void *) *p);

只会打印 c,这是十六进制值 12,这是 num.

的值

然而,如果指针的大小 int 的大小不同 而不是 ,就像在典型的 64 位系统上一样,那么输出将不是可预测的,而且大部分看起来完全是随机的。

前者打印num的地址。 后者打印指针 p 的地址。 因为,一切都需要在内存中存储一​​个位置。

如果取整数, 它有一个存储它的物理地址,以及存储在该位置的数据(整数)。

如果你拿个指点, 它也有一个存储在内存中的物理地址,但这里的数据变成了另一个地址,即某个整数变量的地址。

& 称为操作员地址。它 returns 存储特定变量的内存地址。 按照同样的例子,

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

打印指针p指向的数据。即,num 的地址。

使用

可以获得类似的结果

printf("%p\n", (void*)&num);

因此,两者将产生相同的结果。

然而,

printf("%p\n", (void*)&p);

打印指针p的地址。

以你为例-

int num = 12;
int *p = #                     // store address of num in pointer p
printf("%p\n", (void*)p);          // line 1
printf("%p\n", (void*)&p);         // line 2

第 1 行- 在此它将打印存储在指针 p 中的变量 num 的地址。因此,指针 p 中存储的值是整型变量 num 的地址。

第 2 行 - 指针 p 本身的地址将被打印出来。注意 address of operator 的使用。它给出指针的地址 p.

这里,p包含num的地址,所以第一个printf输出num的地址。

另一方面,&pp的地址,所以第二个printf打印p的地址。

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

打印p包含的值,即num的地址。

printf("%p\n", (void*)&p);

打印指针 p 本身的地址。

您可以在 c/c++ 函数中传递两种类型的参数。

第一个是按值调用,它在程序中调用类似 (void)p 的东西,它复制相同的值,并且该特定 void 函数中的值不会改变。

第二个是引用调用,它实际上进入内存并找出特定的 location/address 并在那里更改其值。这是你的情况 (void)&p