K&R在C编程语言中进行了练习,以查找各种类型的最大/最小值,例如char和int.
在以下代码中:
#include<stdio.h>
#include<limits.h>
void main()
{
printf("Size of Char Max %d\n", CHAR_MAX);
printf("Max Char+1 = %d\n",CHAR_MAX+1); //my test code
}
Run Code Online (Sandbox Code Playgroud)
既然CHAR_MAX是127,这是类型的最大值char,为什么不加1会导致溢出?
首先,范围char是-128到127还是0到255或其他完全是实现定义的.该标准没有定义,如果char是signed或unsigned,也没有定义,它必须有八个二进制位,尽管后者可以安全地在实践中今天承担.见ISO/IEC 9899:1999中的3.9.1(1):
(...)实现定义
char对象是否可以保存负值.(......)
唯一的保证CHAR_MIN是不大于0 CHAR_MAX且不小于127(附件E).
至于另外,你没有得到,因为这两个溢出CHAR_MAX和1(以及11)的int,没有char,所以没有溢出可以预期的.
而且,即便加入
char c = '\x7f';
c + c;
Run Code Online (Sandbox Code Playgroud)
(即,char + char)具有输入int和即使不溢出char是signed因为通常的算术转换被应用到的操作数+.简而言之,这些表明在算术运算中,所有操作数都被转换为最大的涉及类型,并且整数提升也应用于整数类型.积分促销说明,在应用它们的地方,小于的整数类型至少int被转换为int,所以我们再次拥有int + int并且没有溢出.
关于第一段中"八位二进制位"注释的附录/旁注:作为历史意义问题,该问题超出了数据类型甚至在二进制计算机上的位数.它在今天几乎没有实际意义,但C是在并非所有普通计算机都使用整数的二进制补码表示的时候编写的.因此,附件E中签名类型的实施限制是对称的(例如,INT_MAX <= 32767而INT_MIN >= -32767不是-32768).在使用一个补码或有符号幅度表示的机器上,我们习惯的不对称根本不存在,并且有两个零值(0和-0).