The*_*eer 1 c variadic-functions integer-promotion
在下面的示例中:
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);
}
Run Code Online (Sandbox Code Playgroud)
输出:
Char size: 1
int16_t size: 2
They are the same
They are the same
ffffffff
ffffffff
ffffffff
ffffffff
Run Code Online (Sandbox Code Playgroud)
32位值为什么印刷两种char及int16_t,为什么他们能进行比较和被认为是一样的吗?
它们是相同的,因为它们都是-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,这是一个无法在signed char中表示的值.如果将0xff分配给有符号的char,则该位模式最终会被解释为255,而不是-1.(同样,如果你指定了0xfe,那么它将被解释为254,而不是-2.)
0xffff是十进制65535,这是一个无法用a表示的值int16_t.如果将0xffff分配给a int16_t,则该位模式最终会被解释为65535,而不是-1.(同样,如果你指定了0xfffe,那么它将被解释为65534,而不是-2.)
所以,当你说
int16_t array1[] = {0xffff,0xffff,0xffff,0xffff};
Run Code Online (Sandbox Code Playgroud)
这基本上就像你说的那样
int16_t array1[] = {-1,-1,-1,-1};
Run Code Online (Sandbox Code Playgroud)
而当你说
char array2[] = {0xff,0xff,0xff,0xff};
Run Code Online (Sandbox Code Playgroud)
就像你说的那样
char array2[] = {-1,-1,-1,-1};
Run Code Online (Sandbox Code Playgroud)
所以这就是原因*array1 == *array2,而且array1[0] == array2[0].
此外,值得注意的是,所有这一切都是因为类型非常多array1和array2.如果你反而说
uint16_t array3[] = {0xffff,0xffff,0xffff,0xffff};
unsigned char array4[] = {0xff,0xff,0xff,0xff};
Run Code Online (Sandbox Code Playgroud)
您会看到打印(ffff和ff)的不同值,以及来自array3和array4不会比较的值.
另一个答案说"在运行时C中没有类型信息".这是真的,但在这种情况下会产生误导.当编译器生成代码,以从操作值array1,array2,array3,和array4,它生成的代码(这当然是在运行时显著!)将根据其类型.尤其是,生成代码时,从获取的值array1和array2(但不 array3与array4),编译器将使用哪个执行指令符号扩展分配给更大的类型(例如,32位)的对象时.这就是0xff和0xffff如何变成0xffffffff.