我正在编写一个C程序,该程序必须在十六进制答案中显示每个操作,但您必须显示与数据类型相对应的所有字节。
例如,如果它的int应该显示8个字节,如果其短4个字节。
它适用于其他所有数据类型,包括CHAR,其中仅显示两个字节。但是,当我打印时,short总是显示8个字节
char x5 = 0xa1;
short z5 = x5;
printf("nProblem 1f: %xn", z5);
并打印"问题1f:ffffffa1"
同学找到了一个解决方案,其中%hx打印了正确数量的字节,但我不明白为什么这个%x打印了额外的字节,这些字节来自哪里?
预先感谢!
这是由于无声整数类型促销所致。由于 0xa1
是负值(-95 dec( char
,short
将升级为4个字节int
,并由printf
函数打印为负。
要防止促销您可以使用unsigned
类型。
下面的程序说明了签名和未签名类型的行为:
#include<stdio.h>
#include<stdlib.h>
int main() {
char x5 = 0xa1;
short z5 = x5;
int i5 = x5;
unsigned char ux5 = 0xa1;
unsigned short uz5 = 0xa1;
unsigned int ui5 = 0xa1;
size_t sx5 = sizeof(x5);
size_t sz5 = sizeof(z5);
size_t si5 = sizeof(i5);
printf("%zu %zu %zun", sx5, sz5, si5);
printf("%x %x %xn", x5, z5, i5); // silent promotion to 32 bit negative integers
printf("%x %x %xn", ux5, uz5, ui5); // no promotion
ux5 = x5;
uz5 = z5; // remember that z5 is negative number
ui5 = i5; // same for i5
printf("%x %x %xn", ux5, uz5, ui5); // no promotion but numbers are negative ones
return 0;
}
输出:
1 2 4
ffffffa1 ffffffa1 ffffffa1
a1 a1 a1
a1 ffa1 ffffffa1
由于x5
足够大(单字节数据类型中的127
或0x7F
上的任何内容(具有最高的位置( 1 010 0001(,它已解释使用默认签名类型时为负。正如另一个答案所述,使用unsigned char
解决了问题。但是,键入 x5
也将起作用,因为Short使用两个字节来存储该值,并且即使签名也不会将其视为负( 0 000 0000 0000 1010 0001(。
打字将起作用:
char x5 = 0xa1;
short z5 = (unsigned char) x5;
,也将使用未签名的char:
unsigned char x5 = 0xa1;
short z5 = x5;
但是,如果您使用这种方式来避免这种情况。
unsigned char x5 = 0xa1;
unsigned short z5 = x5;