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