%p vs%x,格式为字符串

时间:2019-02-02 21:52:14

标签: c string format

您好即时通讯位C.在字符串格式混淆 有人可以解释我什么是此处键入每个打印的输出?

printf("%p", pointer);
printf("%x", pointer);
printf("%x", &pointer);

2 个答案:

答案 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。