转载自:http://blog.sina.com.cn/s/blog_70ec9a6f01014j1h.html

1char的有无符号类型

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

Ø         若是signed型,就意味着取值范围为[-128,127];

Ø         若是unsigned型,就意味着取值范围为[0,255];

C语言中我们通常直接用类型char,但是它究竟是被当做signed型还是unsigned型,由编译器决定。

C语言允许我们在char前面加上关键字signed或者unsigned,这样,无论在编译器中被当做signed还是unsigned,都会按照前面加的这个关键字来决定。

例如:假设我们现在使用的编译器,把char当做signed来看到,则

char c1;

signed c2;

unsigned c3;

则c1和c2的取值范围都是[-128,127],而c3的取值范围则是[0,255]。

所谓取值范围,是指其值在这个范围之内时,会被正确处理,超出这个范围就会发生溢出。但在这个范围之内,并不意味着它就是可打印字符。这点不要混淆。

2、溢出

1)有符号

c1和c2一样,我们以c1为例来说明。先看向上超过上界的情况:

十进制

十六进制

二进制

126

0000007e

0…0 0111 1110

126

127

0000007f

0…0 0111 1111

127

128

ffffff80

1…1 1000 0000

-128

129

ffffff81

1…1 1000 0001

-127

130

ffffff82

1…1 1000 0010

-126

注:0…0表示24个0,1…1表示24个1

十进制

十六进制

二进制

-127

ffffff81

1…1 1000 0001

127

-128

ffffff80

1…1 1000 0000

-128

-129

0000007f

0…0 0111 1111

127

-130

0000007e

0…0 0111 1110

126

-131

0000007d

0…0 0111 1101

125

-256

00000000

0…0 0000 0000

0

-257

ffffffff

1…1 1111 1111

-1

从这两个表中可以看到,不管是否超过上下届也,不管是负数还是正数,每增加(减少)一个单位,就直接在二进制表示的最后一位上加(减)1。

相加或相减时,都可以先不看前24位:如果倒数第8位变为1,则前面24位全部设置为1,该数被解释为负数;如果倒数第8位变为0,则前面24位全部设置为0,该数被解释为正数。下面我们挑几个例子详细说明:

c1=128;

这时,会在127的最后8位上加1,原来的8位是0111 1111,加1后,变为1000 0000,于是把前面24个位也全部变为1,且该数被表示为负数。其值为-1*2^7+0=-128.

c1=129;

128的最后8位是1000 0000,加上后为1000 0001,前面24位保持1不变。该数被解释为负数,其值为-1*2^7+1=-127.

c1=-129;

-128的最后8位是1000 0000,减去1变为0111 1111,前面24位全部置位0,且该数被解释为正数,其值为2^0+2^1+2^2+2^3+2^4+2^5+2^6=2^7-1=127

c1=-130;

-127的最后8位是0111 1111,减去1变为0111 1110,前面24位全部保持0,且该数被解释为正数,其值为2^1+2^2+2^3+2^4+2^5+2^61=126

c1=-257;

由前面可以类推, -256的最后8位编码是0000 0000,减去1后变为1111 1111,前面24为全部置为1,该数被解释为负数,值为-1*2^7+2^0+2^1+2^2+2^3+2^4+2^5+2^6=-1。

注意:0000 0000减去1,也就是减去0000 0001,单看这8位的话,前面的数较小,我们可以想象在前面那个数的前面再加一个1,变成0001 0000 0000,后面那个数前面加0,变成0000 0000 0000,相减后,我们只看最后8位即可。

2)无符号

我们以c3为例进行说明。

十进制

十六进制

二进制

254

000000fe

0…0 1111 1110

254

255

000000ff

0…0 1111 1111

255

256

00000000

0…0 0000 0000

0

257

00000001

0…0 0000 0001

1

258

00000002

0…0 0000 0010

2

十进制

十六进制

二进制

-2

0000007e

0…0 1111 1110

254

-1

0000007f

0…0 1111 1111

255

0

ffffff80

0…0 0000 0000

0

1

ffffff81

0…0 0000 0001

1

2

ffffff82

0…0 0000 0010

2

其实和有符号型基本相同,唯一的差别就是,前面24位一直都置位0,且该数永远被解释为整数。下面举例说明:

c3=256;

因为255的最后8位是1111 1111,加1后变为0000 0000,所以其值为0;

c3=-1;

因为0的最后8位是0000 0000,减1后变为1111 1111,所以其值为255;

0000 0000减1,相当于减去0000 0001,虽然0的全码是0…0 0000 0000,似乎往上也没法借位,但是我们仍可将0000 0000前面一位加上1,看做0001 0000 0000减去0000 0000 0001,最后得到0000 1111 1111,我们直接去最后8为即可。

归纳:不管是有符号还是无符号,在前面的数小于后面的数时,都可假设在前面的数的上一位加1,而后面的数前面加0,从而进行相减;

另外,相加时,如果最高位,即倒数第8位变为0,只需直接将其变为0即可,其它位不变,不需要进位。

对于无符号型,前24位永远为0,对于有符号型,前24位永远和倒数第8位一样。

有(无)符号char型及其溢出问题的更多相关文章

  1. C语言之将无符号字符型转化为ascii码值

    这个宏是在linux内核中获取的,主要的功能是能够将一个无符号字符型的参数转化为ASCII码值. ASCII : ASCII 编码里包括了128个字符.用 十进制 0  到 127 来表示 .那就对了 ...

  2. 整型,长整型,无符号整型等 大端和小端(Big endian and Little endian)

    一.大端和小端的问题 对于整型.长整型.无符号整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节):而 Little endian ...

  3. 无符号整型 unsigned int、unsigned long、usigned long long、size_t 比较和格式控制

    位数比较 由于数据的长度和平台相关,所以基于 64 位系统比较. Windows Linux unsigned int 32 bits/4294967295 32 bits unsigned long ...

  4. c语言int型和char型的自动类型转换

    ; //机器码为0xff unsigned ; //机器码0xfe if (a <= b){ printf("a <= b\n"); } else{ printf(&q ...

  5. CoreSeek有符号整型

    数据库status字段的值有:-1,0,1 设置过滤字段,发现sql_attr_uint不支持负数,后改用sql_attr_bigint sql_attr_bigint = status sql_at ...

  6. C语言警告:warning C4018: “<”: 有符号/无符号不匹配

    问题如下: 代码出问题之处:   原因分析: strlen返回一个无符号整型,也就是unsigned型,比较时应该两边的数据类型相同,故严格上来说,应该将m定义为unsigned型.       修改 ...

  7. C机器级移位,编码表示 无符号编码表示,有符号编码表示一般最常见的方式是补码

    C机器级移位,编码表示 无符号编码表示,有符号编码表示一般最常见的方式是补码  w位补码所能表示的值范围是 首先我们得心知 补码的最高有效位是符号位,当符号位位1是表示的是负值,当符号位是0是,表示的 ...

  8. JavaScript 32位整型无符号操作

    在 JavaScript 中,所有整数字变量默认都是有符号整数,这意味着什么呢? 有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数. 数值范围从 -2^ ...

  9. 【VHDL】深度讲解二进制无符号和有符号加法处理溢出的问题

    1.Unsigned adders 这个比较简单,只需在A.B前面扩展一位0防止溢出,溢出的数填到第n位cout,n-1到0位就是sum. , 2.Signed adders 一开始也搞不懂下图中为什 ...

随机推荐

  1. 犯罪构成三层次记忆口诀 zt

    犯罪构成三层次记忆口诀 2012-02-17 来源:为你辩护网 浏览次数:232 0 众所周知,犯罪构成“四要件”和犯罪构成“三层次”(“三阶层”)都是分析具体刑事案件的辅助性工具.犯罪构成四要件是指 ...

  2. ChineseCounter.cs 统计中文文本中常用字占比

    http://www.tuicool.com/articles/qmMba2 1 using System; using System.IO; using System.Collections.Gen ...

  3. Android Activity四种加载方式

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  4. Can't find file: './mysql/plugin.frm' (errno: 13)[mysql数据目录迁移错位]错误解决

    大概需要4个步骤,其中第1步通过service mysql stop停止数据库,第4步通过service mysql start启动数据库. 第2步移动数据文件,不知道是否为Ubuntu智能的原因,移 ...

  5. vi中如何去除高亮显示的单词

    在vi命令行模式下输入:set nohlsearch 单词不高亮显示:set hlsearch 单词高亮显示: 如果再次打开仍然显示,则可以随便搜索一个不存在的单词,然后保存,重新打开高亮不在显示:

  6. [原创]使用squish打包与混淆cocos2d-x的lua脚本

    squish是一个开源的用于打包lua脚本的小工具,它的主要功能是将多个lua文件整合成一个文件,并在此基础上做压缩和混淆等处理,混淆和压缩后的代码可以直接被执行而不需要先做解压还原等操作. 它的gi ...

  7. [原][Android]All WebView methods must be called on the same thread.

    问题 webView调用JS出错. class TestJS {         ......         public TestJS(){         }                   ...

  8. MMU(why)

    在ARM中,MMU几个主要作用: 1. I/D Cache 管理      -> 大幅提高代码运行效率. 2. PA/VA 重映射        -> 实现多进程内存空间映射. 3. 内存 ...

  9. ZOJ3469 Food Delivery 区间DP

    题意:有一家快餐店送外卖,现在同时有n个家庭打进电话订购,送货员得以V-1的速度一家一家的运送,但是每一个家庭都有一个不开心的值,每分钟都会增加一倍,值达到一定程度,该家庭将不会再订购外卖了,现在为了 ...

  10. codeforce--600D - Area of Two Circles' Intersection

    题意:求相交圆的面积.借鉴大神代码,精度超高. #include <fstream> #include <iostream> #include <string> # ...