当前课程知识点:C++语言程序设计基础 > 第1章 绪论 > 信息的表示和储存 > 数据的编码表示
数据在计算机中的编码表示
l需要解决的问题:负数如何表示?
l最容易想到的方案:
0:表示“+”号;
1:表示“-”号。
l原码
n"符号──绝对值"表示的编码
例如:
n原码的缺点:
u零的表示不惟一
[+0]原=000...0
[-0]原=100...0
u进行四则运算时,符号位须单独处理,运算规则复杂。
l补码
n符号位可作为数值参加运算;
n减法运算可转换为加法运算;
n0的表示唯一。
l补码的原理
n模数:
n位二进制整数的模数为2n;
n位二进制小数的模数为2。
n补数:
u一个数减去另一个数(加一个负数),等于第一个数加第二个数的补数,例(时钟指针):8+(-2)=8+10(mod12)=6;
u一个二进制负数可用其模数与真值做加法(模减去该数的绝对值)求得其补码,例(时钟指针):-2+12=10。
l补码的计算
n借助于“反码”作为中间码;
n负数的反码与原码有如下关系:
符号位不变(仍用1表示),其余各位取反(0变1,1变0),例如:
X=-1100110[X]原=11100110[X]反=10011001
n正数的反码与原码表示相同,正数的补码与原码相同;
n反码只是求补码时的中间码;
n负数的补码由该数反码的末位加1求得。
n对补码再求补即得到原码。
l补码的优点:
n0的表示唯一;
n符号位可作为数值参加运算;
n补码运算的结果仍为补码。
l计算机中通常采用浮点方式表示小数;
l实数N用浮点形式可表示为:N=M×2E
E:2的幂,N:阶码;
M:N的尾数。
l字符在计算机中是通过编码表示的;
l例如:
ASCII码是一种常用的西文字符编码:用7位二进制数表示一个字符,最多可以表示27=128个字符;
l《GB18030-2005信息技术中文编码字符集》是中国国家标准。
接下来我们来考虑
二进制数的编码表示问题
大家可能会有疑问
二进制数了
机器都可以识别和理解了
还要编什么码呢
那么请大家考虑一个问题
一个二进制的负整数
在系统中如何表示
整数我们可以把它变成二进制
十进制变成二进制在系统里表示
这个没有问题了
那么负号用什么表示
这就是我们要考虑的
用什么样的编码来表示这个数据
比较方便
大家第一下想到的可能就是什么
干脆我用0和1来表示
用0表示整数 +号
用1表示-号是不是可以呀
很多同学我相信
直观就想到这个主意了
这个确实是一种编码
它叫做原码
也叫做符号绝对值表示方法
那么这种表示法
完美不完美呢
仅仅从存储和表示的角度
它貌似很完美了
符号用0和1解决了
数值绝对值
你还是用0和1编码就可以了
二进制的值很好了
但是我们考虑一下
0怎么表示 0很特殊
0前面加+号加-号
它不都是0吗
这个大家已经很习惯了
没有问题但是在计算机里面
如果0出现两种可能的表示方法
这是一件很麻烦的事情
还有一点你要计算怎么办
你要做加减乘除计算的时候
那个-号带在那儿得单独处理
不是说这种事解决不了
你可以写算法
把-号单独处理
去处理写这个运算的算法
但是它很麻烦
那么有没有一种码
能比较让我们满意呢
补码是一个
让我们还比较满意的码
首先它的0的表示是唯一的
还有在计算过程中
符号位可以直接参加运算
也就是那个-号
我们一切的编码说的都是什么
都是负整数的事
现在说的是负整数的事
正整数没什么再需要编码的了
它写个二进制的绝对值就行了
就是用原码就行了
就用原码就行了
但是负数怎么表示
那就要考虑什么编码比较好
补码这种形式就比较好
既可以用统一的方式表示0
又可以让符号位直接参与运算
那么补码到底是什么呢
补码的原理又是什么呢
我们就要了解一个模数的概念
一个补数的概念
举一个例子
比如说我们钟表转一圈是12点
那我们知道我们的计时系统
可以是12小时制的
也可以是24小时制的对吧
如果你用12小时制的呢
13点就是1点 18点就是6点
这就是一个
它用的模数是什么
就是一圈的整圈
12 就是它的模数
那么这个时候呢
什么数跟什么数之间
是补数的关系呢
比如说8-2是几是6
那8+10 是18
18要对于12取模
取模就是除以12取余数
18对12取模得到的也是6
那这就说明这两个数
它们是一个补数的关系
减去一个数
跟加上它的补数效果是一样的
那么计算机系统呢
是一个二进制系统
最多它就是0和1两个数
它没有12个数
所以它的模数都是2的多少次方
这样来计算
看你有多少位
是2的多少次方
来计算这个模数的
那么补码的原理呢
就是从这儿推导出来的
但是作为一个程序设计课
大家作为初学者呢
可以不去理解它的原理
如果大家想去理解这个原理呢
去找一本计算机组成原理的书
来看
在计算机组成原理的课里面
都会详细地讲
这个补码的原理上的推导过程
那么现在我们要了解的是什么呢
求补码的计算规则
在计算机里面
是怎么去求一个补码的
非常简单
但是它要借助一个中间码
叫什么反码
从原码到补码不是一下飞过来的
中间经过一个反
叫做反码的编码过程
反码又是什么呢
反码就是在原码的基础上
保持这个负数的符号位
最高位这个1不变
除了符号位以外的其他位
反转一下0变1 1变0
这就得到了这个负整数的反码
而正整数的反码呢
不反还是它自己
正整数的原码反码
补码都是它自己一样
哪个也别求反
所有这些编码规则
我们解决的都是
怎么表示负号的问题
怎么让负数参与运算的问题
得到了反码以后有什么用呢
反码本身
只是一个求补码过程中的中间码
它自己没任何用途
得到了反码以后
再做一点点事情就到了补码了
什么呢在它最末位
最低位加1
所以简单地讲这个口诀就是
补码怎么求原码求反+1
简称求反+1
实际上就是原码的负数符号位
保持不动
其他的各个位都0变1
1变0反一下
最后在末位再+1
就形成了补码
那么这样形成的补码有什么好处
刚才说了它的好处就是
零的表示唯一了
你写不出来+0 -0了
它就是一种0的表示
还有呢参与运算的时候
你要做加法
连符号位带数值位一起去加
一起参与运算
那一起参与运算
得到的结果会对吗会对的
补码参与运算得到的结果是什么
仍然是补码
如果你要想把补码再变回原码去
怎么变呢
你把补码的符号位保持不动
再次求反+1就行了
那么同学们学了这个以后
可能回去会找一些数据
来做点加法
求求补码做点加法试试
然后总会有人发现不对呀
两个负数的补码我相加
两个负数相加
加完当然结果还是负数
怎么最后一进位一进位
把那个符号位给顶出去了
变成正数了为什么
这是我们后面要讲的
数据它有表示范围
比如你总共用8位表示一个整数
你进位进位这个数太大了
把最高位给顶出去了
补上来的跟最高位原来的不一样
那就造成了什么
比如说两个正数相加
结果变负数了
两个负数相加结果变正数了
这就说明是溢出了
你的数太大了
就给你8位不够了
当然给你32位也有不够的时候
我们在纸上写数字
它是没有限度的只有边沿
你还可以再粘一张纸给它贴上
继续去写
用计算机来存储数据的话
你不管给它8位 16位 32位
64位
你不管这个语法规定
给它多少位来存放这个数据
它总有数大到一定程度
放不下的时候
它就叫溢出了
当然了大到一定程度放不下
我们也不是就没有办法了
专门的大数运算
也有它一定的特定的算法
多个存储单元咱们拼起来
就跟把纸粘起来似的
大家以后有程序设计经验了
可以专门去研究一下
这个大数怎么表示和运算
作为初学的入门课程
我们只考虑在我们规定的
这个位数范围之内能表示的数据
它怎么表示怎么存储和运算
好接下来呢
我们来考虑小数
在计算机中怎么表示
小数有小数点就是实数了
实数它有整数部分
有小数部分中间还有个小数点
那么在计算机中
这个小数点怎么表示
说我再找个编码去表示那个点
那倒不用了
实际上呢
表示实数有两种方案
一种是定点方案
一种是浮点的方案
所谓定点方案就是小数点固定
比如说我总共给32位
表示一个浮点数
那我在这个系统里的约定
小数点在第多少位的
分界点位置上
那么这一半是整数
那一半是小数
这叫定点方式
定点方式它有什么缺点呢
就是特别大的数
和特别小的数它没法表示
所以定点方案早期有过
现在一般系统里面
表示实数都不会再用定点方式
来表示了用什么
用小数点浮动的方式来表示
这也就是为什么我们在C语言
C++语言中说到实数
都不叫它实数叫它浮点数
说它是用小数点浮动的方式
表示的实数
小数点浮动的方式
实际上大家也不陌生
就类似于我们平常数学中习惯的
那个十进制的科学计数法一样
我们说1.23乘10的15次方
大家经常这样写
那么在计算机系统中呢
它是二进制的
所以它都是一个尾数
乘以2的多少次方
用这样的方式来表示一个实数
也就是浮点方式
这样的方式表示一个实数
当数据要溢出的时候
是什么溢出
是它2的多少次幂
那个阶码溢出
那么尾数呢
它能表示多少位有效数字
取决于你给它多少位
来表示这个尾数
像浮点数的表示呢
也有很多相关的标准的
每个编译器的实现可能也不一样
这个我们就不深入去讲它了
大家理解浮点数
是用小数点浮动的方式来表示的
就可以了
那么接下来字符数据
在计算机中是怎么表示的呢
当然也是编码表示的
每一个字符都要用一种规则
给它编成二进制的码
来存储和处理
那么常用的比如说ASCII码
是西文字符常用的一种编码方案
那么汉字呢
我们有国家标准
中国国家标准GB18030
大家如果感兴趣的话
也可以去下载
去找那个标准来看一看
它是一个很全的汉字编码方案
所有这些字符类型的数据
在计算机系统中
也是用编码来表示的
好那么在这一讲中呢
我们学习了信息在计算机中
是如何表示的
我们知道了
为什么要去研究这些问题
因为计算机只有二进制
二进制能够表示整数
但是我们还要考虑负数问题
以及负数的计算问题
二进制也能够表示实数
但是我们要考虑
很大的实数和很小的实数
是不是都能够有效地利用
你给的存储位数
去表现的很好表示的很好
那么这一个呢
就是实数的浮点表示方法
那么还有所有的字符型的数据
也都会变成编码在这里面表示
这样我们知道了
计算机怎么样存储和表示数据
以后我们再用计算机写程序
去存储和计算这些数据
大家心里就比较清楚
我们做的到底是什么
该怎么样把这个事情做得更好了
好这一讲就是这样
-导学
--第1章导学
-计算机系统简介
--计算机系统简介
--计算机系统简介 测试题
-计算机语言和程序设计方法的发展
--计算机语言和程序设计方法的发展 测试题
-面向对象的基本概念
--面向对象的基本概念 测试题
-程序的开发过程
--程序的开发过程
--程序的开发过程 测试题
-信息的表示和储存
--计算机的数字系统
--数据的编码表示
--信息的表示和储存 测试题
-实验指导
-导学
--第二章导学
-C++语言概述
--C++语言概述 测试题
-基本数据类型、常量、变量
--程序举例
--基本数据类型、常量、变量 测试题
-运算与表达式
--运算与表达式 测试题
-实验二:简单程序设计(上)
-数据的输入和输出
--数据的输入和输出
--数据的输入和输出 测试题
-选择结构
--if语句
--switch语句
--选择结构 测试题
-循环结构
--for语句
--循环结构 测试题
-自定义类型
--自定义类型
--自定义类型
-第2章小结
--第二章小结
-实验二:C++简单程序设计(下)
-导学
--导学
-函数定义
--函数定义
--函数定义 测试题
-函数调用
--例3-2
--例3-3
--例3-4
--例3-5
--例3-6
--函数调用 测试题
-嵌套与递归
--例3-9
--例3-10
--嵌套与递归 测试题
-函数的参数传递
--函数的参数传递
--函数的参数传递 测试题
-引用类型
--引用类型 测试题
-含有可变参数的函数
--含有可变参数的函数 测试题
-内联函数
--内联函数 测试题
-constexpr函数
--CONSTEXPR函数课后习题
-带默认参数值的函数
--带默认参数值的函数 测试题
-函数重载
--函数重载 测试题
-C++系统函数
--C++系统函数习题
-第3章小结
--第三章小结
-实验三(上)函数的应用
-实验三(下)函数的应用
-导学
--导学
-面向对象程序的基本特点
--面向对象程序的基本特点 测试题
-类和对象
--类和对象的定义
--类和对象 测试题
-构造函数
--构造函数基本概念
--委托构造函数
--复制构造函数
--构造函数 测试题
-析构函数
--析构函数
--析构函数 测试题
-类的组合
--类的组合
--类的组合程序举例
--前向引用声明
--类的组合 测试题
-UML简介
--UML简介
--UML简介课后习题
-结构体与联合体
--结构体与联合体 测试题
-枚举类
--枚举类
--枚举类 测试题
-第4章小结
--第四章小结
-实验四(上)
--实验四(上)
-实验四(下)
--实验四(下)
-导学
--导学
-标识符的作用域与可见性
--标识符的作用域与可见性 测试题
-对象的生存期
--对象的生存期
--对象的生存期 测试题
-类的静态成员
--类的静态成员 测试题
-类的友元
--类的友元 测试题
-共享数据的保护
--共享数据的保护 测试题
-多文件结构和预编译命令
--多文件结构和预编译命令 测试题
-第5章小结
--小结
-实验五
--实验五
-导学
--导学
-数组的定义与初始化
--数组的定义与使用
--一维数组应用举例
--数组的定义与初始化 测试题
-数组作为函数的参数
--数组作为函数的参数 测试题
-对象数组
--对象数组
--对象数组 测试题
-基于范围的for循环
-指针的定义和运算
--指针的定义和运算 测试题
-综合实例
--综合实例
-实验六(上)
--实验六上
-指针与数组
--指针数组
--指针与数组 测试题
-指针与函数
--指针类型的函数
--指向函数的指针
--指针与函数 测试题
-对象指针
--对象指针
--对象指针 测试题
-动态内存分配
--动态内存分配 测试题
-智能指针
--智能指针
-vector对象
--vector对象
--vector对象 测试题
-对象复制与移动
--移动构造
--对象复制与移动 测试题
-字符串
--C风格字符串
--string类
--字符串 测试题
-第6章小结
--第六章小结
-综合实例
--综合实例
-实验六(下)
--实验六(下)