1. 信息在计算机系统中的表示
我们知道,信息在计算机系统中是以二进制的方式进行传送,存储的。那么信息在计算机系统中是如何表示的呢?在这里可分为数值信息和非数值信息两个方面进行讨论。
![](https://i-blog.csdnimg.cn/blog_migrate/c94f8dfafa968ddc6bc9b8b26eec7c93.png)
1.1 数值信息在计算机系统中的表示
数值信息是有正负之分的,因此,在计算机中存储数值信息必须要有表示符号的方法。由于计算机内是采用二进制编码表示,因此,在一般情况下,我们用“0”表示正号,“1”表示符号,符号位数放在数的最高位。
例如,比如我们有十进制数A= +91,B= -91,8位二进制数A=(+1011011),B=(-1011011),A和B可以在计算机中表示为:
A: | 0(符号位) | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
B: | 1(符号位) | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
可以看出,最左边一位代表符号位,它们连同数字本身一起作为一个数。数值信息在计算机内采用符号和数字化处理后,便可以识别和表示带符号的数值信息了,而根据对负数不同的编码方式,又可分为原码、反码、补码三种方式。
1.1.1 原码
同上所述,直接将符号位数字化为0或1,不再进行其他处理,然后将数的绝对值与符号一起编码,即所谓“符号—绝对值表示”的编码,我们称之为原码(未经过其他处理故我们称之为"原")。
其实上面我们已经说了如何用原码表示一个带符号的整数,如上所述,如果用一个字节(8位)放一个整数,其原码表示如下:
A= +91= +0101011 [A原] = 00101011 ;
B= -91= -0101011 [B原] = 10101011 ;
这里的“原”就是机器数,就是存放在计算机里的实际二进制数字,前面带符号的二进制数我们称之为机器数相对应的真值。
那我们采用原码有什么好处呢?首先就是编码很简单,我们只需要将真值里面的符号数转为0或1就可以变为机器数,机器数和真值转换很方便,一看就懂。
那采用原码表示有什么缺陷吗?还真有,第一个就是零的表示不唯一,我们知道,0是没有符号的,+0和-0都是一样的,没有区别的,那么问题来了,我们如何表示0呢?
[+0] = 00000000 [-0]=100000000
以上两个表示方式都对,所以[0]的表示就有了二义性,这就给机器判零带来了麻烦。
第二个缺陷就是直接用原码进行四则运算时,符号位需要单独处理,且运算规则复杂,例如进行一个加法运算,若两数同号,那么要取两数相同的符号作为最终符号;若两数异号,则要用大数减去小树,再把大数的符号作为最终的符号。虽然我们看起来很好理解,但实际上这种操作对计算机来说是及其麻烦的,因此,人们找到了更好的编码方式来代替,那就是补码表示法。
1.1.2 补码
要说到补码,必须先介绍下什么是反码。反码是基于原码基础上按位取反的,但是需要注意的是符号位是不变的。也就是说:
A: | + | 0 | 1 | 0 | 1 | 0 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
A原: | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 |
A反: | 0(不变) | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
和原码一样,反码对0的表示也不唯一。
介绍完反码,我们就可以引出补码的概念,补码在原理上其实是运用了“模数”的概念,在模数系统中有这么一个概念:
若一个数减去另一个数,或者说一个数加上一个负数,等价于第一个数加上第二个数的补数。
比如,我们取模数为12,那么:
8 + (-2) = 8 +10 (mod12) = 6
为什么这么做呢?这样我们就把加上一个“负数”的“减法”运算变成了加法运算,也就弥补了之前我们原码所说的缺陷。
补码的原理我们不必深究,有一个快速简洁求补码的方法我们需要记住:
对于正数,不存在反码和补码,没有意义。因此,有些教材上说正数的反码补码形式相同是不对的,实际上,应该说正数没有反码补码更合适点。
对于负数,其补码就是反码的最后一位 [加1] 所得。
这里需要注意:最后一位若是0加1就是1,最后一位是1加1就进位变成0,看起来像取反一样,实际上进行的是加操作.
1.2 非数值信息在计算机系统中的表示
在计算机内部,非数值信息也是采用0和 1 两个符号来进行编码表示的。
①字符的编码, ASCII码是“美国信息交换标准代码”的简称,在这种编码中,每个字符用 7 个二进制位表示,即从 0000000 到 1111111 可以给出 128 种编码,可用来表示 128 个不同的字符。一个字符的 ASCII码通常占用一个字节,由七位二进制数编码组成,故 ASCII 码最多可表示 128 个不同的符号。由于 ASCII码采用七位编码,来用到字节的最高位,故在计算机中一般保持为“0” ,在数据传输时可用作奇偶校验位。
② 汉字的编码,目前,我国使用的是“国家标准信息交换用汉字编码” ,该标准码是二字节码,用2个七位二进制数编码表示一个汉字,并收人了 6763 个汉字。汉字在计算机内的表示,有多种编码,如汉字输入码,输人码进人计算机后,必须转换成汉字内码,才能进行信息处理。为了最终显示、打印汉字,再由内码转换成汉字字形码。此外,为使不同的汉字处理系统之间能够交换信息,还必须设有汉字交换码。
2. 内存地址和内存空间的简单理解
2.1 理解内存地址和内存空间
首先我们先来看这么一个代码
int a =1,b=2;
int main()
{
a++;
b++;
return 0;
{
这么一段简单的代码在计算机中如何执行呢?a和b在计算机中如何区分?要回答这个问题,必须要简单理解下计算机中的内存地址和内存空间。
实际上,如果我们反汇编一下,就可以看到a++和b++分别对应的是:
incl 0x80495f8 //把0x80495f8地址中的整数加1
incl 0x80495fc //把0x80495fc地址中的整数加1
在这里,那0x80495f8地址和0x80495fc地址就叫做a和b在内存中的地址。要了解内存地址首先必须要知道的是,内存地址就只是一个编号,一个内存地址就代表一个内存空间。那么这个空间是多大呢?我们常说,计算机中存储器的容量是以字节为基本单位的。什么叫以字节为单位,就是说一个内存地址代表一个字节(1Byte 也就是 8bit)的存储空间,这就是我们说的字节Byte是计算机的基本单位的含义。
1个内存地址 = 1个字节(Byte) = 8位(bit)
我们还知道,int型是占据4个字节的(4字节Byte=32位bit),也就是说存储一个int型必须用4个字节,也就等价于至少占据4个内存地址,所以,int在计算机中存储是占据了4个内存地址的。我们在输入语句int a =1,b=2; 后,计算机就分别为a和b分配了4个内存地址来存储a和8,这一以来,我们只需要知道a和b的内存起始地址(首地址),再加4,就是a和b实际在计算机中的地址,如下图示:
![](https://i-blog.csdnimg.cn/blog_migrate/7c3504eb0abf10c3e5116e6936a4c917.png)
再比如经常说32位的操作系统最多支持4GB的内存空间,也就是说CPU只能寻址2的32次方,即2的32次方个8bit单位,或者说最大只有2的32次方个内存地址。
2的32次方Byte = 4GB =4 294 967 296Byte
2.2 数据在内存的存储
理解了内存地址和内存空间后,我们便能知道数据在计算机中到底最终是怎么存储的。
学习编程,必须对内存的地址有一个透彻的理解。我们编程中的每一行代码,代码中用到的每个数据,都需要在内存上有其映射地址。当然,我们并不需要掌握内存是如何进行编址,那是计算机系中的另外一门课:操作系统的事了。
内存地址:计算机把所有的信息都给数字化了,所以它知道自已把一个数据,一条命令记到了内存中的哪个(些)位置。
看下面的例子,看计算机是如何在内存里记住变量a和变量b的:
变量: | (int) a = 4 | (int) b = 2 | ||||||
内存地址: | 0x80495f8 | 0x80495f9 | 0x80495fa | 0x80495fb | 0x80495fc | 0x80495fd | 0x80495fe | 0x80495ff |
内存空间: | 2001H | 2002H | 2003H | 2004H | 2005H | 2006H | 2007H | 2008H |
内存数据: | 00000000 | 00000000 | 00000000 | 00000100 | 00000000 | 00000000 | 00000000 | 00000010 |
通过以上我们可以知道,int型变量a和b都占据了4个字节也就是4个内存空间,一个内存地址对应一个内存空间也对应一个字节即8个位。
可以看到,(int) a 和 b 的确是由一串0、1组成的。更确切地,从图上可以看出它们分别都是由32位0和1组成。这32数都存放在4个内存地址里。所以,内存地址是内存当中存储数据的一个标识,并不是数据本身,通过内存地址可以找到内存当中存储的数据。