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

时间:2018-01-17 20:01:04

标签: c pointers

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

open(readdata.filename(), 'a')

我试图打印 #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); } 的地址,a的地址以及p的第一个字节开始的位置。

使用tab时我可以获得十六进制值,但我愿意使用地址的十进制值。

修改:在Video image上,有人使用"%p"打印指针地址的十进制值,这让我很困惑。< / p>

5 个答案:

答案 0 :(得分:10)

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

  

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

#include <inttypes.h>
uintptr_t d = (uintptr_t)(void *) &a;

然后打印出来。
关于PRIuPTR

的一些信息
printf("%" PRIuPTR "\n", d);

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

OP后来发表了评论

“...我将尝试操作tab变量,我将测试选项卡中的每个单元格是否为4字节,因此可能会执行tab + 8字节以获取特定单元格的值,此处这是一个简单的例子,带小数对我来说很容易。“

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

答案 1 :(得分:4)

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

然后,与指针最相似的整数类型是intptr_t(已签名)或uintptr_t(无符号) - 均来自<stdint.h>

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

 printf("address of a in decimal is %lld\n", (long long) (intptr_t) (&a));

但实际上,你为什么要以这种方式展示地址?我认为不需要它(例如,调试器或链接器通常以hexa显示地址,这可能是%p所做的。)

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

  

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

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

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

答案 2 :(得分:3)

如果要将指针视为十进制整数,请将其强制转换为unsigned long并以%lu格式打印。虽然标准不能保证这一点,但它应该适用于大多数实现。

printf("the address of a is %lu\n", (unsigned long)&a);    

答案 3 :(得分:3)

对于打印“地址”(实际上是指针)"%p"是最常用的方法(请注意void*必要的强制转换)。如果需要十进制而不是十六进制的地址,可以将指针转换为整数值;这在C中有明确定义(参见this在线C标准草案):

  

6.3.2.3指针

     

(6)任何指针类型都可以转换为整数类型。除了   之前指定的,结果是实现定义的。如果   结果不能用整数类型表示,行为是   未定义。结果不必在任何值的范围内   整数类型。

所以代码可能如下所示:

int main(int argc, char *argv[]) {
    int a =10;
    int *p = &a;
    p  = &a;

    unsigned long long addrAsInt = (unsigned long long)p;

    printf("the adress of a is %llu \n",addrAsInt);
    printf("the adress of a using the pointer is %p \n",(void*)p);
}

答案 4 :(得分:0)

p是打印指针的转换说明符。使用它。

int a = 42;

printf("%p\n", (void *) &a);

请记住,省略强制转换是未定义的行为,而使用p转换说明符的打印是以实现定义的方式完成的。