您好即时通讯位C.在字符串格式混淆 有人可以解释我什么是此处键入每个打印的输出?
printf("%p", pointer);
printf("%x", pointer);
printf("%x", &pointer);
答案 0 :(得分:2)
%p
的意思是“打印指针”。您应该将已经转换为void *
的指针传递给它。 %x
的意思是“以十六进制打印unsigned int
。”您应该将unsigned int
传递给它;向它传递指针是不正确的。
假设我们有
char *pointer = "Hello";
char array[] = "World";
然后,在:
printf("%p", (void *) pointer);
printf("%p", (void *) array);
将以某种实现定义的方式打印pointer
的值。 (它应该向您显示存储在pointer
中的地址。)
在第二个printf
中,数组array
将转换为指向其第一个元素的指针,并且该指针的值将以实现定义的方式打印。
请注意,我在(void *)
上插入了强制类型转换。这是使用%p
的正确方法。
在:
printf("%x", (unsigned) pointer);
printf("%x", (unsigned) array);
pointer
的值将转换为unsigned int
。转换的结果是实现定义的。这并不奇怪,但它可能是从你看到什么不同%p
。另外,unsigned int
可能太窄而无法包含指针的完整值,在这种情况下,某些信息将丢失。
此转换后,第一条语句将以十六进制打印值(不带前导“ 0x”,而使用%p
通常确实包含前导“ 0x”)。第二条语句将再次将array
转换为指向其第一个元素的指针,然后将其转换为unsigned int
,然后以十六进制打印。
如果unsigned int
是足够宽的,这是可能的,甚至不是不可能,通过这种方法印刷的值会显示相同的十六进制值,如图所示由%p
的方法,但不能依靠这一点。
请注意,使用%x
打印这些而不将其强制转换为unsigned
时,其行为不是C标准定义的-为%x
规范传递指针是错误的。你必须先将其转换。没有转换的原始代码可能会导致打印值来自与指针无关的任意数据,或者可能导致程序中止,或者可能打印了正确的地址,或者可能已经完成还有其他东西-行为没有定义。
在:
printf("%x", (unsigned) &pointer);
printf("%x", (unsigned) &array);
pointer
的地址而非其值将被转换为unsigned int
,然后以十六进制打印。几乎可以肯定,这与打印pointer
的结果有所不同。
有关&array
,所述阵列的所述地址将被转换为unsigned
。与之前的语句不同,array
不会转换为指向其第一个元素的指针。这是因为&
是抑制此转换的特殊运算符。它返回数组的地址。
数组的地址与第一个元素的地址“相同”,因为在内存中,数组从其第一个元素的起始位置开始。但是,指针可能具有不同的表示形式,与将&array
转换为unsigned int
相比,将array
转换为unsigned int
可能会产生不同的值。尽管如此,在大多数C实现中,它们产生的值相同,因此您对printf("%x", (unsigned) &array);
的结果与对printf("%x", (unsigned) array);
的结果相同。
答案 1 :(得分:0)
第一个用于指针,第二个用于整数,即使结果经常是相同的。这正在解释一切。如果你想打印指针%p
如果整数%x
。
所有其他讨论都是错误的,因为使用错误的格式说明符会调用UB。