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类型的溢出问题的更多相关文章

  1. 在vs中char类型的实参与LPCWSTR类型的形参类型不兼容怎么解决?

    今天在做 COS脚本解释器的时候,遇到了这个问题 先了解一下 LPCTCHAR 这个东东 LPCTSTR用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么 ...

  2. 加深关于Java中char类型的理解

    1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a';  //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...

  3. C#和C++中char类型的区别

    对于char,这个字符类型.我们一般都认为就是一个字节.今天在仔细比较发现,C#的char和C++的char是有区别的. 1.首先来看C#中char占多大空间 using System;using S ...

  4. 怎么解决ORACLE 中 CHAR类型的索引问题

    在很多场景中,都有如下情况 trim(a.colunm1) = trim(b.colunm2) 应该怎么优化呢? 用到 TRIM 的很多原因是某些系统为了提高查询效率,不使用  ORACLE 的特有的 ...

  5. C中char类型的用法

    代码 /* char类型的用法 */ #include <stdio.h> main(int argc, char *argv[]) { /* 声明字符变量c1 */ char c1 = ...

  6. c++中char类型字符串拼接以及int类型转换为char类型 && 创建文件夹

    如下所示: #include <iostream> #include <windows.h> #include <cstring> using namespace ...

  7. C++中char类型的十六进制字符串转换成字节流

    如a[5]="1234"转换成a[5]={0x12,0x34} 代码如下: void HexStrToByte(const char* source, unsigned char* ...

  8. c++中char类型的取值范围

    -128~127,数字在计算机中以补码形式存储,因为正数的补码就是其本身且正数符号位置0,故最大值为01111111(一个0七个1)也就是127 而负数是对应正数值取反加一,拿最大的负数-1来说,就是 ...

  9. C#中char空值的几种表示方式

    C#中char空值的几种表示方式 在C#中char类型的表示方式通常是用单引号作为分隔符,而字符串是用双引号作为分隔符. 例如: 程序代码 程序代码 char a = 'a'; char b = 'b ...

随机推荐

  1. linux下让irb实现代码自动补全的功能

    我不知道其他系统上irb是否有此功能,但是在ubuntu上ruby2.1.2自带的irb默认是没有代码自动补全功能的,这多少让人觉得有所不便.其实加上也很简单,就是在irb里加载一个模块:requir ...

  2. Javascript的console['']几种常用输入方法

    1.console.log是最常用的输入方法,正常化输出语句,还具有print占位符整数(%d||%i),浮点数(%f),对象(%o),字符(%s); 2.console.error输出错误化的语句 ...

  3. Spring AOP四种实现方式Demo详解与相关知识探究

    一.前言 在网络上看到一篇博客Spring实现AOP的4种方式,博主写的很通俗易懂,但排版实在抓狂,对于我这么一个对排版.代码格式有强迫症的人来说,实在是不能忍受~~~~(>_<)~~~~ ...

  4. jquery.js

    /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license //@ sourceMappingUR ...

  5. lua函数随记

    在大多数Lua语法分析中可以获得这些标准Lua函数. 无可争辩, 我们可以查阅Lua网站, 但是一些少了的函数被Blizzard进行了调整. 下面列出了所有Lua函数. WoW API中的Lua注意在 ...

  6. vue-cli的webpack模版,相关配置文件dev-server.js与webpack.config.js配置解析

    1.下载vue-cli npm install vue-cli -g vue-cli的使用与详细介绍,可以到github上获取https://github.com/vuejs/vue-cli 2.安装 ...

  7. ssh运行环境搭建及测试

    一.运行环境 1.Spring环境 Spring是一站式开发框架,在SSH中主要有以下作用,就像一个大管家: 控制反转(Inversion of Control):类不再自己进行类创建,而是交给Spr ...

  8. php实现点击文字提交表单并传递数据至下一个页面

    <?php $id="4";//等会要把这个数据传到第二个页面 ?> <?php echo "<li>"; echo " ...

  9. windows系统下输入法图标显示设置

    原先任务栏有两个搜狗输入法的标志,还有一个"中/英"的图标:甚至桌面还悬浮这一个搜狗输入法图标. 打开vscode等工具时,桌面悬浮的图标有时可能会遮挡到一些信息,十分不爽. 如今 ...

  10. 函数上下文this

    一般来说谁调用上下文都指向谁,具体有以下几种情况: 1.函数用圆括号调用,函数的上下文是window 注意:所有的全局变量都是window的属性,而函数里边定义的变量谁的属性也不是. 2.函数作为对象 ...