3. 从二进制到十六进制

八进制的出现一样,十六进制的出现也是为了方便人类书写

十六进制的书写比八进制更常见一些,这还要从头说起

计算机硬件设备要运作,有几个问题必须解决

如何精准的找到内存中的某个数据

小说、电影、音乐、图片都要从硬盘读取到内存中才能打开,它们以1和0的形式在内存中待着,于是在某一个时间点,内存中就会出现大量纷繁复杂的数据

内存中的数据

CPU很忙,一会儿要从内存中取电影数据,一会儿要取音乐数据,一会儿要取小说数据

如何才能保证CPU能够精确的取到想要的数据,不至于取错呢?

人们想了一个非常有效的办法,就是给内存中每一个空间进行编号,就像看电影时给座位编号一样

内存编号

有了编号后,计算机就可以轻松的根据编号取到想要的数据了

这种编号,称之为内存地址,就像每家每户的门牌号一样。我们把计算机根据内存地址,取出地址中数据的过程叫做寻址

每个地址的空间占多大

有了内存地址后,新的麻烦又出现了:每个内存地址占用的内存空间应该多大呢?

如果每个内存地址仅占用一个二进制位(bit),那么每个编号的空间中只能存放1或者0

这不仅会导致编号本身的数字会变得非常非常大,而且还会导致同一个数据被分配到过多的编号中,要取很多次才能取完

比如,10000这个数字的二进制是‭10 0111 0001 0000‬,占用12个bit,就会占用12个编号,也就意味着要取出这个数字,需要CPU做出12次的取址

cpu分多次取出一个数据

你这样打算把CPU给累死!

所以这种方案肯定不行,那么多来一点行不行呢?

如果每个内存地址(编号)中不要只占用1个bit,而占用30个会怎么样呢?

自然,这样一来,编号会少很多,同时每个空间又足够大,足以支撑大数字的存储,刚才的数字10000也占不满30个bit

但是,内存地址中的空间过大,又会导致空间的浪费

为什么呢?

试想,你总不能把两个数字混淆在一个空间吧,比如,1000020000,二进制分别是‭10 0111 0001 0000‬‭0100 1110 0010 0000‬,占用的位数分别是12bit14bit

你一看,这不挺好吗?两个加起来都才只占26,把它们全部塞到一个内存地址中就可以了呀

可是你要考虑一下CPU的感受,CPU可不知道这个内存空间中有两个数字,就算它知道有两个数字,它也不知道这两个数字在哪里分割,所以,CPU会把它当作一个很大的数字读取出来

因此,每个空间最多只能保存一个有意义的数据

就是说,你数字可以很大,我分为多个空间保存,但是绝对不能出现一个空间保存多个数字

换句话说,一个空间中保存了一种数据,就不能再保存了

于是,如果空间选的太大,就会导致空间中有些bit会被浪费掉

大量的空间被浪费

综上所述,空间的划分既不能太小,又不能太大

经过谨慎的研究,最终,绝大部分计算机将一个内存地址划分为8bit,并给了它一个名称:字节 byte

这就是我们平时所说的:1byte = 8bit

如果一个数据占不满1个字节,前面就用0填充

于是,上面的数字10000,二进制12位,占用两个字节

占不满就补零

而实际上,很多计算机语言为了保证同一种数据占用的空间固定,往往会做进一步规定

比如,C、java等语言规定:别人我管不了,反正我的整数必须占用32位,即4byte

4个字节的整数

这样虽然造成了一些浪费,但好处是统一了每个整数占位的数量,这样一来,就可以很方便的告诉CPU,从某个内存地址开始,给我取出4个字节,CPU分四次取出,就得到了完整的数字了。并且,对于所有的整数都是一样的规则。

如果超过了32位的数字怎么办呢?很多语言表示:你们玩,我退了

再说十六进制

现在,我们知道了,计算机是以字节为单位来划分内存空间的

每个数据占用的内存量,一定,百分之百,是字节的整数倍

而同时,我们又知道,每4位的二进制,最多可以表示24个数字,范围是 0 ~ 241,即 0 ~ 15

那么每四位我们可以用一个十六进制的数字来表示,岂不是更加容易书写?

于是,我们在人类的十个数字基础上,加入了A、B、C、D、E、F,分别表示10、11、12、13、14、15

这样一来,就可以用一位的十六进制数来表示4个bit的数字了

比如:

0001   1
0010   2
0100   4
1000   8
1100   C = 8 + 4
1011   B = 8 + 2 + 1

进一步来想,我们一个字节,就可以用两位的十六进制表示了

某个内存地址:1101 1010   十六进制:DA
某个内存地址:1111 1101   十六进制:FD

看吧,用十六进制来表达内存中某个地址的数据,再合适不过了

所以,我们的十六进制数经常会两个两个连起来书写,以表达某个内存中某个字节的真实存储情况

比如,我们之前的32位整数:

4个字节的整数

它用16进制表示出来就是:00 00 27 10

这样是不是既准确,又简洁呢,而且可以一眼就看出它占用4个字节,不是吗?