C++中char类型的溢出问题

Posted !!-阳光-!!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中char类型的溢出问题相关的知识,希望对你有一定的参考价值。

C++中什么经常会运用到char类型,也会将char类型作为循环语句的循环条件,但往往这里最容易出现错误,容易出现溢出,进入死循环。这里我们就来简单介绍下为什么会出现这种情况。

首先,了解下char类型的取值范围:

char分为无符号(unsigned)和有符号(signed)两种:

   无符号(unsigned)的取值范围:0~255;

   有符号(signed)的取值范围为:-128~127.

   一般我们常用char来声明一个变量,编译器默认为有符号的,即范围为:-128~127.

常见溢出问题:

   知道了char类型的取值范围后,就容易理解为什么会出现溢出了。出现溢出的地方很多都是因为将char类型的变量作为了循环语句的条件部分,这样就很容易出现溢出,这里讲解一下char类型的自增情况。

   一般作为循环条件时,char类型往往被赋值了int类型,如char i = 0,然后i进行自增。

   当i是无符号型时,取值范围为-128 ~ 127,当i=127后再进行自增的时候,这时i就不是等于128了,而是等于-128;当i= -128,再进行自减的时候就不是等于-129,而是等于127.

   当i是有符号型的时候,取值范围为0 ~ 255,当i = 255时,再进行自增,这时i=0,而不是等于256;当i=0,进行自减的时候i= 255,而不是-1.

  这是因为char型对于有符号型,前24位永远和倒数第8位一样,对于无符号型,前24位永远为零。

  造成上面的结果的原因:

  当为有符号型时,当i = 127时,二进制为:0....0 0111 1111,然后加1后,按照上面的原理,变为:1....1 1000 0000,结果i = -128;当i=-128时,减1,二进制变为:0....0 0111 1111,结果i = 127.

  当为无符号时,当i=255时,二进制为:0....0 1111 1111,加1后,按照上面的原理,变为:0....0 0000 0000 ,结果为i= 0;当i = 0时,减1,二进制为:0...0 1111 1111,结果为255.

下面通过一个实例来说明:

#define s8 char
static int k = 0;
void func()
{
  s8 i = 0;
  for(i = 0; i < 128; i++)
 {
    k += i&3;
  }
  printf("k = %d\n", k);
}

这里很多人可能会动笔就计算,算得 k= 192,但结果是错的。

原因:注意i为一个char类型,且为有符号型,并被赋初值0,这里当i = 127的时候,程序会正常进行,然后i自增,变为-128,最后还是满足条件,程序并不会终止,这样就出现了char类型的溢出,程序进入死循环。此时,要么改变循环中的条件,改为:i < 127;或者将i的类型改为int型。

以上是关于C++中char类型的溢出问题的主要内容,如果未能解决你的问题,请参考以下文章

C++基本数据类型的字节数范围大小溢出处理

vector 内存泄漏问题?

C++中string和char[]类型的区别

我在 C++ 程序中遇到堆栈溢出异常

C++ 堆栈内存没有被释放

C++ 堆栈溢出初始化数组