【发布时间】:2020-04-16 09:21:36
【问题描述】:
#include <stdio.h>
void main()
{
unsigned char a = 0xfb;
char b = 0xfb;
printf("case1 : %d, %d", a, b); // case1
char x=90, y=60, z=100, h;
h = x*y/z;
printf("\ncase2 : %d", h); // case2
int m = 32768, n = 65536, o = 2, i;
i = m*n/o;
printf("\ncase3 : %d", i); // case3
}
result
case1 : 251, -5
case2 : 54
case3 : -107341824
在 case1 中,标识符 b 被编译为 -5,这不是语法错误,认为 char 只接受 -128~127 值。那么,第一个问题是标识符b在翻译结束时首先保存为int数据类型?(翻译结束时,b将保存为char。)
在 case2 中,x,y 被提升为 int。所以 h 有正确的结果值。但在 case3 中,m、n 不会被提升为 unsigned int(也许)。标识符 I 没有普通值(2^30)。 C99 这么说
如果一个int可以表示原始类型的所有值,则将该值转换为一个int; 否则,将其转换为无符号整数。
基于C99,h的值是自然的,但是处理m*n/o是溢出的。这不自然,因为它反对 C99。这是我的第二个查询。
【问题讨论】:
-
请不要发布代码图片 - 将文本复制到问题中。
-
促销没有发生在您的“案例 3”中 - 因为
m和n已经定义为int。因此,对于i = m * n / o,您只是看到整数溢出。 -
@Adrian Mole 根据'如果一个int可以表示原始类型的所有值,则将该值转换为int;否则,它被转换为无符号整数。',我认为 m 和 n 与'否则,它被转换为无符号整数'有关。所以我无法理解 case3 中没有发生促销。
-
在这种情况下,没有促销 - 只是有符号和无符号之间的转换(或两个)。
-
m * n超过了int的存储大小(加一),中间结果不能用int表示。 Why is unsigned integer overflow defined behavior but signed integer overflow isn't?
标签: c integer-promotion