在C语言中,有过各种各样的数据类型,如:int,char ,short,long,long long,float,double等,其中,整形分为有符号和无符号。今天,我就以char类型为例子剖析C语言整型的取值范围。



char类型的三个有趣代码

测试环境为vs2010,不同的编辑器对char的定义为signed char还是unsigned char是不同的,vs2010将char定义为signed char。

  • 第一个
#include<stdio.h>
int main ()
{char a = -128;printf("%u\n",a);return 0;
}

运行结果如下:

当我们将a的初始化的值改为128,又会发生什么呢?

#include<stdio.h>
int main ()
{char a = 128;printf("%u\n",a);return 0;
}


观察可以发现,两个程序的运行结果一模一样,那么,我提出两个问题。

  • 为什么两个程序运行结果一模一样
  • 为什么打印的是这个数字


  • 第二个
#include<stdio.h>
#include<string.h>
int main ()
{char arr[1000];int i = 0;for(i=0;i<1000;i++){arr[i] = -1-i;}//求该数组的长度printf("%d",strlen(arr));return 0;
}

运行结果如下:

我再提出一个问题。

  • 为什么该数组的长度是255?


  • 第三个
#include<stdio.h>
int main ()
{unsigned char i = 0;for(i=0;i<=255;i++){printf("hello world.\n");}return 0;
}

运行结果如下:

死循环打印hello world.

  • 为什么for循环的每次都在接近限制条件,还是死循环了呢?


这四个问题,可以深入思考,等到文章末尾讲完char类型的取值范围,我再解答这四个问题。



signed char的取值范围

char类型有1个字节,也就是8个比特位。

下面我以二进制位来分析取值范围

00 00 00 00 ------- 0
00 00 00 01 --------1
00 00 00 02 --------2
……
……
……
01 11 11 11 --------127

到目前为止,二进制位的还是符合逻辑的,接着分析。

01 11 11 11 ---------127
10 00 00 00 ----------(-128)

这下子就有人疑惑了,127加1变成了-128?别急,听我分析。

我们注意一下,标题就已经表明,我要谈论的是signed char,也就是有符号char,那么即然是有符号的,我们的第一位便是符号位,代表的是正负,10 00 00 00,从这个方面来看,它就不是一个正数。

-128本身是一个半计算半规定的一个数字,我来分析。
首先,写出-128的原码是1 10 00 00 00 ,有人可能疑问这里为什么是9个比特位,在这里我们写的是-128的原码,而不是规定在char类型上写-128的原码。

原码:1 10 00 00 00
反码:1 01 11 11 11
补码:1 10 00 00 00

当我们存入char类型时,发生截断,即为:10 00 00 00。
观察可以发现,这不就是我们上面-128在signed char类型的补码相同吗。

而当我们对10 00 00 00这个数进行取值时,原码为:00 00 00 00,所以才有-128是一个半计算半规定的数字的说法,存的时候计算,取的时候规定为-128。

我们继续分析,signed char的取值范围。

00 00 00 00 ------- 0
00 00 00 01 --------1
00 00 00 02 --------2
……
……
……
01 11 11 11 --------127
10 00 00 00 ---------(-128)
10 00 00 01 ---------(-127)
10 00 00 10 ---------(-126)
10 00 00 11 ----------(-125)
……
……
……
11 11 11 11 ----------(-1)

总结:signed char的取值范围是-128~127。

unsigned char的取值范围

由于无符号char类型的二进制位本身就都是数值位,没有符号位,那么对unsigned char的取值范围的分析就更简单了。

00 00 00 01 ----------1
00 00 00 10 ----------2
00 00 00 11 ----------3
00 00 01 00 ----------4
……
……
……
01 11 11 11 -----------127
10 00 00 00 ----------128
10 00 00 01 ----------129
10 00 00 10 ----------130
……
……
……
11 11 11 11 -----------255

总结:unsigned char的取值范围是1~255。

各种整形的取值范围

以char为例子,我们懂得了分析某个整形类型的取值范围的方法,在分析其他整形类型时,我们就可以分为signed类型和unsigned类型,以二进制位为突破口进行分析。

解决三个代码

  • 第一个
    为什么两个程序的运行结果一模一样?

答:vs的环境下,char类型默认为signed char类型,所以取值范围是-128~127,第二个程序的a的值是128超过了取值范围,128可以看成127+1,即为-128,也就是与第一个程序的值相同。

127在内存存储为:01 11 11 11
127加一,二进制表达式加1
10 00 00 00
前面我们已经解释了该二进制位为-128

为什么打印的是该数字?

-128在内存中的存储是10 00 00 00

%u打印
需要整形提升

因为是signed char类型
发生整形提升时,补符号位,也就是1

即为11111111 11111111 11111111 10000000

该二进制的结果如下:

  • 第二个
    为什么该数组的长度是255?

strlen函数遇到0会停止('\0’的ascall码值是0),并且不把0计入,所以长度便是-128到127,也就是255。

为什么-128变成了127呢?
程序是的循环是 -1 - i
当i为127时,-1 - i 也就是-128
当i为128时,-1 - i ,也就是-129
-129 可以看成在-128的基础上减1
-128在内存中的存储是 10 00 00 00(char类型),8个字节
-128-1,即10 00 00 00减一
也就是 01 11 11 11
也就是127

  • 第三个
    为什么for循环的每次都在接近限制条件,还是死循环了呢?

当i为0到255之前,程序并未出现问题

但当i = 255时,再进行加一
而unsigned char的取值范围为1~255
一旦255+1便超过了取值范围

255的原码 11 11 11 11
加一
1 00 00 00 00
而unsigned char只有一个字节内存,也就是8个比特位
发生截断
00 00 00 00
又变成了0
死循环

今天的分享就到此,喜欢的点赞加关注,下期更精彩。

深度剖析C语言中整形的取值范围相关推荐

  1. 深度剖析C语言结构体

    深度剖析C语言结构体 1.什么是结构 2.结构体的声明 3.结构体变量的定义 4.结构成员变量的访问: 5.结构体变量的初始化: 6.嵌套的结构体: 7.结构体数组: 8.typedef 9.结构的自 ...

  2. C/C++ 语言中的表达式求值

    转载地址:http://www.cnblogs.com/heyonggang/p/3340301.html 在此,首先向裘老师致敬! 裘宗燕:C/C++ 语言中的表达式求值 经常可以在一些讨论组里看到 ...

  3. python在json文件中查找指定数据_Python中json的取值 如何使用python提取json中指定字段的数据...

    python中为什么用json有什么作用 如何用python读取json里面的值啊我爱你,所以我给了你伤害我的权力,只要我能忍受,我会一直陪伴着你,但你不能伤害我太多. 数据如下,我想要读取name. ...

  4. 裘宗燕:C/C++ 语言中的表达式求值

    裘宗燕:C/C++ 语言中的表达式求值 经常可以在一些讨论组里看到下面的提问:"谁知道下面C语句给n赋什么值?" m = 1; n = m+++m++; 最近有位不相识的朋友发em ...

  5. C/C++ 语言中表达式的求值

    原文http://www.math.pku.edu.cn/teachers/qiuzy/technotes/expression2009.pdf C/C++ 语言中表达式的求值  裘宗燕  北京大学数 ...

  6. vue 取数组第一个值_vue遍历对象中的数组取值示例

    前几天小项目,没考虑周全,让后端改接口,改成数组中包含对象中包含数组的形式,后来越琢磨越不对,后台把所有数据放在了一个对象里,我拿弹窗数据不好拿,索性又改了回来,把后端折腾够呛,自己也折腾够呛,发上来 ...

  7. 决定c++语言中函数的返回值类型的是,全国2009年10月高等教育自学考试C++程序设计试题及部分参考答案...

    全国2009年10月高等教育自学考试 C++程序设计试题 课程代码:04737 一.单项选择题(本大题共20小题,每小题1分,共20分) 在每小题列出的四个备选项中只有一个是符合题目要求的,请将其代码 ...

  8. datetime 比较_Python 字典中key命中取值的两种方法性能比较!

    起步 从字典中取值有两个方法,一个是先判断key是否在字典中再取值:另一个是包裹try块中直接去取值: Python资源共享群:484031800 def use_in(d, key):if key ...

  9. Java|Java中int的取值范围是多少

    Java 中 int 的取值范围是:-2^31 ~ 2^31-1 大致想一下,int 占 4字节,也就是 32 位,int 是有符号的,最高位为符号位.所以剩下31个位置. 那么我们大胆猜测一下,最大 ...

  10. Java中int的取值范围

    先上代码,通过下面代码的执行结果观察 public class Test {public static void main(String[] args) {// 2的31次方int j = (int) ...

最新文章

  1. python大学课程-大学只安排了C和Python课程,是否有必要学习一下Java
  2. LeetCode Spiral Matrix II (生成螺旋矩阵)
  3. rebar Erlang构建工具(转)
  4. 快速构建Windows 8风格应用10-设备方向
  5. Git删除分支/恢复分支
  6. 数学猜想验证步骤_高中数学解题思路与技巧汇总,19种解题方法,实用!
  7. gradle是否可以编译c语言,build.gradle按条件编译与cmake配置
  8. java if和else if的区别_关于C语言中if,elseif和else的区别在哪里
  9. docker加载新的镜像后repository和tag名称都为none的解决方法
  10. LUT查表法乘法器所犯下错误。。。。
  11. python读取指定路径txt文件-python读取txt文件并取其某一列数据的示例
  12. python生成词云_词云制作没那么难,Python 10 行代码就实现了!
  13. Java实现微信轰炸
  14. ​关于技术变现的几点思考
  15. sublime补全java代码快捷键_Sublime快捷键
  16. 论文解读:PV-RCNN: Point-Voxel Feature Set Abstraction for 3D Object Detection
  17. 很好的万年历代码。随时可运行
  18. 中国最大的“隐形首富”,掌舵中国最大汽车集团,身价高达760亿
  19. 数控机床是什么编程php吗,数控车床编程实例
  20. 应用层 DNS域名解析服务器 文件传送协议FTP 简单邮件传送协议SMTP 万维网 HTTP超文本协议

热门文章

  1. 2023中国眼博会/护眼仪/CEYEE青少年眼健康产业展览会
  2. 关于Windows下装jupyter
  3. Ubuntu编译OpenPose的一些坑(附可能涉及的码云地址)
  4. 【dsPIC33】振荡器与定时器
  5. Android烂笔头
  6. 5月6阴阳师服务器维护,《阴阳师》手游5月6日维护更新公告
  7. 条形码怎么看?一文带你认识!
  8. 笔记(待续)-基于梯度下降法的RBF神经网络控制
  9. ST-Link该如何升级?
  10. php七牛云,php七牛云