指针指向的打印地址,指向地址的值,以及指针本身的地址

时间:2015-05-12 06:36:24

标签: c pointers

我写了一个小程序来熟悉它们之间的指针和关系。为了做到这一点,我写了一小段代码,只是声明并初始化一个整数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

1 个答案:

答案 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 *)强制转换显式编写此转换。

具有不同指针表示的体系结构的示例现在往往不那么受欢迎,但是较老的程序员可能记住nearfar指针的日子以及函数和数据指针具有不同的各种内存模型尺寸。