繁体   English   中英

为什么CHAR_MAX + 1不会引起溢出?

[英]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_MAX1 (以及11 )都是int ,而不是char ,因此不会发生溢出。

而且,即使加上

char c = '\x7f';

c + c;

(即char + char )的类型为int ,即使对char进行了signed也不会溢出,因为通常的算术转换适用于+的操作数。 简而言之,这些状态表示在算术运算中,所有操作数都将转换为最大涉及的类型,并且整数提升适用于整数类型。 整数提升表示,在应用它们时,小于int整数类型将转换为至少int ,因此我们再次具有int + int且没有溢出。

关于第一段中“八位二进制位”说明的附录/附带说明:从历史的角度来看,问题超出了二进制计算机上数据类型的位数。 今天它没有什么实际意义,但是C并非在所有普通计算机都使用整数的二进制补码表示的时候编写的。 因此,附件E中为有符号类型给出的实现限制是对称的(例如INT_MAX <= 32767INT_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+1int值等于0x00000080(128)
  • 转换为char ,将被截断为char值0x80(-128)
  • 传递给printf ,它将扩展为int值0xFFFFFF80(-128)

由于您没有在代码中将其intchar ,因此int值0x00000080将“按原样”传递给printf


上面的答案是基于您平台上的CHAR_BIT为8且sizeof(int)为4的假设。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM