在C,我想到使用printf显示指针,以便他们行正确的,我想垫他们0。

我的猜测是正确的方式做这是:

printf("%016p", ptr);

这一工作,但这个海湾合作委员会抱怨与以下信息:

warning: '0' flag used with ‘%p’ gnu_printf format

我已经google搜索一位,以下线是关于同一主题的,但是并没有真正得到一个解决方案。

http://gcc.gnu.org/ml/gcc-bugs/2003-05/msg00484.html

阅读它,它似乎是原因,海湾合作委员会抱怨是,我的语法建议中未定义C99。但我似乎找不到任何其他方式做同样的事情在标准的核准方式。

因此,这里的双重问题:

  • 我的理解是正确的,这种行为是不是定义的C99标准?
  • 如果是这样,是否有一个标准获得批准,便携式的方式这样做?
有帮助吗?

解决方案

#include <inttypes.h>

#include <stdint.h>

printf("%016" PRIxPTR "\n", (uintptr_t)ptr);

但是它不会打印指针在执行定义的方式(说 DEAD:BEEF 为8086分割的模式)。

其他提示

使用:

#include <inttypes.h>

printf("0x%016" PRIXPTR "\n", (uintptr_t) pointer);

或用另一个变体的宏从那头。

还注意到,一些实现 printf() 印'0x'前面的指针;其他人不这样做(以及两者都是正确的根据C的标准)。

唯一的 便携式 的方式来打印指针的价值是使用 "%p" 说明符,其产生的执行情况定义的输出。(转换到 uintptr_t 和使用 PRIxPTR 是有可能的工作,但(a) uintptr_t 介绍了在C99,所以有些编制者使用时就会不支持它,以及(b)它不能保证存在,甚至在C99(有可能不是一个整数类型的大到足以容纳所有可能的指数值。

因此,使用 "%p"sprintf() (或 snprintf(), 如果你有的话),打印的字符串,然后打印的字符串填充有领先的空白。

一个问题是,有没有真的很好的方式确定的最长的字符串产生的 "%p".

这是无可否认的不便(虽然你当然可以包装在一个功能)。如果你不需要100%的携带,我从来没有使用的系统被铸造的指针 unsigned long 和打印结果的使用 "0x%16lx" 不会的工作。[更新:是的,我有。64位Windows有64位的指针,以及32位的 unsigned long.] (或者您可以使用 "0x%*lx" 和计算宽,可能喜欢的东西 sizeof (void*) * 2.如果你真偏执,你可以考虑的系统 CHAR_BIT > 8, 所以你会得到超过2hex digits每字节。)

这答案是相似的一个鉴于早些时候在 https://stackoverflow.com/a/1255185/1905491 但是还需要尽可能宽度的入账户(所概述的通过 https://stackoverflow.com/a/6904396/1905491 我没有认识到直到我的回答是呈现下它;)。以下剪将打印的指针为8 0-通过六角字上的明智*机在那里他们可以表示的32位,16 64和4月16b系统。

#include <inttypes.h>
#define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))

printf("0x%0*" PRIxPTR, PRIxPTR_WIDTH, (uintptr_t)pointer);

注意使用星号的字取宽度的下一论点,这是在C99(可能是之前吗?), 但这是很少见的"在野"。这是更好的方式比使用 p 转换,因为后者是执行定义。

*该标准允许 uintptr_t 要大于最小,但我认为,没有执行,不使用最低限度。

这很容易解决,如果你投的指针指向一个很长的类型。问题是这不会在所有的平台,因为它假定一个指针可能适合内部的一个长期的,而这一指针可以显示,在16个字符的(64位)。但是,这是真正的大多数平台。

因此,它将成为:

printf("%016lx", (unsigned long) ptr);

作为你的链路已经表明,行为是不确定的。我不认为有一个便携式的方式这样做%p本身取决于在平台上你的工作。你当然可以只把指针指向一个int,并显示它在hex:

printf("0x%016lx", (unsigned long)ptr);

也许这会很有趣的(从一个32位的windows的机器,使用mingw):

rjeq@RJEQXPD /u
$ cat test.c
#include <stdio.h>

int main()
{
    char c;

    printf("p: %016p\n", &c);
    printf("x: %016llx\n", (unsigned long long) (unsigned long) &c);

    return 0;
}

rjeq@RJEQXPD /u
$ gcc -Wall -o test test.c
test.c: In function `main':
test.c:7: warning: `0' flag used with `%p' printf format

rjeq@RJEQXPD /u
$ ./test.exe
p:         0022FF77
x: 000000000022ff77

正如你可以看到,该%p版垫零尺寸大小的指针,然后空间指定的大小,而在使用%x和转换(在转换和格式说明是高度无法移植)使用仅零。

注意,如果指针指纹与"0x"前缀,你会需要的替代品"%018p"补偿。

我通常使用%x显示指针。我想这不是便携式的64位系统上,但它的工作的现用于32苦.

我将有兴趣看到什么答案有用 便携式解决方案, ,因为指针的表示是不完全的便携式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top