[英]Why doesn't CHAR_MAX + 1 cause overflow?
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
}
由于CHAR_MAX
为127(这是char
类型的最大值),为什么不加1导致溢出?
首先, char
的范围是-128到127还是0到255或完全由实现定义。 该标准没有定义char
是带signed
还是unsigned
,也没有定义必须具有8个二进制位,尽管在实践中可以安全地假定使用后者。 参见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;
(即char + char
)的类型为int
,即使对char
进行了signed
也不会溢出,因为通常的算术转换适用于+
的操作数。 简而言之,这些状态表示在算术运算中,所有操作数都将转换为最大涉及的类型,并且整数提升适用于整数类型。 整数提升表示,在应用它们时,小于int
整数类型将转换为至少int
,因此我们再次具有int + int
且没有溢出。
关于第一段中“八位二进制位”说明的附录/附带说明:从历史的角度来看,问题超出了二进制计算机上数据类型的位数。 今天它没有什么实际意义,但是C并非在所有普通计算机都使用整数的二进制补码表示的时候编写的。 因此,附件E中为有符号类型给出的实现限制是对称的(例如INT_MAX <= 32767
和INT_MIN >= -32767
而不是-32768)。 在使用补码或有符号幅度表示的机器上,我们习惯于不存在的非对称性根本不存在,并且有两个零值(0和-0)。
您正在以整数类型(%d)打印CHAR_MAX
的值。 因此它将按整数数据类型打印该值。
char
总范围是-128 to 127
。
对于整数是四个字节。 因此没有溢出。
你可以试试看
char a=256;
这样分配时,您会得到警告。
warning: overflow in implicit constant conversion [-Woverflow]
CHAR_MAX
in被定义为宏常量,而不像您想的那样属于char
类型。 在这里看看。
在printf("Max Char+1 = %d\\n",CHAR_MAX+1);
,预处理器将CHAR_MAX
替换为127
。 由于127 + 1为128,并且格式说明符为%d
(int),因此没有溢出。
您的想法对此是正确的:
printf("Max Char+1 = %d\n",(char)(CHAR_MAX+1));
让我们回顾一下这行代码:
CHAR_MAX+1
的int
值等于0x00000080(128) char
,将被截断为char
值0x80(-128) printf
,它将扩展为int
值0xFFFFFF80(-128) 由于您没有在代码中将其int
为char
,因此int
值0x00000080将“按原样”传递给printf
。
上面的答案是基于您平台上的CHAR_BIT
为8且sizeof(int)
为4的假设。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.