如何在C程序中打印指针地址?

zak*_*zak 1 c pointers

我正在尝试学习如何(使用)C程序中的指针; 我的例子如下:

   #include <stdio.h>
   #include <stdlib.h>

   int main(int argc, char *argv[]) {
        int * tab = (int*)malloc(sizeof(int)*5);
        int a =10;
        int *p;
        p  = &a;
        printf("the adress of a is%d \n",&a);    
        printf("the adress of a using the pointer is%p \n",p);    
        printf("the adress of tab is%d \n",tab);    
    }
Run Code Online (Sandbox Code Playgroud)

我正在尝试打印地址a,开头p的第一个字节的地址和位置tab.

我在使用时可以获得十六进制值"%p",但我愿意使用地址的十进制值.

编辑:在这个视频 图像上,有人用来"%d"打印指针地址的十进制值,这让我很困惑.

chu*_*ica 10

要打印对象指针的十进制版本,首先将指针转换为整数.最好使用可选类型uintptr_t.

以下type(uintptr_t)指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型(uintptr_t)...C11dr§7.20.1.41

#include <inttypes.h>
uintptr_t d = (uintptr_t)(void *) &a;
Run Code Online (Sandbox Code Playgroud)

然后打印出来.
有关PRIuPTR的一些信息

printf("%" PRIuPTR "\n", d);
Run Code Online (Sandbox Code Playgroud)

对于C99之前的代码,请考虑直接转换为unsigned long. @Barmar


OP后来评论道

"...我将尝试操纵tab变量,我将测试标签中的每个单元格是否为4字节,因此我可能会使用tab + 8字节来获取特定单元格的值,这里它很简单例如,带小数对我来说很容易."

这是一个值得怀疑的方法,因为指针的十进制化可能无法提供预期的连续数值模型.这篇文章可能对学习有好处,但OP在另一篇文章中提供了更多细节,甚至可以为更高层次的问题提供更好的想法.


Bas*_*tch 5

首先,请注意地址通常是“类似数字的”,但也可能不是(例如,请记住 1980 年代 16 位 x86 PC 上远地址的段+偏移量概念)。

然后,与指针最相似的整数类型是intptr_t(signed) 或uintptr_t(unsigned) - 两者都来自<stdint.h>.

您可能会将其转换为 a long long(希望它们不小于指针),例如

 printf("address of a in decimal is %lld\n", (long long) (intptr_t) (&a));
Run Code Online (Sandbox Code Playgroud)

但说真的,你为什么要以这种方式显示地址?我认为没有必要(例如,调试器或链接器通常以六进制显示地址,这可能是%p 这样做的)。

请注意,C11 标准(参见n1570 , §7.21.6.2, p315)%p对打印指针没有太多说明:

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

我以某种方式理解上述内容,其中Hello ?任何指针的打印都是可接受且符合标准的行为。在实践中,实现以类似于链接器和调试器所做的方式打印指针,并且不会以愚蠢的方式行事(但我理解他们可以)。

最后,指针的实际具体“数字”值并不重要,并且在一次执行和下一次执行之间可能会有很大差异(例如,因为ASLR)。