天天看点

《C语言程序设计:问题与求解方法》——1.1节二进制简介

本节书摘来自华章社区《c语言程序设计:问题与求解方法》一书中的第1章,第1.1节二进制简介,作者:何 勤,更多章节内容可以访问云栖社区“华章社区”公众号查看

1.1 二进制简介

为了从整体上把握计算机的基本工作原理,并为后面的编程学习奠定扎实的基础,读者有必要先对数字信号、二进制及其相关知识有比较清晰的、整体的了解。

1.1.1 二进制与二进制数的基本概念

二进制就是只能用数字“0”和“1”来进行计数的数字系统。二进制加法运算的重要规则是: 1+1=10 ,即两个1相加,就产生了向高位的进位,即“逢二进一”(做减法时则是“借一当二”),类似于十进制中的“逢十进一”(做减法时则是“借一当十”)。其他二进制加法规则更简单:0+0=0、0+1=1、1+0=1。二进制与十进制、十六进制的对照如表1-1所示。

《C语言程序设计:问题与求解方法》——1.1节二进制简介

延伸与拓展:二进制的算术运算规则非常简单。这种简单性是计算机采用二进制的一个重要原因。如何用逻辑门电路(在当代,主要是用大规模集成在硅芯片上的晶体管逻辑门电路)来构成计算机中的二进制算术运算和逻辑运算电路这部分内容并不难懂,感兴趣的读者请参阅本书末尾列出的参考文献。

与十进制数类似,在一个二进制数中,靠左边的数字是高位数,靠右边的数字是低位数。其中最左边的位称为最高位。

我们经常用一对圆括号括住一个数值,并在圆括号外面加一个整数下标,用此下标来表示一个数值是几进制数(但是对于十进制数,常常省略圆括号和下标)。比如,(1011)16是一个十六进制数,而(1011)2是一个二进制数。

二进制数的多项式展开表示

对于一个十进制整数,比如3785,其数值可用以下的多项式展开来表示:

我们把(1)式中10的几次方称为权重,权重左边的乘数称为系数。(1)式中共有4个系数,从左到右依次是“3”、“7”、“8”、“5”,权重依次分别是103、102、101、100。

可见,用这种记数法表示数值数据时,越左边的系数所对应的权重越大。权重中的基数(即底)与表示该数的进制是一样大的,在这里都是10。

类似的,任意一个二进制整数,其数值也可用多项展开式来表示。比如,二进制整数1011可表示为

(2)式中系数从左到右依次是“1”、“0”、“1”、“1”,而权重依次分别是23、22、21、20。

展开式中系数的最大值一定比进制数小1。比如,在十进制计数系统中,系数的最大值是9,而在二计制计数系统中,系数的最大值是1。

下面我们先来熟悉一些与书写、存储或传输一串二进制数有关的术语。

1.1.2 与二进制数相关的术语:位、位串、字节

1.位

书写、存储或传输单个的二进制数字称为位(bit)。单个“位”中的数字不是0就是1,不可能有其他数字。

任何一个只能处在两个不同稳定状态的电子元件(电容、触发器等)或者某种(比如均匀覆盖着磁性颗粒的)介质表面上的一个小点,都可以用来(间接)表示和存储一个“位”。

2.位串及其长度

多个二进制数顺序排列在一起称为位串(有些教科书将其称为“位模式”)。位串中含有的数字总个数称为位串的长度。比如,位串100110的长度是6。处于位串左边的位称为高位,位于位串右边的位是低位,位于位串最左边的位称为最高位。

3.度量位串长度的基本单位—字节

“位”这个二进制的度量单位太小,用起来很不方便。现代的大多数计算机和一些数字处理设备通常是以长度为8的位串—字节(byte)来作为度量(部件或设备的)数据存储容量大小的一种基本单位。

把长度为8的一个位串称为一个字节,长度为16的一个位串称为2个字节。长度为n的位串一共有n/8个字节。也就是说,一个位串的长度,既可以用位串中的总位数来度量,也可以用位串所具有的字节数来度量。

延伸与拓展:二进制数据存储和传输的其他一些常用单位

“字节”这个基本单位的大小是“位”这个最小二进制单位的8倍,但是在很多场合仍然还是显得太小,更大的常用单位有(在各种资料中,经常用字符b来表示字节byte,用k来表示数值1024):

千字节: 1kb=1024b=210b

兆字节: 1mb=1024kb=210kb=220b=1048576 b(约为一百万字节)

千兆字节: 1gb = 1024mb=210mb=230b=1073742814 b(约为十亿七千多万字节)

注意:相邻单位之间都是1024倍的关系,而不是1000倍的关系。

我们常常会看到一些数据存储设备在标识其数据存储容量时使用kb(千字节)、mb(兆字节)或gb(千兆字节)。

不过,在网络和通信领域,人们还是习惯用“位”作为数据传输的基本单位。所以,通常所谓的10兆宽带网,并不是每秒能够传输10mb(10485760字节)的数据,而是每秒传输10×106位(bit)。也就是说,在网络通信领域,“兆”这个名词就是精确地等于一百万(即106)。

4.位串的通常传输方式—并行或串行

一个长度为n的位串,既可以用n根并排的导线同时进行传输,每根导线传输一个位,即并行传输(这种方式的传输速度很快,但要用多根导线);也可以用一根导线,分为n个相等时间段,一位一位地依次先后进行传输,即串行传输(这种方式的传输速度较慢,但只要用一根导线)。

1.1.3 数和码的含义与区别

如果计算机只能够对一些数值进行运算—在计算机刚发明的早期年代,确实就是如此—那么它的应用范围就必然很窄。现代计算机的应用范围几乎深入人类社会生产生活的方方面面。其根本原因在于:现代计算机不仅能够对“数值”进行运算,还能够借助于各种软件和硬件,对间接表示世界上各种各样事物的“码”进行不同的处理。也就是说,同样的一个位串,既可以用来表示数值,也可以用来表示各种不同事物的“码”。

所以,我们想要真正懂得计算机并且学好编程,就不仅要熟悉二进制的“数”,还必须对一些常见的二进制的“码”有清晰的了解。

1.十进制的数和码

我们先来通过一个例子,说明十进制数字系统中数与码的区别。

如果3785用于表示数,则越高位(即越左边的位)的数字越重要(因为权重越大)。而3785用来表示非数值的码,则每一位数字都同样重要。码值仅相差一,所表示的文字(或代表的意义)就可以有巨大的区别(比如,3785可代表汉字“大”,而3786可代表汉字“小”)。

虽然十进制3785只能直接表示唯一的一个非负整数,这个数的值是三千七百八十五;但是,同样一个十进制的数字串“3785”,通过某种编码,可以表示的事物种类却是无限制的:码3785既可以表示一个汉字,也可以表示任何码值为3785的事物。

2.二进制的数和码

与十进制一样,二进制数与二进制码也有类似的区别。只不过在二进制中,只能用数字0和1组成的位串来表达任何大小的数值或者表示具有任何含义的码。

(1)一位二进制的数和码

如果用单个位来表示整数值,只能直接表示0和1这两个值中的一个。如果用单个“位”来表示码,则能够用来对任何(同属一种类型的)两种不同事物制定编码规则。比如,用0表示“假”, 用1表示“真”;用0表示状态“关”,用1表示状态“开”; 用0表示“是”,用1表示“否”;用0表示“取物品”, 用1表示“存物品”;用0表示“黑”,用1表示“白”等。

(2)两位二进制的数和码

如果用长度为2的一个位串来直接表示整数值,则只能够表示00(其值等于0)、01(其值等于1)、10、11这4个二进制非负整数值中的某一个。如果用长度为2的位串来进行编码,由于一共有00、01、10、11这4(即22)个码值可以使用,则能够用来对属于同一类型的4个不同的事、物(或状态)制定编码规则。比如,{煎,炒,蒸,煮 }、{加,减,乘,除}、{班主任,老师,家长,朋友}、{a,b,c,d}、{–2,–1,0,1}、{宿舍,教学楼,食堂,图书馆}、{向左,向右,前进,后退}等,都可用长度为2的二进制码来间接表示。

【例题1.1】编码和解码的一个实例。

通过制定一个编码规则,比如,规定用00表示“d”、01表示“c”、 10表示“b”、11表示“a”,就可以构成一张用4个码来表示4个字符的编码解码表,见表1-2。

用严格的数学术语来讲,所谓制定编码规则,就是规定了一张两个集合{00,01,10,11}与 {a,b,c,d} 之间的所有元素的一对一的映射表而已。

表1-2 4个字符的一张编码解码表

《C语言程序设计:问题与求解方法》——1.1节二进制简介

有了这张编码解码表,对字符串“cab”进行编码后,就可以用码值构成的二进制位串“011110”,在二进制的数字信号处理设备中间接地存储和传输这个字符串。

到达目的地后,接收方也要具有同样的一张“字符编码解码表”,才能将接收到的二进制位串翻译成它的本来意义。比如将二进制位串011110翻译成字符串“cab”,这个过程称为解码。

(3)长度为n的二进制的数和码

长度为n的位串可以表示的最大二进制非负整数111…1(一共n个1)究竟是多大呢? 这很简单,将由n个1构成的此二进制数加上1,可得到100…0(1的后面一共有n个0)。由这个数的多项式展开可知,它的大小就是2n。因此二进制整数111…1(一共n个1)的大小为2n–1。

因此,如果用长度为n的位串来直接表示一个非负整数,则可以表示的二进制数值从小到大依次是0、1、10、11、…、1111…11(一共n个1,其值等于2n-1),一共有2n个数,则能够用来对任意的2n个同类事物所构成的集合制定一对一的编码规则。

3.世上的绝大多数事物都可通过编码来间接表示

用一个位串只能够直接表示一个非负整数,有符号整数都不能直接用位串来表示。但是,用位串作为码可以间接表示事物的种类却是无限的,世界上的一切可数的事物都可以用码来间接表示,不可数的事物可以用码来近似表示(如何用位串来表示实数、图像和声音请参见后面的内容)。

延伸与拓展:

无效码(或称为非法码)

在可使用的码比(要进行编码的)集合中的元素多的情况下,就会存在一些无效码,这些无效码不代表集合中的任何一个元素。究竟哪些是无效码,是由具体编码规则决定的。

比如用长度为3的位串来对某个集合(中的所有元素)进行编码,可用的码值一共有8(即23)个,集合中如果只有5个元素,那么必然有3个码是无效码。

一般情况下,长度为n的位串一共有2n个码,如果用来对m个元素构成的集合进行编码,而且2n大于m,则总共有2n–m个无效码。

不定长度编码

还有一种码的长度不一样的编码方式,常常用比较短的码表示集合中经常出现的元素。比如哈夫曼编码就是一种不定长度的编码,详细内容请参见相关文献。

4.ascii码表

英文文件中出现的常用字符,不仅有26个大小写英文字符,还有10个阿拉伯数字字符,另外还有一些用作标点符号的字符(“,”,“.”,“!”等),所有这些字符加上通信过程中需要使用的符号和表示计算机输入输出设备动作的一些特殊空白字符(比如回车、换行、退格等)一共有128个。对于这些字符构成的集合,可用长度为7位的二进制进行编码,历史上曾有多种编码方案,现代最常用的是ascii编码解码表(简称ascii码表),即美国信息交换标准代码(参见附录b)。

下面将简要介绍计算机的基本工作原理,为读者学习用高级语言编程奠定坚实的理论基础。对计算机工作原理更深入一步的讲解请参见第11章。

继续阅读