【问题标题】:print the memory location of a variable (or pointer)打印变量(或指针)的内存位置
【发布时间】:2013-12-20 21:51:36
【问题描述】:

我想打印变量的存储位置。我谷歌了它,我发现了这个:

int *p;
printf("memory location of ptr: %p\n",  (void *)p);

如果我写这个,对吗?

printf("memory location of ptr: %p\n",  &p);

我编译了它,没有收到任何错误或警告。但是,上面两个命令返回的值不一样!

【问题讨论】:

    标签: c variables pointers memory-address


    【解决方案1】:

    假设你有这些声明:

    int i;
    int *p = &i;
    

    它在内存中看起来像这样:

    +---+ +---+ | p | --> |我 | +---+ +---+

    如果你然后使用&p,你会得到一个指向p的指针,所以你有这个:

    +----+ +---+ +---+ | &p | --> | p | --> |我 | +----+ +---+ +---+

    所以p的值就是i的地址,&p的值就是p的地址。这就是为什么你会得到不同的值。

    【讨论】:

    • 让我们总结一下:(void *)p 打印指针显示的对象的内存位置,&p 显示指针本身的内存位置。对吗?
    • 好的,那么接下来的问题!由于 p 的值是他显示的对象的内存地址。我不能只打印 p 的值吗?像那样printf("%s", p);(我运行它但我收到格式'%s'的警告,需要'char *'类型的参数,但参数2的类型为'int *'所以我猜是不对的......
    • @Nat95 因为p 指向int,你当然必须打印一个整数(开始),并得到p 指向你必须使用的值解引用运算符*printf("%d\n", *p); 也是如此
    【解决方案2】:

    如果我写这个,对吗?

    没有。这个不对。对于%p 说明符,您必须将其转换为void *。你的编译器应该给warning这个:

    warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int **’ [-Werror=format=]  
    

    阅读此answer。它说:

    %p 格式需要void* 类型的参数。如果int*int(*)[10] 类型的指针具有与void* 相同的表示形式,并且以相同的方式作为参数传递,就像大多数实现的情况一样,它可能会起作用,但不能保证。您应该将指针显式转换为void*

    草案 n1570; 7.21.6 格式化输入/输出函数:

    p 参数应该是指向void 的指针。指针的值为 在实现定义中转换为打印字符序列 方式。


    但是如果我将这两个语句都放在程序中,它们不会返回相同的值。

    是的,它不会返回相同的值。 P 将为您提供变量p 指向(pointee)的地址值,而&p 将为您提供指针p 本身的地址值。将&p 转换为void *

    printf("memory location of ptr: %p\n",  (void *)&p);  
    

    【讨论】:

    • 好的,但为什么我没有收到任何警告? (我通过 VirtualBox 使用 ubuntu)
    • 在 C 中,所有指针都可以隐式转换为 void *,反之亦然。
    • 在编译器设置中启用 Wextra 标志。
    • @JoachimPileborg;你能详细说明一下吗?
    • 例如,free 采用 void * 参数,但您不必强制转换它。以及 malloc 返回一个 void * 但您也不必强制转换它。实际上,您不应该 不强制转换void * 参数并返回,因为当函数未正确声明时,这可能会隐藏细微的错误。也就是说,这在 C 中是这样的,在 C++ 中你必须强制转换。
    【解决方案3】:

    如果在指针上使用“&”运算符,则创建指向该指针的指针。因此,您的结果将是 int**。

    当您使用 %p 说明符时,

    printf 需要一个 void*,因此第一种方法是正确的。

    【讨论】:

      【解决方案4】:

      正如您所发现的,两者做的事情不同。

      第一个将打印存储在p 中的值。您通常会认为这是int 的地址(尽管人们会做最糟糕的事情)。

      第二个将打印p的地址。但是,出于可移植性的原因,您需要向void * 添加一个演员表,所以第二个应该是

      printf("memory location of ptr: %p\n", (void *)&p);
      

      我想打印变量的存储位置。

      所以你的问题的答案取决于你关心的变量是什么?对于p 指向的int,您要使用第一个。对于变量p 本身,您想使用第二个。

      【讨论】:

        【解决方案5】:
        #include <stdio.h>
        
        int main()
        {
            int i;
            int *x = &i;
        
            i = 8;
            printf("value of i is %d\n",i);
            printf("value of x is %d\n", *x);
            printf("address of x is %p\n",x);
            printf("address of i is %p\n",&i);
        }
        

        输出:

        ~/workspace/C$ ./test

        i 的值为 8

        x 的值为 8

        x的地址是0x7fff793b09c4

        i的地址是0x7fff793b09c4

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-27
          • 2017-02-16
          • 2021-05-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多