C 为什么<;inttypes.h>';s PRIx16不等于;hx";?

C 为什么<;inttypes.h>';s PRIx16不等于;hx";?,c,printf,C,Printf,为什么(和)在GCC之下 我希望它是“hx”,因此以下功能可以正常工作: #include <inttypes.h> int16_t v = -1; printf("%04" PRIx16 "\n", v); // prints ffffffff, not ffff #包括 int16_t v=-1; printf(“%04”PRIx16“\n”,v);//打印FFFFFF,而不是ffff 简短回答: 要打印签名类型,请使用d,i 要打印未签名类型,请使用x、u、o int1

为什么(和)在GCC之下

我希望它是
“hx”
,因此以下功能可以正常工作:

#include <inttypes.h>

int16_t v = -1;
printf("%04" PRIx16 "\n", v);  // prints ffffffff, not ffff
#包括
int16_t v=-1;
printf(“%04”PRIx16“\n”,v);//打印FFFFFF,而不是ffff
简短回答:

要打印签名类型,请使用
d
i

要打印未签名类型,请使用
x
u
o


int16\u t v
是有符号整数类型

PRIxN
PRIx16
中一样,被列为“用于无符号整数的fprintf宏”
PRIxN
未列出“带符号整数的fprintf宏”

要将
v
打印为十进制文本,请使用
PRId16
PRIi16

printf("%04" PRId16 "\n", v);
要将
v
打印为十六进制文本,请强制转换/转换为一些无符号文本

printf("%04" PRIx16 "\n", (uint16_t)v);

我还希望PRIx16的
hx
,这是我的GCC编译(GNUC11(GCC)版本6.4.0)的方式,但这更可能是一个问题(我的:ldd(cygwin)2.9.0)。我怀疑OP的编译器/库是否最新

#include <stdio.h>
#include <inttypes.h>

int main(void) {
  printf(PRIx16);
  return 0;
}
简短答复:

要打印签名类型,请使用
d
i

要打印未签名类型,请使用
x
u
o


int16\u t v
是有符号整数类型

PRIxN
PRIx16
中一样,被列为“用于无符号整数的fprintf宏”
PRIxN
未列出“带符号整数的fprintf宏”

要将
v
打印为十进制文本,请使用
PRId16
PRIi16

printf("%04" PRId16 "\n", v);
要将
v
打印为十六进制文本,请强制转换/转换为一些无符号文本

printf("%04" PRIx16 "\n", (uint16_t)v);

我还希望PRIx16的
hx
,这是我的GCC编译(GNUC11(GCC)版本6.4.0)的方式,但这更可能是一个问题(我的:ldd(cygwin)2.9.0)。我怀疑OP的编译器/库是否最新

#include <stdio.h>
#include <inttypes.h>

int main(void) {
  printf(PRIx16);
  return 0;
}

PRIx16
用于
uint16\u t
;您误用了它。另一方面,
hx
同时适用于
有符号的short
无符号的short
,因此这似乎是不必要的限制。是否存在用于
int16\u t
的另一个宏?C99第7.8.1章,没有用于签名类型的PRIx宏。我同意,但我不认为
PRIx16==“x”
不符合。@Eric,您使用的是什么版本?
PRIx16
用于
uint16\u t
;您误用了它。另一方面,
hx
同时适用于
有符号的short
无符号的short
,因此这似乎是不必要的限制。
int16\u t
是否存在另一个宏?C99第7.8.1章,没有用于签名类型的PRIx宏。我同意,但我不认为
PRIx16==“x”
不符合。@Eric,您使用的是什么版本?不需要强制转换。OP的问题与有符号/无符号位解释问题无关。“x”不符合规范,应该是“hx”。@jwdonahue我同意
“hx”
会更好,但是C规范不支持
“x”
不符合规范。作为注释,签名类型没有PRIx宏。因此OP的代码是UB,它与类型无关。查看函数签名:
intprintf(char*,…)
。无论你推一个int16或uint16,它都会在堆栈上推两个字节。格式字符串由代码解释,它假定您实际上对它撒谎,而不是一直向下推char*。@jwdonahue您的评论是
“hx”
起作用的一个很好的原因(当然,由于整数提升,会推送4个字节),但它并没有说明OP使用
“x”
的代码的有效性。C指定要与
uint16\u t
一起使用的
PRIx16
,并且
“x”
可与之配合使用。C没有指定
PRIx16
可以与
int16\u t
一起使用-因此,将其与
int16\u t
一起使用是非常困难的,即使它在某些平台上工作。我要补充的是,
PRIx16
是一个宏,这里没有进行类型检查,它甚至不需要任何参数来检查它们。请编辑您的答案。不需要演员阵容。OP的问题与有符号/无符号位解释问题无关。“x”不符合规范,应该是“hx”。@jwdonahue我同意
“hx”
会更好,但是C规范不支持
“x”
不符合规范。作为注释,签名类型没有PRIx宏。因此OP的代码是UB,它与类型无关。查看函数签名:
intprintf(char*,…)
。无论你推一个int16或uint16,它都会在堆栈上推两个字节。格式字符串由代码解释,它假定您实际上对它撒谎,而不是一直向下推char*。@jwdonahue您的评论是
“hx”
起作用的一个很好的原因(当然,由于整数提升,会推送4个字节),但它并没有说明OP使用
“x”
的代码的有效性。C指定要与
uint16\u t
一起使用的
PRIx16
,并且
“x”
可与之配合使用。C没有指定
PRIx16
可以与
int16\u t
一起使用-因此,将其与
int16\u t
一起使用是非常困难的,即使它在某些平台上工作。我要补充的是,
PRIx16
是一个宏,这里没有进行类型检查,它甚至不需要任何参数来检查它们。请编辑您的答案。