C 已定义的行为,将字符传递给printf(“02X”);
我最近遇到,OP在打印变量的十六进制值时遇到问题。我相信问题可以归结为: 每个打印使用的格式字符串是C 已定义的行为,将字符传递给printf(“02X”);,c,printf,undefined,C,Printf,Undefined,我最近遇到,OP在打印变量的十六进制值时遇到问题。我相信问题可以归结为: 每个打印使用的格式字符串是%02X,我一直将其解释为“将提供的int打印为至少两位的十六进制值” 第一种情况将signedCharacter作为参数传递,并打印出错误的值(因为int的其他三个字节的所有位都已设置) 第二种情况解决了这个问题,对值应用位掩码(0xFF)以删除除存储char的最低有效字节以外的所有字节。这是否可行?当然:signedChar==signedChar&0xFF 第三种情况通过将字符强制转换为无符
%02X
,我一直将其解释为“将提供的int
打印为至少两位的十六进制值”
第一种情况将signedCharacter作为参数传递,并打印出错误的值(因为int
的其他三个字节的所有位都已设置)
第二种情况解决了这个问题,对值应用位掩码(0xFF
)以删除除存储char
的最低有效字节以外的所有字节。这是否可行?当然:signedChar==signedChar&0xFF
第三种情况通过将字符强制转换为无符号字符
(这似乎清除了前三个字节?)来解决问题
对于以上三种情况中的每一种,有人能告诉我行为是否定义了吗?如何/在哪里?我不认为这个行为完全是由c标准定义的。毕竟它取决于有符号值的二进制表示。我将只描述它可能如何工作
printf(“Raw: %02X\n”, signedChar);
(char)0xf0
可以写成(char)-16
被转换成(int)-16
它的十六进制表示形式是0xfffff0
printf(“Masked: %02X\n”, signedChar &0xff);
printf(“Cast: %02X\n", (unsigned char)signedChar);
0xff
属于int
类型,因此在计算和之前,signedChar
将转换为(int)-16
。
((int)-16)和((int)0xff)
=(int)0x000000f0
printf(“Masked: %02X\n”, signedChar &0xff);
printf(“Cast: %02X\n", (unsigned char)signedChar);
(无符号字符)0xf0
可写为(无符号字符)240
转换为(无符号整数)240
作为十六进制,它是0x000000f0
小于int
的整数类型,在传递到printf时会升级为int
。因为数字的底层位表示形式在C标准中没有定义,所以确切的输出是未指定的。@Paul R:那么在第二种情况下,升级是否总是在bi之前进行tmask被应用?或者它会发生在掩码无效之后吗?顺便说一句,char
的签名是由实现定义的。如果你想要一个有符号的字符,请使用signed char
@unwind:真的吗?我一直假设默认情况下变量是有符号的,除非你另外指定。整数也是这样吗ers?(unsigned char)240
根据C99标准中的6.3.1.1:2转换为(int)240
:“如果一个int可以表示原始类型的所有值,那么该值将转换为int”。如果我只想打印两个符号,哪种方式更好/更快?掩蔽还是强制转换?