简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM