在下面的示例中:
int main(int argc, char *argv[])
{
int16_t array1[] = {0xffff,0xffff,0xffff,0xffff};
char array2[] = {0xff,0xff,0xff,0xff};
printf("Char size: %d \nint16_t size: %d \n", sizeof(char), sizeof(int16_t));
if (*array1 == *array2)
printf("They are the same \n");
if (array1[0] == array2[0])
printf("They are the same \n");
printf("%x \n", array1[0]);
printf("%x \n", *array1);
printf("%x \n", array2[0]);
printf("%x \n", *array2);
}
输出:
Char size: 1
int16_t size: 2
They are the same
They are the same
ffffffff
ffffffff
ffffffff
ffffffff
为什么打印
char
和int16_t
的32位值,为什么可以比较它们并认为它们相同? 最佳答案
它们是相同的,因为它们都是-1的不同表示。
它们打印为32位的ff
值,因为您在32位计算机上,并且使用了%d
并且发生了默认参数提升(基本上,所有较小的参数都会提升为int
)尝试使用%hx
(这可能会让您ffff
;除了使用ff
或使用unsigned char
:& 0xff
掩蔽之外,我不知道还有什么方法可以获得printf("%x \n", array2[0] & 0xff)
)
扩展到“它们是相同的,因为它们都是-1的不同表示”:int16_t
是有符号的16位类型。它可以包含-32768到+32767范围内的值。char
是一种8位类型,在您的机器上它显然也有签名所以它可以包含-128到+127范围内的值。
0xff是十进制255,不能用有符号字符表示的值。如果将0xff赋给一个有符号的字符,那么这个位模式最终会被解释为-1,而不是255(类似地,如果您分配了0xfe,则它将被解释为-2,而不是254。)
0xffff是十进制65535,不能用int16_t
表示。如果将0xffff赋给int16_t
,则该位模式最终将被解释为-1,而不是65535(类似地,如果您分配了0xfffe,则它将被解释为-2,而不是65534。)
所以当你说
int16_t array1[] = {0xffff,0xffff,0xffff,0xffff};
基本上就像你说的
int16_t array1[] = {-1,-1,-1,-1};
当你说
char array2[] = {0xff,0xff,0xff,0xff};
就好像你说过
char array2[] = {-1,-1,-1,-1};
所以这就是为什么。
另外,值得注意的是,所有这些都是因为
*array1 == *array2
和array1[0] == array2[0]
的类型如果你说uint16_t array3[] = {0xffff,0xffff,0xffff,0xffff};
unsigned char array4[] = {0xff,0xff,0xff,0xff};
您将看到打印的值不同(
array1
和array2
),并且来自ffff
和ff
的值不会进行相同的比较。另一个答案是“运行时C中没有类型信息”这是真的,但在这件事上有误导性当编译器生成代码来操作
array3
、array4
、array1
和array2
中的值时,它生成的代码(当然,这在运行时很重要!)将基于其类型特别是,当生成从array3
和array4
获取值的代码(但不是array1
和array2
)时,编译器将使用在分配给更大类型的对象(例如32位)时执行符号扩展的指令这就是0xff和0xffff如何变为0xFFFFFF的原因。关于c - Char和int16数组元素都显示为32bit十六进制?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31562375/