在C中将char和int相乘
今天我发现了以下内容:
#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),那么我会得到类似的行为。通常是否建议不要使用不同大小的操作数进行算术?
Today I found the following:
#include <stdio.h>
int main(){
char x = 255;
int z = ((int)x)*2;
printf("%d\n", z); //prints -2
return 0;
}
So basically I'm getting an overflow because the size limit is determined by the operands on the right side of the = sign??
Why doesn't casting it to int before multiplying work?
In this case I'm using a char and int, but if I use "long" and "long long int" (c99), then I get similar behaviour. Is it generally advised against doing arithmetic with operands of different sizes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
char
可以是有符号的,也可以是无符号的,具体取决于您的编译器。在您的情况下,它似乎是有符号的,并且 255 超出了它可以表示的范围(可能它只能表示从 -128 到 127 的数字)。
因此,当您将 255 分配给 char 变量时,就会出现问题 - 这会导致实现定义的值,在您的情况下,该值似乎是 -1。
当您将 -1 乘以 2 时,您将得到 -2。那里没有什么神秘的。转换为
(int)
不会执行任何操作 - 比int
窄的类型始终会在之前提升为int
或unsigned int
任何计算都是用它们完成的。char
can be either signed or unsigned, depending on your compiler.In your case, it appears to be signed, and 255 is outside the range it can represent (likely, it can only represent numbers from -128 to 127).
So the problem occurs when you assign 255 to your
char
variable - this results in an implementation-defined value, which in your case, appears to be -1.When you multiply -1 by 2, you get -2. No mystery there. The cast to
(int)
does nothing - types narrower thanint
are always promoted toint
orunsigned int
before any calculations are done with them.看来 char 已在您的平台上签名。因此,
char x = 255
实际上与char x = -1
相同。强制转换为 int 并不重要。尝试将其更改为:
It appears that char is signed on your platform. So the
char x = 255
is effectively the same aschar x = -1
. The cast to int doesn't matter.Try changing that to:
不,第二行(乘法)不会溢出。问题是您的编译器默认使用
signed char
,并且 255 溢出,意味着 -1。基本上,您正在使用值 -1 初始化变量x
。将 -1 转换为 int 将得到 -1(有符号操作数将在向上转换中进行符号扩展,而无符号操作数将进行零扩展)。您可以通过添加
unsigned
前缀来强制char
为unsigned
:No, you are not getting an overflow on the second line (multiplication). The problem is your compiler is using
signed char
by default and 255 overflows and will mean -1. Basically, you are initializing variablex
with the value of -1. Casting -1 to int will result in -1 (signed
operands will get sign-extended in upcasts whereasunsigned
operands will get zero-extended).You can force the
char
to beunsigned
by adding theunsigned
prefix:其他答案很好地解释了您的示例如何“工作”,所以我不会再解释这一点。
但是,让我观察一下,如果您要使用的是“无符号 8 位整数”,只需使用
的uint8_t
即可(及其16、32、64 位同伴)并远离这个世界上的所有char
、short
和int
。The other answers nicely explain how your example "works", so I will not explain that again.
However, let me observe that if what you want to use is an "unsigned 8 bit integer", just use
<stdint.h>
'suint8_t
already (and its 16, 32, 64bit companions) and keep away from all thechar
s,short
s andint
s in this world.