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类型的溢出问题的更多相关文章
- 在vs中char类型的实参与LPCWSTR类型的形参类型不兼容怎么解决?
今天在做 COS脚本解释器的时候,遇到了这个问题 先了解一下 LPCTCHAR 这个东东 LPCTSTR用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么 ...
- 加深关于Java中char类型的理解
1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a'; //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...
- C#和C++中char类型的区别
对于char,这个字符类型.我们一般都认为就是一个字节.今天在仔细比较发现,C#的char和C++的char是有区别的. 1.首先来看C#中char占多大空间 using System;using S ...
- 怎么解决ORACLE 中 CHAR类型的索引问题
在很多场景中,都有如下情况 trim(a.colunm1) = trim(b.colunm2) 应该怎么优化呢? 用到 TRIM 的很多原因是某些系统为了提高查询效率,不使用 ORACLE 的特有的 ...
- C中char类型的用法
代码 /* char类型的用法 */ #include <stdio.h> main(int argc, char *argv[]) { /* 声明字符变量c1 */ char c1 = ...
- c++中char类型字符串拼接以及int类型转换为char类型 && 创建文件夹
如下所示: #include <iostream> #include <windows.h> #include <cstring> using namespace ...
- C++中char类型的十六进制字符串转换成字节流
如a[5]="1234"转换成a[5]={0x12,0x34} 代码如下: void HexStrToByte(const char* source, unsigned char* ...
- c++中char类型的取值范围
-128~127,数字在计算机中以补码形式存储,因为正数的补码就是其本身且正数符号位置0,故最大值为01111111(一个0七个1)也就是127 而负数是对应正数值取反加一,拿最大的负数-1来说,就是 ...
- C#中char空值的几种表示方式
C#中char空值的几种表示方式 在C#中char类型的表示方式通常是用单引号作为分隔符,而字符串是用双引号作为分隔符. 例如: 程序代码 程序代码 char a = 'a'; char b = 'b ...
随机推荐
- Oracle 远程访问配置
服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 # listener.ora N ...
- 第15章-输入/输出 --- 理解Java的IO流
(一)理解Java的IO流 JAVA的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出(键盘.文件.网络连接等)抽象表述为"流"( ...
- access登录校验代码二
' 这一段是用来检查有没有输入用户名或密码的If IsNull(Trim(Me.username )) ThenDoCmd.BeepMsgBox ("请输入用户名称! ")Else ...
- ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?
官方已经给出解决方案:https://github.com/pyenv/pyenv/wiki/Common-build-problems#error-the-python-ssl-extension- ...
- 关于JavaScript的那些话
1.初学者动手环境----推荐Chrome的控制台(F12调用)2.JS中两个非常重要的数据类型是对象和数组.3.JavaScript 程序是用Unicode字符集编写的.4.JavaScript是区 ...
- JavaScript函数节流和函数防抖之间的区别
一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变 ...
- 程序员快递请查收,来自Python黑客大佬的一份DDOS攻击说明书!
DDoS攻击没有我们想象中的那么简单,并不是什么Python程序员都能够做到的. 若要知晓黑客利用DDOS攻击原理那么我们必须要知道是实行DDoS攻击比较难的原因是什么? 很简单的一句话概括:&quo ...
- 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)
lASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操 ...
- js基础进阶--关于setTimeout的思考
欢迎访问我的个人博客:http://www.xiaolongwu.cn 先热身 看看下面的额代码会打印出什么? for (var i = 0; i < 5; i++) { setTimeout( ...
- Spring Boot实战笔记(二)-- Spring常用配置(Scope、Spring EL和资源调用)
一.Bean的Scope Scope描述的是Spring容器如何新建Bean实例的.Spring的Scope有以下几种,通过@Scope注解来实现. (1)Singleton:一个Spring容器中只 ...