在C中将char和int相乘

时间:2010-04-16 00:06:52

标签: c size math operands varying

今天我发现了以下内容:

#include <stdio.h>

int main(){
char x = 255;
int z = ((int)x)*2;

printf("%d\n", z); //prints -2

return 0;

}

所以基本上我得到溢出因为大小限制是由=符号右侧的操作数决定的

为什么在乘法工作之前不将它强制转换为int?

在这种情况下,我使用的是char和int,但如果我使用“long”和“long long int”(c99),那么我会得到类似的行为。通常建议不要对不同大小的操作数进行算术运算吗?

4 个答案:

答案 0 :(得分:11)

char可以是有符号或无符号的,具体取决于您的编译器。

在您的情况下,它似乎是有符号的,并且255超出了它可以代表的范围(可能,它只能代表-128到127之间的数字)。

因此,当您为char变量分配255时会出现问题 - 这会导致实现定义的值,在您的情况下,似乎为-1。

当你将-1乘以2时,得到-2。那里没有神秘感。对(int)的强制转换不执行任何操作 - 比int更窄的类型在使用它们进行任何计算之前始终会提升为intunsigned int

答案 1 :(得分:5)

似乎在您的平台上签署了char。因此char x = 255实际上与char x = -1相同。强制转换为int并不重要。

尝试将其更改为:

unsigned char x = 255;

答案 2 :(得分:4)

不,你没有在第二行(乘法)上溢出。问题是你的编译器默认使用signed char并且255溢出并且意味着-1。基本上,您使用值-1初始化变量x。将-1转换为int将导致-1(signed操作数将在upcast中进行符号扩展,而unsigned操作数将得到零扩展。

您可以通过添加char前缀强制unsignedunsigned

unsigned char x = 255;

答案 3 :(得分:3)

其他答案很好地解释了你的例子如何“有效”,所以我不再解释。

但是,让我观察一下,如果你想要使用的是“无符号8位整数”,那么只需使用<stdint.h>的{​​{1}}(和它的16,32,64位同伴)和远离这个世界上的所有uint8_tcharshort