[英]Printing address a pointer points to, value the address points to, and the address of the pointer itself
I wrote a little program to familiarize myself with pointers and relations between them a little more. 我编写了一个小程序,以使自己熟悉指针和指针之间的关系。 In order to do this I wrote a small piece of code that just declares and initializes an integer
a
, then declares a pointer *p
to the address of a
and then goes on deeper to assign a pointer to a pointer *pp
and so on so far up to ****pppp
. 为了做到这一点,我写了一个小的一段代码,只是声明和初始化一个整数
a
,然后宣布指针*p
到的地址, a
然后继续更深的指针赋值给一个指针*pp
等等等等高达****pppp
。 If I understood pointers correctly a pointer to a pointer to a ... basically works like this: 如果我正确理解了指针,则指向...的指针的指针基本上是这样的:
Address of pointer (or integer) itself: 0x7fff08d1c658 0x7fff08d1c660 0x7fff08d1c668 0x7fff08d1c670 0x7fff08d1c67c
↑ ↑ ↑ ↑ ↑
pppp --> ppp --> pp --> p --> a = 42
↓ ↓ ↓ ↓
Address pointer points to: 0x7fff08d1c660 0x7fff08d1c668 0x7fff08d1c670 0x7fff08d1c67c
The addresses on the diagonal have to be identical because the previous pointer always points to the address of the next pointer which it has been assigned. 对角线上的地址必须相同,因为前一个指针始终指向已分配的下一个指针的地址。 Now I want to check this in a program using
printf()
calls and here I am unsure if the way I print the address the more elaborate pointers **pp
, ***ppp
, and ****pppp
point to and how I print the addresses of these pointers themselves are correct. 现在,我想在使用
printf()
调用的程序中检查此内容,在这里我不确定是否以更复杂的指针**pp
, ***ppp
和****pppp
指向地址的方式打印地址以及我如何打印这些指针本身的地址是正确的。 Could someone point out possible mistakes? 有人可以指出可能的错误吗? Here is the code followed by its output:
以下是代码及其输出:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
int *p;
int **pp;
int ***ppp;
int ****pppp;
a = 42;
/* Take the address of a */
p = &a;
/* Take the address of p */
pp = &p;
/* Take the address of pp */
ppp = &pp;
/* Take the address of ppp */
pppp = &ppp;
printf("Address of int &a: %p\n", &a);
printf("value of a: %d\n\n", a);
printf("Address where p points to via (void *)p: %p\n", (void *)p);
printf("Value that *p points to via *p: %d\n", *p);
printf("Address of *p itself via (void *)&p: %p\n\n", (void *)&p);
printf("Address where pp points to via (void *)pp: %p\n", (void *)pp);
printf("Value that **pp points to via **pp: %d\n", **pp);
printf("Address of **pp itself via (void *)&pp: %p\n\n", (void *)&pp);
printf("Address where ppp points to via (void *)ppp: %p\n", (void *)ppp);
printf("Value that ***ppp points to via ***ppp: %d\n", ***ppp);
printf("Address of ***ppp itself via (void *)&ppp: %p\n\n", (void *)&ppp);
printf("Address where pppp points to via (void *)pppp: %p\n", (void *)pppp);
printf("Value that ****pppp points to via ****pppp: %d\n", ****pppp);
printf("Address of ****pppp itself via (void *)&pppp: %p\n", (void *)&pppp);
return EXIT_SUCCESS;
}
Output: 输出:
Address of int &a: 0x7fff08d1c67c
value of a: 42
Address where p points to via (void *)p: 0x7fff08d1c67c
Value that *p points to via *p: 42
Address of *p itself via (void *)&p: 0x7fff08d1c670
Address where pp points to via (void *)pp: 0x7fff08d1c670
Value that **pp points to via **pp: 42
Address of **pp itself via (void *)&pp: 0x7fff08d1c668
Address where ppp points to via (void *)ppp: 0x7fff08d1c668
Value that ***ppp points to via ***ppp: 42
Address of ***ppp itself via (void *)&ppp: 0x7fff08d1c660
Address where pppp points to via (void *)pppp: 0x7fff08d1c660
Value that ****pppp points to via ****pppp: 42
Address of ****pppp itself via (void *)&pppp: 0x7fff08d1c658
Your code is mostly correct: you understand that printf
prints the value of pointers with the %p
conversion specifier. 您的代码大部分是正确的:您了解
printf
使用%p
转换说明符打印指针的值。 The actual output is implementation specific but can be parsed back into a pointer value by scanf
with the same %p
specifier. 实际输出是特定于实现的,但可以由
scanf
使用相同的%p
说明符将其解析回指针值。
There is one small detail you got wrong in printf("Address of int &a: %p\\n", &a);
您在
printf("Address of int &a: %p\\n", &a);
有一个小错误printf("Address of int &a: %p\\n", &a);
: pointers should always be converted to void *
when passed to printf
as the value to convert for the %p
specifier. :指针在传递给
printf
作为%p
说明符要转换的值时,应始终转换为void *
。 The reason for this is subtle: on some architectures, pointers to different types may have a different representation, including a different size, and may be passed to printf
in a different way. 这样做的原因很微妙:在某些体系结构上,指向不同类型的指针可能具有不同的表示形式,包括不同的大小,并且可能以不同的方式传递给
printf
。 Converting the pointer to void *
ensures that it will be passed in the form and manner expected by the printf
function. 将指针转换为
void *
可确保以printf
函数期望的形式和方式传递指针。
This conversion is not automatic as printf
takes a variable number of arguments of different types, these arguments are passed in a manner specific to vararg
functions: for instance float
values are converted to and passed as double
, but various pointer types are not converted to void *
, so you must write this conversion explicitly with a (void *)
cast. 这种转换不是自动的,因为
printf
接受可变数量的不同类型的参数,这些参数以特定于vararg
函数的方式传递:例如, float
值被转换为double
并作为double
传递,但是各种指针类型不会转换为void *
,因此您必须使用(void *)
强制转换显式编写此转换。
Examples of architectures with different pointer representations tend to be less popular nowadays, but older programmers may remember the days of near
and far
pointers and the various memory models where function and data pointers had a different size. 如今,具有不同指针表示形式的体系结构示例趋于不那么流行,但是年龄较大的程序员可能会记得
near
指针和far
指针以及功能和数据指针具有不同大小的各种内存模型的时代。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.