#include <stdio.h> int main() { signed char a = 200; signed char b = 3; signed char c = 2; signed char res = (a * b)/c; printf("%d\n", res); return 0; }
上面代码的输出和简要说明?因为res类型应该升级为integer,我以为它会打印-212,但实际输出是-84。
6xfqseft1#
假设你在一个SCHAR_MAX小于200的平台上(在大多数平台上都是这样),那么,根据ISO C11标准的§6.3.1.3 ¶3,行
SCHAR_MAX
200
signed char a = 200;
将向a写入一个实现定义的值,或引发一个实现定义的信号。大多数平台将简单地从200中减去值UCHAR_MAX+1。假设UCHAR_MAX的值为255(在大多数平台上都是这种情况),这意味着它将把值-56写入a。那条线
a
UCHAR_MAX+1
UCHAR_MAX
255
-56
signed char res = (a * b)/c;
因此等于:
signed char res = (-56 * 3)/2;
这相当于:
signed char res = -84;
值得注意的是,该子表达式
(a * b)
将计算为-168,即使该值小于SCHAR_MIN。这是因为结果的类型是int。作为通常算术转换的一部分,两个操作数都升级为int,这意味着结果也是int。由于结果-168在分配给signed char之前被除以2,因此它的值为-84,ISO C标准保证该值可以用signed char表示(SCHAR_MIN保证等于或小于-127)。
-168
SCHAR_MIN
int
signed char
2
-84
-127
nuypyhwy2#
表达式(a * b)/c似乎会导致算术溢出,因为有符号字符只能有从-128到127的值(在大多数平台上),而a的值是-56。-56*3是-168,-168/2是-84。但在计算中,它对int值执行操作,因此没有溢出。
(a * b)/c
-128
127
-56*3
-168/2
2条答案
按热度按时间6xfqseft1#
假设你在一个
SCHAR_MAX
小于200
的平台上(在大多数平台上都是这样),那么,根据ISO C11标准的§6.3.1.3 ¶3,行将向
a
写入一个实现定义的值,或引发一个实现定义的信号。大多数平台将简单地从200
中减去值UCHAR_MAX+1
。假设UCHAR_MAX
的值为255
(在大多数平台上都是这种情况),这意味着它将把值-56
写入a
。那条线
因此等于:
这相当于:
值得注意的是,该子表达式
将计算为
-168
,即使该值小于SCHAR_MIN
。这是因为结果的类型是int
。作为通常算术转换的一部分,两个操作数都升级为int
,这意味着结果也是int
。由于结果
-168
在分配给signed char
之前被除以2
,因此它的值为-84
,ISO C标准保证该值可以用signed char
表示(SCHAR_MIN
保证等于或小于-127
)。nuypyhwy2#
表达式
(a * b)/c
似乎会导致算术溢出,因为有符号字符只能有从-128
到127
的值(在大多数平台上),而a
的值是-56
。-56*3
是-168
,-168/2
是-84
。但在计算中,它对int
值执行操作,因此没有溢出。