《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所示。


219c2a81820f3e63bf1f4c8e8c7729cac28facb8

延伸与拓展:二进制的算术运算规则非常简单。这种简单性是计算机采用二进制的一个重要原因。如何用逻辑门电路(在当代,主要是用大规模集成在硅芯片上的晶体管逻辑门电路)来构成计算机中的二进制算术运算和逻辑运算电路这部分内容并不难懂,感兴趣的读者请参阅本书末尾列出的参考文献。
与十进制数类似,在一个二进制数中,靠左边的数字是高位数,靠右边的数字是低位数。其中最左边的位称为最高位。
我们经常用一对圆括号括住一个数值,并在圆括号外面加一个整数下标,用此下标来表示一个数值是几进制数(但是对于十进制数,常常省略圆括号和下标)。比如,(1011)16是一个十六进制数,而(1011)2是一个二进制数。
二进制数的多项式展开表示
对于一个十进制整数,比如3785,其数值可用以下的多项式展开来表示:

3785=3×103+7×102+8×101+5×100(1) 

我们把(1)式中10的几次方称为权重,权重左边的乘数称为系数。(1)式中共有4个系数,从左到右依次是“3”、“7”、“8”、“5”,权重依次分别是103、102、101、100。
可见,用这种记数法表示数值数据时,越左边的系数所对应的权重越大。权重中的基数(即底)与表示该数的进制是一样大的,在这里都是10。
类似的,任意一个二进制整数,其数值也可用多项展开式来表示。比如,二进制整数1011可表示为

(1011)2=1×23+0×22+1×21 +1×20(2)

(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个字符的一张编码解码表


452d556805ce49c5f7729632462c3d63486f7f86

有了这张编码解码表,对字符串“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章。

相关文章
|
人工智能 C语言
|
算法 C语言
【C语言程序设计——循环程序设计】求解最大公约数(头歌实践教学平台习题)【合集】
采用欧几里得算法(EuclideanAlgorithm)求解两个正整数的最大公约数。的最大公约数,然后检查最大公约数是否大于1。如果是,就返回1,表示。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。作为新的参数传递进去。这个递归过程会不断进行,直到。有除1以外的公约数;变为0,此时就找到了最大公约数。开始你的任务吧,祝你成功!是否为0,如果是,那么。就是最大公约数,直接返回。
500 18
|
Serverless C语言
【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】
根据提示在右侧编辑器Begin--End之间的区域内补充必要的代码,求解出数值x的平方根;运用迭代公式,编写一个循环程序,求解出数值x的平方根。注意:不能直接用平方根公式/函数求解本题!开始你的任务吧,祝你成功!​ 相关知识 求平方根的迭代公式 绝对值函数fabs() 循环语句 一、求平方根的迭代公式 1.原理 在C语言中,求一个数的平方根可以使用牛顿迭代法。对于方程(为要求平方根的数),设是的第n次近似值,牛顿迭代公式为。 其基本思想是从一个初始近似值开始,通过不断迭代这个公式,使得越来越接近。
488 18
|
存储 C语言
【C语言程序设计——函数】递归求斐波那契数列的前n项(头歌实践教学平台习题)【合集】
本关任务是编写递归函数求斐波那契数列的前n项。主要内容包括: 1. **递归的概念**:递归是一种函数直接或间接调用自身的编程技巧,通过“俄罗斯套娃”的方式解决问题。 2. **边界条件的确定**:边界条件是递归停止的条件,确保递归不会无限进行。例如,计算阶乘时,当n为0或1时返回1。 3. **循环控制与跳转语句**:介绍`for`、`while`循环及`break`、`continue`语句的使用方法。 编程要求是在右侧编辑器Begin--End之间补充代码,测试输入分别为3和5,预期输出为斐波那契数列的前几项。通关代码已给出,需确保正确实现递归逻辑并处理好边界条件,以避免栈溢出或结果
817 16
|
C语言
【C语言程序设计——循环程序设计】统计海军鸣放礼炮声数量(头歌实践教学平台习题)【合集】
有A、B、C三艘军舰同时开始鸣放礼炮各21响。已知A舰每隔5秒1次,B舰每隔6秒放1次,C舰每隔7秒放1次。编程计算观众总共听到几次礼炮声。根据提示,在右侧编辑器Begin--End之间的区域内补充必要的代码。开始你的任务吧,祝你成功!
378 13
|
存储 安全 C语言
【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】
分支的语句,这可能不是预期的行为,这种现象被称为“case穿透”,在某些特定情况下可以利用这一特性来简化代码,但在大多数情况下,需要谨慎使用。编写一个程序,该程序需输入个人数据,进而预测其成年后的身高。根据提示,在右侧编辑器补充代码,计算并输出最终预测的身高。分支下的语句,提示用户输入无效。常量的值必须是唯一的,且在同一个。语句的作用至关重要,如果遗漏。开始你的任务吧,祝你成功!,程序将会继续执行下一个。常量都不匹配,就会执行。来确保程序的正确性。
571 10
|
小程序 C语言
【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】
目录 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果: 任务描述 相关知识 编程编写一个程序,从键盘输入3个变量的值,例如a=5,b=6,c=7,然后将3个变量的值进行交换,使得a=6,b=7,c=5。面积=sqrt(s(s−a)(s−b)(s−c)),s=(a+b+c)/2。使用输入函数获取半径,格式指示符与数据类型一致,实验一下,不一致会如何。根据提示,在右侧编辑器补充代码,计算并输出圆的周长和面积。
436 10
|
存储 编译器 C语言
【C语言程序设计——函数】分数数列求和2(头歌实践教学平台习题)【合集】
函数首部:按照 C 语言语法,函数的定义首部表明这是一个自定义函数,函数名为fun,它接收一个整型参数n,用于指定要求阶乘的那个数,并且函数的返回值类型为float(在实际中如果阶乘结果数值较大,用float可能会有精度损失,也可以考虑使用double等更合适的数据类型,这里以float为例)。例如:// 函数体代码将放在这里函数体内部变量定义:在函数体中,首先需要定义一些变量来辅助完成阶乘的计算。比如需要定义一个变量(通常为float或double类型,这里假设用float。
713 3
|
存储 C语言
【C语言程序设计——循环程序设计】利用数列的累加和求 sinx(头歌实践教学平台习题)【合集】
项的累加和,一般会使用循环结构,在每次循环中计算出当前项的值(可能基于通项公式或者递推关系),然后累加到一个用于存储累加和的变量中。在C语言中推导数列中的某一项,通常需要依据数列给定的通项公式或者前后项之间的递推关系来实现。例如,对于一个简单的等差数列,其通项公式为。的级数,其每一项之间存在特定的递推关系(后项的分子是其前项的分子乘上。,计算sinx的值,直到最后一项的绝对值小于。为项数),就可以通过代码来计算出指定项的值。对于更复杂的数列,像题目中涉及的用于近似计算。开始你的任务吧,祝你成功!
432 6
|
存储 算法 安全
【C语言程序设计——函数】分数数列求和1(头歌实践教学平台习题)【合集】
if 语句是最基础的形式,当条件为真时执行其内部的语句块;switch 语句则适用于针对一个表达式的多个固定值进行判断,根据表达式的值与各个 case 后的常量值匹配情况,执行相应 case 分支下的语句,直到遇到 break 语句跳出 switch 结构,若没有匹配值则执行 default 分支(可选)。例如,在判断一个数是否大于 10 的场景中,条件表达式为 “num> 10”,这里的 “num” 是程序中的变量,通过比较其值与 10 的大小关系来确定条件的真假。常量的值必须是唯一的,且在同一个。
924 2