字节?比特?
在很多IO操作的底层实现中,字节是最基本的操作单位,很多IO操作,都是将数据读取为字节数组,或者将一个字节数组写成数据。
根据我们所学习的计算机知识,一个字节(byte)是八个比特位(bit),那么为什么一个字节是八个比特,而不是7个,或者说9个、16个?
或者说,我们能不能直接将数据读取为bit的形式,而不是读取为byte的形式呢?
首先我先回答一下这个问题。
答案是能!
因为计算机本身只能识别0与1组成的机器语言,所以任何的编程语言从计算机中读取到的数据,本质上都是0和1组成的bit数据,例如0100100001000101010011000100110001001111
。
而字节数组(byte[])是我们人为将bit数据按照八位为一组,划分之后得到的一组数据。
比如0100100001000101010011000100110001001111
这组bit数据按照八位为一组,划分之后便可以得到一个字节数组,这个字节数组的表现形式可以粗略地表示为[01001000,01000101,01001100,01001100,01001111]
。
那么为什么要按照八位为一组进行划分呢?
ASCII编码表
首先我们必须明确,一个bit位只能表示0和1两种状态,这对于人类而言明显是不够的。
比如说用0
来表示人类语言中是你今天早上吃饭了吗?
这句话,用1
来表示人类语言中是你今天中午吃饭了吗?
这句话,那么如果人类需要用机器语言表示你今天晚上吃饭了吗?
又该怎么办呢?
于是人类便用两个bit位,比如10
来表示你今天晚上吃饭了吗?
,甚至这个时候,两个bit位还有一个11
能够用来表示其他的人类语言,于是人类就将11
表示为吃了
。
但是这个时候又犯难了,如果没吃
用机器语言又该怎么表示呢?
所以说,一个或者两个bit位对于人类而言并没有太大的含义,所以人类需要一个对照表,能够用机器语言来表示所有的人类语言。
于是在计算机发展早期,美国国家标准学会制定了ASCII编码表,用来表示机器语言和人类语言的对照表。
只要所有人按照ASCII的标准进行编码,那么所有人都可以将人类语言写成机器语言,而且这些机器语言同样可以被其他遵守ASCII的标准的人正确读取为人类语言。
例如上述中的0100100001000101010011000100110001001111
,按照ASCII标准,可以翻译为人类语言的HELLO
。
在ASCII编码表中,规定了人类使用的128种类型(0-127)的字符与机器语言的对照。
而为了表示128种类型,即0-127的值,机器语言最少需要使用7个bit位来表示(2的7次方)。
但是ASCII编码表为了保留扩展性,保留了一个bit位作为扩展,于是ASCII编码便规定了八个bit位作为一个人类可读的有效字符。
ASCII编码理论上能够表示256种类型的字符,ASCII编码表目前规定的128种类型的字符中,第八个bit位均为0。一些欧洲国家使用的编码表便是在ASCII编码表是基础上进行扩展的,能够表示256种字符。
至于为什么不使用16个bit位进行表示呢?那是因为早期的计算机资源极其珍贵,在八个bit位能够表示所有字符(美国国家标准学会当初认为的所有字符)的情况下,使用16个bit位来表示一个字符是非常浪费的。
为什么1个字节是8个比特?
所以说,目前的计算机之所以使用使用八个比特来表示一个字节,主要就是因为当初美国国家标准学会制定了ASCII编码,其中规定了使用八个比特来表示一个字节。
后期虽然发展出了类似UTF-8之类的编码表,需要使用27个比特或者32个比特来表示一个字符,但是因为历史的原因,人类依然按照八个比特来读取一个字节,然后用多个字节来表示UTF-8支持的字符。
如果当初的美国国家标准学会能够知道互联网在未来会发展成全球性的网络环境,那么或许他们当初就会直接制定类似于UTF-8一样的编码标准了,这样或许就不是八个比特来表示一个字节,而是27个比特表示一个字节,或者32个比特表示一个字节。
或许当初真的这样制定了编码标准,现在的人就应该发问:为什么1个字节是32个比特?