Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C “替代品”p";格式限定符_C_Embedded_Microcontroller - Fatal编程技术网

C “替代品”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

我在嵌入式系统(特别是PIC上的XC8)上使用的平台/编译器不包括printf()的%p指针地址格式说明符

例如:

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()
函数-通常,该函数相当大。