使用%x打印指针中包含的十六进制地址

时间:2014-08-08 19:35:06

标签: c pointers memory-address

我刚读了这篇简短的文章http://karwin.blogspot.com/2012/11/c-pointers-explained-really.html,它很好地描述了指针。然而,作者说地址只是这些十六进制值,所以他用%x打印它,但是当我这样做时,我不仅从编译器得到一个警告,说我传递指针而不是unsigned int,但有时候我得到的东西根本不像地址(如1C)。有人可以澄清这个问题吗?

5 个答案:

答案 0 :(得分:2)

%x期望其对应的参数具有类型unsigned int,这就是您获得警告和时髦输出的原因。使用%p显示指针值:

T *p = some_pointer_value;
...
printf( "p = %p\n", (void *) p );

%p期望其对应的参数具有类型void *。这几乎是你应该在C中明确地指向void *的指针。

修改

刚看了一下页面。请注意,该代码示例是 old (写于1990年),并使用K& R风格(1989年之前的标准)函数定义语法和隐式int。它使用%x来显示指针值,因为{1989}标准之前没有将%p转换说明符添加到语言中。

应该用作现代C编程实践的模型。

他对指针的解释非常不错。

答案 1 :(得分:1)

%x用于以十六进制格式打印值。虽然指针通常用十六进制编写,但指针的其他注意事项会使%x不合适,就像您看到的1C输出一样。

%p用于指针,可能就是你要找的东西。它会更好地格式化指针,因为它知道它是一个指针。

1C是一个完全有效的十六进制输出,但它对于指针来说很奇怪,因为你期望在显示指针时会发生某些特殊事情,例如具有正确的长度。

由于%x适用于十六进制数字,因此将指针传递给它会给出警告。它给你警告的一个原因是指针的大小不一定与unsigned int相同。

答案 2 :(得分:1)

%x预计unsigned int,其他任何内容都是 UB

对于打印数据指针,有%p可以打印空指针(类型void*,转换可选),通常会打印它用十六进制表示法。

如果这不能让您满意,请考虑将指针转换为uintptr_t,并使用PRIxPTR中的格式说明符 - 宏PRIXPTR<inttypes.h>进行打印,以保证十六进制输出。
您甚至可以选择使用的案例。

答案 3 :(得分:1)

值不能是&#34; hex&#34;。价值观只是价值观。同时,&#34; hex&#34;是一种代表人类消费价值的方法。 &#34;十六进制&#34;是一种表示法。

直接在指针上使用%x是非法的,因为%x格式说明符需要unsigned int参数,而不是指针。指针可以转换为unsigned int类型,结果可以与%x格式说明符一起使用,但这在一般情况下不起作用,因为unsigned int类型很容易变得太窄而不能正确代表数字地址值。

换句话说,忘掉%x。在那个应用程序中它毫无用处。你的文章的作者非常错误。

如果你真的想通过转换为整数类型来打印指针p,那么正确的方法就是这个

printf("%" PRIxPTR "\n", (uintptr_t) p);

注意使用uintptr_t类型和PRIxPTR宏代表与该类型相关联的实现定义的格式说明符。

除此之外,您可以使用专用格式说明符%p,它会打印void *指针,并且通常会为此目的使用十六进制表示法。

答案 4 :(得分:0)

如果使用%x或%u等整数格式进行操作,则指针会给出未定义的结果。建议指针使用%p。 就警告而言,%x需要unsigned int,并且您的变量可能与unsigned int的大小或对齐要求不同,因此您将收到警告。