我写了一个小程序来熟悉它们之间的指针和关系。为了做到这一点,我写了一小段代码,只是声明并初始化一个整数a
,然后向*p
的地址声明一个指针a
,然后继续深入分配到指针*pp
的指针,依此类推到目前为止****pppp
。如果我正确理解指针,指向指向...的指针基本上就像这样:
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
对角线上的地址必须相同,因为前一个指针始终指向已分配的下一个指针的地址。现在我想在使用printf()
调用的程序中检查这一点,在这里我不确定我打印地址的方式是更精细的指针**pp
,***ppp
和****pppp
指向以及如何打印这些指针的地址本身是正确的。有人能指出可能的错误吗?以下是输出后面的代码:
#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;
}
输出:
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
答案 0 :(得分:2)
您的代码大多是正确的:您了解printf
使用%p
转换说明符打印指针的值。实际输出是特定于实现的,但可以通过scanf
使用相同的%p
说明符解析回指针值。
printf("Address of int &a: %p\n", &a);
中出现了一个小错误:指针在传递给void *
时应始终转换为printf
作为转换为%p
说明符的值。其原因很微妙:在某些体系结构上,指向不同类型的指针可能具有不同的表示形式,包括不同的大小,并且可能以不同的方式传递给printf
。将指针转换为void *
可确保它以printf
函数所期望的形式和方式传递。
此转换不是自动的,因为printf
采用不同类型的可变数量的参数,这些参数以特定于vararg
函数的方式传递:例如,float
值被转换以double
传递并传递,但各种指针类型未转换为void *
,因此您必须使用(void *)
强制转换显式编写此转换。
具有不同指针表示的体系结构的示例现在往往不那么受欢迎,但是较老的程序员可能记住near
和far
指针的日子以及函数和数据指针具有不同的各种内存模型尺寸。