C “替代品”p";格式限定符
我在嵌入式系统(特别是PIC上的XC8)上使用的平台/编译器不包括printf()的%p指针地址格式说明符 例如:C “替代品”p";格式限定符,c,embedded,microcontroller,C,Embedded,Microcontroller,我在嵌入式系统(特别是PIC上的XC8)上使用的平台/编译器不包括printf()的%p指针地址格式说明符 例如: printf("J: %f [@ 0x%p]\r\n", j, &j); 将在大多数编译器中显示名为“j”的变量的值和地址。但是,根据编译器文档,它不包括对%p的支持。给出错误“无效的格式说明符或类型修饰符” 那么在这种情况下,除了打印变量的地址,还有什么替代方法呢?名义上,您可以使用标题、uintptpr\t类型和PRIXPTR或PRIXPTR格式(最初在C99或ISO
printf("J: %f [@ 0x%p]\r\n", j, &j);
将在大多数编译器中显示名为“j”的变量的值和地址。但是,根据编译器文档,它不包括对%p的支持。给出错误“无效的格式说明符或类型修饰符”
那么在这种情况下,除了打印变量的地址,还有什么替代方法呢?名义上,您可以使用
标题、uintptpr\t
类型和PRIXPTR
或PRIXPTR
格式(最初在C99或ISO/IEC 9899:1999中正式定义):
但是,如果您没有%p
,您可能也没有这些,因此您可能不得不求助于:
printf("J: %f [@ 0x%lX]\r\n", j, (unsigned long)&j);
这假定
sizeof(无符号长)==sizeof(void*)
;如果不是,则需要使用整数类型,以便sizeof(other\u integer\u type)==sizeof(void*)
。如果找不到这样的类型,您需要详细解释机器上的类型。通常,您会使用
标题、uintptr\t
类型和PRIXPTR
或PRIXPTR
格式(最初在C99或ISO/IEC 9899:1999中正式定义):
但是,如果您没有%p
,您可能也没有这些,因此您可能不得不求助于:
printf("J: %f [@ 0x%lX]\r\n", j, (unsigned long)&j);
这假定
sizeof(无符号长)==sizeof(void*)
;如果不是,则需要使用整数类型,以便sizeof(other\u integer\u type)==sizeof(void*)
。如果找不到此类类型,则需要详细解释计算机上的类型。通常由运行库中的printf
函数实现%p
格式,而不是在编译器中。对于编译器和库不一定来自同一供应商或其他来源的实现,这种区别可能很重要。(一些编译器可能会使用文本格式字符串优化printf
调用;多亏chux指出了这一点。)
正如马特·麦克纳布(Matt McNabb)的评论所建议的那样,您很可能可以将指针转换为无符号long
,并使用%lx
打印它。我可能会使用类似于:
printf("J: %f [@ 0x%lx]\r\n", j, (unsigned long)&j);
assert(sizeof (unsigned long) >= sizeof (void*));
如果(a)指针的宽度大于无符号长
或(b)从指针类型到无符号长
的转换丢失信息,则此操作可能会失败。我研究过一些奇怪的系统,但我从未见过一个会违反这两个假设的系统
由于您的代码可能并不意味着可移植,因此您可以在平台上检查指针的大小和unsigned long
。如果你觉得有妄想症,你可以添加如下内容:
printf("J: %f [@ 0x%lx]\r\n", j, (unsigned long)&j);
assert(sizeof (unsigned long) >= sizeof (void*));
只是为了(几乎)确保转换不会丢失信息。
%p
格式通常由运行库中的printf
函数实现,而不是在编译器中。对于编译器和库不一定来自同一供应商或其他来源的实现,这种区别可能很重要。(一些编译器可能会使用文本格式字符串优化printf
调用;多亏chux指出了这一点。)
正如马特·麦克纳布(Matt McNabb)的评论所建议的那样,您很可能可以将指针转换为无符号long
,并使用%lx
打印它。我可能会使用类似于:
printf("J: %f [@ 0x%lx]\r\n", j, (unsigned long)&j);
assert(sizeof (unsigned long) >= sizeof (void*));
如果(a)指针的宽度大于无符号长
或(b)从指针类型到无符号长
的转换丢失信息,则此操作可能会失败。我研究过一些奇怪的系统,但我从未见过一个会违反这两个假设的系统
由于您的代码可能并不意味着可移植,因此您可以在平台上检查指针的大小和unsigned long
。如果你觉得有妄想症,你可以添加如下内容:
printf("J: %f [@ 0x%lx]\r\n", j, (unsigned long)&j);
assert(sizeof (unsigned long) >= sizeof (void*));
只是为了(几乎)确保转换不会丢失信息。尝试
%lx
并将地址强制转换为(无符号长)
尝试%lx
并将地址强制转换为(无符号长)
“%p格式是由运行库中的printf函数实现的,而不是在编译器中。”不一定如此。PIC编译器(取决于哪个编译器)在编译时分析常量格式字符串,并形成所需的函数调用。@chux:这一点很好。gcc可以做类似的转换,尽管没有那么积极;例如,printf(“hello\n”)
可能会产生相当于put(“hello”)的代码用于嵌入式平台的代码>编译器,如此优化,以避免引入整个printf()
函数-通常,该函数相当大。“%p格式由运行库中的printf函数实现,而不是在编译器中。”不一定如此。PIC编译器(取决于哪个编译器)在编译时分析常量格式字符串,并形成所需的函数调用。@chux:这一点很好。gcc可以做类似的转换,尽管没有那么积极;例如,printf(“hello\n”)
可能会产生相当于put(“hello”)的代码用于嵌入式平台的代码>编译器,如此优化,以避免引入整个printf()
函数-通常,该函数相当大。