欢迎回到C++程序设计 那麽接下来我们要来看一下 我们常用的一些数据 比如说整形数据 实性数据 字符形数据 是怎麽存放在计算机的存储器中的 因为我们知道 如果想让计算机处理这些数据 必须把这些数据保存成二进制的形式 在存储器裡面才可以 所以我们接下来要研究的问题 就是如何把我们常用的整形 实形 字符形数据 转换成二进制的形式 保存在计算机的存储器裡面 首先我们先来看整数在计算机中的一个表示 那我们知道计算机裡面只有0和1两种数据形式 而整数它是有正整数和负整数 是有正负之分的 因此我们还要想办法将一个数的正负 也要用0和1来进行表示 那麽我们就规定 如果这个数是一个正数的话 那麽最高位 它佔的这个字节的最高位这一位 那麽作为符号位应该放著0 也就是说最高位为0 这个数就是一个正数 如果最高位为1 这个数就是一个负数 那麽这就是我们整数在计算机中的表示形式 那麽按照这个规则 我们来写一下一个数的圆码 所谓的圆码就是按照我们刚才说的符号位为0 就是正数 符号位为1 就是负数的这样一个原则写出来的这个整形数据 那麽这下我们假定一个数在计算机中佔一个字节 也就是8位 每一个位都是用来放一个0或者放一个1的 好 那麽这8位来怎麽分配呢 我们说对于圆码来说 它的最高位为符号位 所以我们的负数最高位为1 而正数的最高位为1 举个例子 比如说我要存放一个正7 那麽存放在这一个字节裡面怎麽存放呢 那麽因为它是一个正数 所以最高位这个符号位为0 那麽因为它的值为7 所以第3位都为1 然后中间4位为0 那麽如果是一个负7 只需要将最高位从0变成1 就是负7的这个圆码了 好 那麽用圆码来表示我们的这个整数 那麽科学不科学呢 我们来看一下这个计算 我们知道负1加1的值应该是0 但是如果用圆码来进行这样的运算结果 是不是0呢 我们看一下 比如说正1它的圆码就是高7位全部为0 最低位为1 那麽如果是负1呢 最高位变成了1了 其他都是一样的 好 那麽这样的两个数相加 我们看1+1=0 往上进一位是1 然后中间几位全部为0 最高位也变成1了 那我们看运算的结果是不是不对啊 首先运算的结果最高位为1 所以它是一个负数 那麽是负几呢 是负2 也就是说负1加正1没有得到我们想得到的0 而得到了一个负2的值 那麽这个错误的原因在哪呢 错误的原因是不是就在于这个符号位啊 这个符号位的运算是错误的 所以在计算机裡面用圆码来保存数据肯定是不可以的了 那麽于是人们想办法又出现了这个反码 那我们看看反码可不可以 反码是什麽样的呢 对于正数来说 圆码和反码都是一样的 那麽对于负数来说 反码为将圆码除了符号位以外的所有位都按位取反 所谓按位取反就是0变1 1变0 那麽对于负数来说 我们的圆码和反码是不一样的 比如说正7 那麽它的圆码和反码都是这样写的 那麽如果是负7呢 就是除了符号位以外 圆码的符号位是1 那麽这个1仍然不变 然后低7位呢 都取反 就变成了高位为5个1 低位为3个0了 好 那麽这就是负7的这个反码 好 那麽我们看解决没解决我们刚才说的那个问题呢 我们再用负1加1的这样的一个反码来进行一个运算 我们看 正1的圆码和反码是一样的 那麽对于负1来说 就是将它的圆码 然后除了符号位以外全部按位取反 所以得到的结果就是高7位全部为1 最低位为0 好 那麽相加的结果我们看就是8位全部为1了 那麽相加的结果肯定也是一个反码了 那我们再把它转换成这个圆码 我们看是几啊 是不是就是负0啊 就8位全部为1相当于就是一个负0 也就是说反码仍然存在著一个问题 就是有正0和负0之分 那我们知道在我们的习惯裡面0就是0 哪有什麽正0和负0啊 所以反码仍然存在著这个缺陷 那麽怎麽办呢 于是人们又想出了一个办法就是补码 那麽对于正数来说 圆码 反码 补码都是一样的 那麽如果是负数的话 那麽补码就为将反码的值再加上一个1就形成了补码了 好 那我们来看一下这个补码的计算 比如说正7仍然是这样的一个形式 那麽负7就为在刚才反码的计算上再加上一个1 所以最低位也变成一个1了 好 那我们看解决没解决这个正0 负0的问题 我们看 那麽正1的这个补码仍然是这样的一个状态了 那麽负1它的补码就是在反码的计算上再加一个1 所以就变成8位全部为1了 好 那麽相加的结果 我们看 两个1相加等于0 向上进一位 两个1相加等于0 向上进一位 一直进位 一直进位 直到在有一个1 最高位的这个1是不是给1出出去了 因为我们这一个数只佔一个字节 我们假定只佔一个字节 所以我们只观察这一个字节裡面的这个位到底是0还是1 那麽出去的这个1呢 我们就不关心它了 所以这一个字节现在裡面放的就是8个0 那我们说 是不是就是我们说的这个0这个值啊 所以补码就取消掉了正0 负0的这个区分 是比较科学的 所以我们说 一个整数 不管是正整数还是负整数 它存放在计算机裡面 都是按照补码的形式来进行存放的 那麽理解了这个数据在内存中是怎麽存放的 那麽有利于将来我们编程的时候 不会去犯一些错误 好 那麽下来我们看两个例题 比如说我们对负9和9进行一个计算 我们看负9的补码是这样写 那麽9的补码是这样写 那麽相加的结果呢 是不是就是0了 那麽因为再往上进的这一位呢 我们就取消掉了 我们只看这一个字节 对吧 那我们再看65+66的结果 对不对 65转换成二进制是这样子的 66转换成二进制是这样子的 好 那麽接著我们相加 我们看 相加的结果呢 我们看 首先它最高位变成1了 那麽它仍然是一个补码 那麽转换成原码呢 其实就是负的125了 那我们看这还是不是出现错误了 两个正数相加结果变成一个负数了 原因出在哪呢 我们说我们刚才假设一个整数佔的是什麽 8位 对吧 佔的8位 那麽它能表示的最大的这个数是不是有限的呀 那麽8位能表示的最大数是不是就是高位为0 低7位全部为1呀 那麽这个数呢就是127 也就是说我用一位数来表示整数的话 我放的最大的数就是127 而65+66 它的结果明显是不是已经超出127了 所以就导致了这个运算结果的一个错误 那麽这个错误我们在程序中也叫做一出 就说我们不管什麽类型的数据 它佔的存储空间是有限的 那麽有限的存储空间保存的这个数据的大小肯定也是有限的 那麽一旦超过了这个限制 就会出现一出的这个错误 导致这个数据的结果不是你想象的这个结果 那麽一出的这个问题 我们在后面讲数据类型的时候 还会给大家再详细的讲解 接下来我们来看一下伏点数在计算器中的表示 那这个伏点数呢 相当于就是我们数学上的这个小数了 我们也把它叫做实行数据 那麽为什麽它叫伏点数呢 因为这个小数点是可以浮动的 比如说我们说0.1 我可以写成0.1 小数点在0~1之间 我是不是也可以写成1乘以10的负1次方 那麽小数点是不是就跑到1的右边去了 所以我们把这种数就叫做伏点数 那麽数学中的实数 就是小数 在计算机中我们就把它叫做伏点数 它是指小数点不固定的这样一个数 那麽伏点数在计算机中的表示方法比整数相对来说要複杂一些 那麽首先我们要把一个伏点数转换成二性质 我们要先把它转换成规格化的这个数 怎麽转换成规格化数呢 要转换成这种形态 负1乘以s次方乘以2的大e次方再乘以1.f 要先把它转换成这种形式以后 然后再分别把se和f存放在计算机的这个存储器裡面去 那麽在这我们假设一个伏点型数据 它在计算机裡面佔4个字节 每个字节8位 那麽一共就佔了32位 那麽这32位到底是0还是1 怎麽算呢 我们通过一个例子 我们来看一下 首先我们看最高的这一个位是用来存放s的 那麽s相当于是不是就是符号位啊 s为0的时候 负1的0次方就是1 那麽如果它为1的话 负1的1次方就是-1 所以它为0相当于表示的就是一个正数 如果它为1表示的就是一个负数 然后呢 低的这23位是用来放这个f的 就是我们在转换的时候 我们要转换成1.f 就是小数点左边一定是一个1 然后这个e呢 我们这还写的是个大e 但是实际上放在中间8位的是一个小e 那麽大e怎麽转换成小e呢 我们后面的例子会告诉大家 好 那麽知道了这个规格化形式大概的一个写法以后 下来我们看一个具体的例子了 我们现在来看一看这个50.0这个伏点数 放在计算机中4个字节是怎麽来存放的 那麽怎麽计算呢 首先先把50.0转换成二进制 然后呢 再把二进制的形式转换成规格化的形式 我们看规格化的形式就是 这个最右边的这个小数点的左边一定是个1 所以就是1.100100 对吧 然后呢 左边怎麽写呢 负1的0次方 因为它是一个正数 所以它这个s就是0 然后呢 小数点向左移动了几位啊 1 2 3 4 5 所以这号就乘以2的5次方 好 那麽通过转换成规格化的形式 我们就得到了F就是100100 对吧 F我们已经得到了 然后E就是5 就是这个米5 然后s就是0 那麽接著我们要把E转换成e 转换的方法就是在E的基础上再加上127 就得到了132 这就是e的值了 当然我们要把它转换成这个二进制的形式 就是10000100了 好 那麽现在s已经有了 f也有了 这个e也有了 现在我们把它们全部放到相应的位置就可以了 那麽s是这32位的最高位放的是0 然后中间这8位呢 放的是这个e 那麽如果不够8位的话 在右边补0就行了 所以放的就是10000100 好 然后这个F呢 是放在最低的这23位的 所以放的就是100100 然后不够的这些位呢 把它全部补成0就行了 所以我们可以看到50.0存放在4个字节的 这样的一个存储空间裡面 它的每一位是来这样进行存放的 那麽这就是伏典型数据在内存中的表示形式 那麽最后我们再来看一下 西文字符在内存中是怎麽存放的 那麽西文字符其实就是我们的 常用的这个英文字符的那些abcd啊 那些字符叫做西文字符 那麽西文字符就包含了英文字符 数字和各种符号 那麽最常用的西文字符集是美国信息交换标准码 我们也把它称之为ASCII码 那麽ASCII码是怎麽对西文字符来进行编码的呢 它採用的是7位的二进制编码 编码值是从0到127 那麽它可以表示128个字符 它相当于就是用一个数字来表示一个字符 那我们通过这个表 我们来看一下 我们看这个h表示的就是高三位 它是用7位的二进制数来表示的 所以这行 最上面这一行表示的就是最高的这三位 左边这一列呢 就是低四位 对吧 比如说我第一个编码的字符就是000000 它表示的是一个空字符 NUL就是空的意思 空表示的是一个空字符 那我们看採用这样的一个字符编码集 我们一共能够对128个字符进行编码 这128个字符就包含了英文字符裡面的一些常用字符 那麽这些字符呢 分成两个部分 一部分是控制字符 一部分呢 是图形字符 那麽控制字符它就是起控制作用的 而图形字符呢 它就是可以显示到显示器上的这样一些字符 那我们可以看一下 有33个控制字符 分别就是0 十进制的这个ASCII码值 就是从0开始一直到哪呢 一直到32 一直到这个字符 就左边这两列 加上这个字符 它都属于这个 到这行 它都属于这个控制字符 然后最后一个delete D-E-L是delete这样一个控制字符 这33个都是控制字符 那麽剩下的全部呢 都是图形字符 那麽我们可以看一下 那麽它在编码的时候呢 这个数字字符和这个字母字符 它是不是都连在一起的 比如说0的ASCII码是0110000 那麽它的转换成十进制就是65 也就是说 我这个0这个字符在内存中 其实存放的就是65这个数字 那好 接著1这个字符 它的ASCII码值是01100001 那麽是不是就是66啊 因为它接著加了个1嘛 就是66了 那麽0123456789 这都是连续存放的 所以我们只要记住0的ASCII码值 其他字符的ASCII码值 我们是不是都可以计算出来啊 那麽再看这个大写字母和小写字母 也都是连续的 所以我们要记住大写字母的ASCII码值A是65 小写A的ASCII码值是97 把这两个记住了 后面的我们也都可以把它进行计算出来 好 那麽通过刚才的这个解释 我们知道了 其实在ASCII码的这种编码方案中 我们所谓保存一个字符在内存中 其实就是将这个字符的一个ASCII码值把它保存在内存中了 那麽举个例子 比如说大写字母A 那麽我们想象的是保存的是大写字母A 但实际上呢 我们存放的是65这个数字 当然这个数字肯定是以二进制的形式 保存在计算器存储器裡面的 所以通过这个例子呢 我们就知道了 这个字符放在存储器裡面 其实放的就是一个正整数ASCII码值 好 那麽利用这个ASCII码表呢 其实我们也可以做一些特殊的用途 比如说我们键盘上的这个A这个按键给坏掉了 那麽我们在输入的时候是不是就没有办法输入A这个字符了 那麽我们这时候应急的措施是什麽呢 我们可以把键盘上的ALT键给它按下去 按下去以后不要鬆开 然后在键盘右边的这个小键盘呢 输入一个65 输入完了以后再鬆开ALT键 我们就会发现 原来我们就已经成功的输入了一个大写字母A 那麽通过这个小实验就证明了 我们的这个微型计算机这个系统裡面 通常採用的这个编码的一个方式 就是用ASCII码来对英文字符呢 来进行一个编码的 好 那麽这一讲呢 我们就讲到这裡 谢谢大家 再见 (字幕制作:贝尔) (字幕制作:贝尔) (字幕制作:贝尔)