在C语言中将字符和整数相乘

8

今天我发现了以下内容:

#include <stdio.h>

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

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

return 0;

}

基本上,我之所以出现溢出的情况是因为等号右侧的操作数确定了大小限制?在乘法之前将其转换为int为什么不起作用?如果我使用“long”和“long long int”(c99),那么我会得到类似的行为。通常建议不要使用不同大小的操作数进行算术运算吗?
4个回答

13

char 可以是有符号的,也可以是无符号的,这取决于你的编译器。

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

因此,当您将255赋给char变量时,这会导致一个实现定义的值,在您的情况下,似乎是-1。

当您将-1乘以2时,您会得到-2。没有什么神秘的地方。强制转换为(int)并没有起任何作用 - 比int窄的类型始终在进行任何计算之前被提升为intunsigned int


5

看起来在你的平台上,char是带符号的。因此,char x = 255实际上与char x = -1相同。强制转换为int并不重要。

尝试将其更改为:

unsigned char x = 255;

4
不,第二行(乘法)并没有出现溢出。问题在于你的编译器默认使用有符号字符(signed char),255会发生溢出并变成-1。基本上,你正在用-1初始化变量x。将-1强制转换为int将导致-1(有符号操作数在升级时会被符号扩展,而无符号操作数则会被零扩展)。
你可以通过添加unsigned前缀来强制将char转换为unsigned:
unsigned char x = 255;

3
其他答案已经很好地解释了你的例子是如何“工作”的,所以我不会再解释一遍。
然而,让我观察一下,如果你想使用的是“无符号8位整数”,只需使用 <stdint.h>uint8_t(以及它的16、32、64位伙伴),并远离这个世界上所有的 charshortint

1
使用#include <stdint.h>来定义这些类型。 - slartibartfast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接