版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第一章 C程序设计基础程序员是在要解决的问题领域与计算机的真实运行之间的一个桥梁,而构通两者的工具是使用C语言,所以要让计算机真正实现预期的目标,必须对这三个方面都有相当程度的理解和把握。本章首先从计算机的基础二进制入手,随之从软件角度说明计算机底层指令级的运行方式,接着将问题领域看成是两大要素的组合,从两个方面摸索解决问题的途径,描述算法并画流程图是可行的有效手段,本章再对C程序做初步的介绍,示例最基本的、也是最常用和最重要的C程序和语句等,然后结合以上三个方面,通过由浅入深的两个实际例子,详细分析从问题领域到程序代码的各种方法和每一个步骤,本章最后提出代码的书写风格,并对学习编程做一个总的
2、描述。1.1 二进制基础我们常用的记数方法为十进制,即逢十进一,使用0,1,9这10个数码,而二进制则是逢二进一,只使用0和1这2个数码。二进制是计算机最根本的基础,计算机系统的一切最终都可以归结到二进制,因此不管是硬件设计还是软件设计,都要对二进制有深刻的理解。1.1.1 为什么采用二进制初学计算机的人往往奇怪为什么计算机要采用二进制形式,而不是采用更常用的十进制形式,这有以下几个原因。一、成本更低从硬件角度来说,要表示一个具体的数,总是需要一定的电路器件,而一定的电路器件所能表示的数的范围也总是有限的,与十进制相比,二进制计数方法可以使用更少的器件,却能表示更大的数据范围,有两种模型可以比
3、较十进制与二进制的效率优劣。1纸张模型假设一个球队的得分范围为0到999分,使用较原始的纸张方法来表示得分情况,事先要准备30张纸,从左到右平均分成三叠,分别代表百位数、十位数和个位数,每叠纸从上到下依次写上0到9,对应十进制每位数的10个数码。现在假设要表示数字“58”,左边表示百位数的纸翻到“0”,中间的十位数翻到“5”,右边的个位数翻到“8”,合起来表示数字“058”,即“58”。由于1000=103,表示0到999这1000个数,十进制方式的总代价为3*10=30张纸。那么采用二进制计数方法代价又是多少呢?由于1024=210,所以表示0到1023这1024个数,需要10叠,每叠2张纸
4、,总代价为20张,与十进制相比,表示同样范围的数代价只有原来的2/3。在纸张模型中,可以证明三进制才是最佳方式,但与二进制相比优势不大。2算珠模型考虑使用算盘来表示数字,算盘的列数即是数的位数,算珠的颗数即是代价。使用二进制方式,每位只需1颗算珠,算珠拔上表示1,拔下表示0,10位二进制只需10颗算珠。使用十进制方式,每位需要5颗算珠,其中1颗表示5,4颗表示1,如果表示7,则拔上一颗表示5的珠子和2颗表示1的珠子,要表示0则拔开所有珠子,3位十进制总共需要15颗算珠。在算珠模型中,二进制是最佳方式。二、运算更简单由于二进制的每一位只有0和1这两种,因此2个二进制数之间的加减乘除等运算也非常简
5、单,比如相乘,它不需要“九九乘法表”。三、硬件上更容易实现开关的开与关,指示灯的亮与暗,电压的高与低,电流的通过与截止,逻辑上的真与假,存在性的有与无等等,都可以简单地和二进制中的0与1相对应。而半导体器件的最基本特性就是开关特性,所以二进制最容易实现,也很容易判断某位数为0或1,不容易误判。1.1.2 二进制、十六进制和八进制计算机内部数据都是使用二进制形式,而二进制表示数字时往往位数太长,不易书写和记忆,为了表示方便,经常使用与二进制接近的十六进制或八进制来代替二进制,另一方面,人们习惯使用的仍是十进制,所以要能熟练各进制之间的转换及简单运算。一、二进制转换到十进制借助幂级数表示形式可以计
6、算各种进制数的值,如十进制数234写成以10为基的幂级数形式是(十进制百位、十位、个位的权分别为102,101,100):(234)10210231014100上式中下标10表示十进制,二进制数也有对应的幂级数表示形式,如:(1101)2123122021120上式中下标2表示二进制,右式部分按十进制计算,得(1101)28401(13) 10表1-1 将二进制转换为十进制的简易方法二进制的权值1286432168421结果例1二进制1101累加84113例2二进制1011010累加64168290使用表1-1可以快速地将二进制转换为十进制数,将二进制各位的权值先计算好并从高到低排列,在该列下
7、写出二进制数,与权值一一对应,累加二进制数中位为1对应的权值,即得十进制结果,如二进制1101中有3个1,分别对应权值8,4和1,相加得十进制结果为13,又如:(1011010)2641682(90) 10二、十进制转换到二进制将二进制幂级数形式中的2提取出来,得(13) 10 = (1101)2123122021120 = (1)2+1)2+0)2+1其中,右式中带下划线部分就是十进制对应的二进制值,使用长除法可以计算出十进制对应的二进制值:13 2 6 余 1,余数1为二进制的最低位 6 2 3 余 0 3 2 1 余 1 1 2 0 余 1,余数1为二进制的最高位按余数部分从低到高列出,
8、即得二进制值,即(13) 10 = (1101)2对于数值不太大的十进制数,可以将其转化二进制权值的累加和,再按表1-2,将其转化为二进制,如十进制13,先将13化为8+4+1,然后按权值顺序即得上式结果,又如150=128+16+4+2=(10010110)2。这种方法只有十进制的加减运算,比较简单,也不易出错。表1-2 将十进制转换为二进制的简易方法二进制的权值128643216842113分解841二进制00001101150分解1281642二进制10010110三、二进制与八进制互换由于8=23,每3位二进制对应1位八进制,对应关系如表1-3所示。将二进制按3位1组,根据表1-3,很
9、容易转化为八进制,如:(10101)2 = ( 010 101)2 = (25)8(1001110)2 = (001 001 110)2 = (116)8反过来,八进制也很容易转化为二进制,如:(34)8 = (011 100)2 = (11100)2(507)8 = (101 000 111)2 = (101000111)2表1-3 八进制与二进制的对应关系八进制01234567二进制000001010011100101110111四、二进制与十六进制互换由于16=24,每4位二进制对应1位十六进制,对应关系如表1-4所示。将二进制按4位1组,根据表1-4,容易转化为十六进制,如:(1010
10、1)2 = ( 0001 0101)2 = (15)16(1001110)2 = (0100 1110)2 = (4E)16反过来,十六进制也很容易转化为二进制,如:(34)16 = (0011 0100)2(A5D)16 = (1010 0101 1101)2计算机一般多用8位、16位或32位二进制来表示一个整数,转化为十六进制,正好对应2位、4位及8位十六进制,所以,多数微机中使用十六进制的频率比八进制高,写二进制数时,更多的习惯是使用每4位1组方式。表1-4 十六进制与二进制对应关系十进制01234567十六进制01234567二进制000000010010001101000101011
11、00111十进制89101112131415十六进制89ABCDEF二进制10001001101010111100110111101111五、二进制加减运算二进制只有0和1两种数字,直接采用二进制运算实际上比十进制更简单,对于加法,无进位时,0+0=0,0+1=1,1+0=1,1+1=0(带进位),有进位时,0+0+进位=1,0+1+进位=0(带进位),1+0+进位=0(带进位),1+1+进位=1(带进位),如:二进制运算 十六进制运算 十进制运算(1001 0110)2 (96)16 (150)10 + (0101 1010)2 + (5A)16 + ( 90)10 (1111 0000)2
12、 (F0)16 (240)10 运算时要记住二进制是逢二进一,十六进制是逢十六进一。对于减法,无借位时,0-0=0,1-1=0,1-0=1,0-1=1(带借位),有借位时,0-0-借位=1(带借位),1-1-借位=1(带借位),1-0-借位=0,0-1-借位=0(带借位),如:二进制运算 十六进制运算 十进制运算(1001 0110)2 (96)16 (150)10 - (0101 1010)2 - (5A)16 - ( 90)10 (0011 1100)2 (3C)16 ( 60)10 六、二进制乘除运算直接使用二进制进行乘除运算同样不难,读者可以自己验证。1.1.3 原码、反码与补码计算机
13、表示一个数,绝大多数是采用8位、16位或32位二进制表示,一般情况下使用16位二进制就可以了,而如果数的范围很小,使用8位也许就够了,或者如果要表示数可能很大,那就采用32位,本书以后若不特别说明,一般都假定是采用16位表示方式。如果计算机表示的是一个非负整数,可以很简单地将该数转换为16位二进制数即可,这时,可以表示的最小数为0,最大数为216-1=65535,二进制转换为十进制只要常规地将每一位转成对应的权值再相加,这种表示法称为无符号表示法。可是如果一个数有可能为负数时,计算机是如何表示这种带符号的数呢?因为计算机是基于二进制的,只有0和1,它是无法直接识别正号“+”与负号“-”的,计算
14、机使用0表示正号“+”,而使用1表示负号“-”,用于表示正负号的二进制位称为符号位,一个数的符号位只需一位,它总是位于其他二进制位的左边,即符号位是二进数的最高位。有以下三种表示负数的方案。一、原码表示法除符号位以外,其他二进制位为数值的绝对值,这种方案称为“原码”表示法,如下所示。+20的原码为:0 000 0000 0001 0100 0表示“+”,其余15位二进制值为20-20的原码为:1 000 0000 0001 0100 1表示“-”,其余15位二进制值为-20的绝对值,即20二、反码表示法除符号位以外,负数的反码表示是在原码基础上其他二进制位取反,而正数的反码表示与原码相同。如:
15、+20的反码为:0 000 0000 0001 0100 0表示“+”,正数的反码=该数的原码-20的反码为:1 111 1111 1110 1011 1表示“-”,负数的反码=该数的原码符号位外各位取反也可以认为,负数的反码=对应正数的原码所有位取反。三、补码表示法负数的补码表示是在反码基础上加1,而正数的反码表示与原码相同。+20的补码为:0 000 0000 0001 0100 0表示“+”,正数的补码=该数的原码-20的补码为:1 111 1111 1110 1100 1表示“-”,负数的补码=该数的反码加1也可以认为,负数的补码=对应正数的原码所有位取反后再加1。四、为什么计算机一般
16、采用补码表示法原码、反码和补码是用于表示负数的三种方案,三种方案中,原码最适合于乘除类运算,补码适合于加减类运算,而反码则加减与乘除都不是最理想,由于加减运算的频率远高于乘除运算,所以多数计算机系统采用的是补码方案,这主要有以下几个原因。1惟一性表示先计算一下+0与-0的表示,如下所示:+0的编码为:0000 0000 0000 0000 (原码、反码与补码都相同)-0的原码为:1000 0000 0000 0000-0的反码为:1111 1111 1111 1111-0的补码为:0000 0000 0000 0000-0的补码等于-0的反码加1,这个加1为简单加,连符号位同时参于运算,相加时
17、最高位会产生进位,产生的进位位由于超出16位而被丢弃,其余的16位正好与+0的补码完全一样,除补码外,其他两种方案中+0的编码与-0的编码是不相同的,导致要比较两个数是否相同,不能简单地看两数的16位二进制是否完全一样,因此必然要增加硬件上额外开销,这是不必要的。2正负数混和相加加减法是计算机中最常用的一种运算,它应该尽可能简单,实际上要求加法器在进行运算时,连同符号位与其他二进制位等同运算,尽量不要特殊化。我们以(-3)+(+1)=(-2)以及(-3)+(+5)=(+2)使用最简单的二进制加来考察各种编码。首先看原码方案,应该要有(-3)的原码+(+1)的原码=(-2)的原码。1000 00
18、00 0000 0011 (-3)的原码+ 0000 0000 0000 0001 (+1)的原码1000 0000 0000 0100 (-4)的原码要求的是加法运算,而实际上通过简单二进制加得到的却是减法的结果,与预期结果不同。其次看反码方案,应该要有(-3)的反码+(+1)的反码=(-2)的反码。1111 1111 1111 1100 (-3)的反码+ 0000 0000 0000 0001 (+1)的反码1111 1111 1111 1101 (-2)的反码符合要求,再看另一式子:1111 1111 1111 1100 (-3)的反码+ 0000 0000 0000 0101 (+5)
19、的反码(1) 0000 0000 0000 0001 (+1)的反码两数通过简单二进制加时,最高位与其他位一样相加,最高位相加后产生进位,该进位超出16位二进制范围,超出部分被舍弃,其余16位二进制的结果为+1,与正确结果相差1,不符合要求。最后看补码方案,应该要有(-3)的补码+(+1)的补码=(-2)的补码。1111 1111 1111 1101 (-3)的补码+ 0000 0000 0000 0001 (+1)的补码 (式1)1111 1111 1111 1110 (-2)的补码另一式子,应该要有(-3)的补码+(+5)的补码=(+2)的补码。1111 1111 1111 1101 (-
20、3)的补码+ 0000 0000 0000 0101 (+5)的补码(1) 0000 0000 0000 0010 (+2)的补码可以看出,只有补码方案才能只使用简单加法器就得到正确答案,其他方案的加法器都需要一定的变换或补偿。3带符号与无符号的混合相加除带符号的数以外,计算机中还有大量的数是使用无符号编码方案,带符号数相加、无符号数相加以及带符号数与无符号数的相加,如果采用补码方案,一个简单加法器能满足所有要求。考察式子:65533+1=65534,将式中所有数转化为二进制,然后相加,有:1111 1111 1111 1101 65533的二进制码+ 0000 0000 0000 0001
21、1的二进制码 (式2)1111 1111 1111 1110 65534的二进制码注意65533与65534的二进制码中最高位不是符号位,而是和其他位一样,它表示权值32768。比较式1与式2,它们完全一样!同一个式子可以有两种理解,并且两种计算结果都是正确的。实际上,如果把二进制串(1111 1111 1111 1101)看成无符号数,最高位的1就表示32768,它是一个大于或等于32768的正数;而如果把它看成是带符号数,最高位为1就表示这是一个负数。同样一个二进制串,却可能有多种理解,这在计算机表示中是很常见的。还可以考察式子(-2)+(-1)=(-3)与65534 +(-1)= 655
22、33,后式是无符号数与带符号数混合相加,请读者自己验证通过简单加可以完成,并且这两个式子也是完全一样的。4加减法的统一设x为任意一个16位二进制数,记x的所有位取反的结果为y,则有x + y = 1111 1111 1111 1111由于x与y的每一位都正好相反,故简单加的结果为每一位都是1,在补码表示法中,所有位为1,正好是-1的补码,因此有x + y = -1再记x的“所有位取反后加1”的结果为z,则有z = y + 1可得z = -x即“所有位取反后加1”运算就是“取负”运算,它是可逆的。由于 a b = a + (-b),先将b“所有位取反后加1”,即得(-b),减法运算就可以转化为加
23、法运算来实现。当然,也可以单独设计一个简单减法器实现所有的减法要求,同样,也可以反过来将加法运算转化为减法运算。1.1.4 模216原则假定计算机使用16位二进制表示一个整数,由于16位二进制最多可以有216=65536个不同的组合,可以表示无符号整数0至65535,或者可以表示有符号整数-32768至32767(补码方案),可如果计算机进行运算时运算结果超出这16位范围,那么计算机将只取低16位作为结果,这样,运算结果始终只在0至65535或-32768至32767之间,它与实际数学上的运算结果可能会相差216的整数倍。设有两个整数a和b,若存在一个整数n,使得满足 a = b + 216*
24、n,那么这两数的二进制表示中低16位将完全相同,计算机因此认为a与b是同一个数。也可以这么说,如果a与b对216求余数(模)所得结果相同,那么计算机就认为这两数是同一个数,计算机的这个特征称为取模原则或模216原则,即任何一个数加上或减去65536所得结果相同。举例说,设有无符号数运算65534 + 3 = 65537,用二进制运算表示为:1111 1111 1111 1110+ 0000 0000 0000 0011 1 0000 0000 0000 0001 (低16位与1的编码相同)由于计算机只保留16位二进制结果,所以计算机会认为结果为1,即65534+3=1,这个结果与实际正好相差6
25、5536,有65534 + 3 = 65537 65537 65536 = 1模216原则对负数同样适用,如1-3 = -2 -2 + 65536 = 65534,即-2就是65534,它们的16位二进制表示完全一样,都是1111 1111 1111 1110,它既是65534转换为二进制的结果,又正好是-2的补码表示结果。一个负数的编码会与一个无符号数的编码完全一样,这提醒我们,负数的编码除常规的“所有位取反后加1”外,还可以先将该负数加上65536,使之变为正数,然后按十进制转二进制方法求得该数编码,根据模216原则,该编码同时也为所求负数的编码。1.1.5 浮点小数的二进制表示一、二进制
26、与十进制小数互换1二进制转十进制按二进制幂级数展开,如:2十进制转二进制整数部分按除2方式(见第一章)转换,小数部分按乘2方式转换,如:0.68752 = 1.375,小数部分为0.375,整数部分为1 0.3752 = 0.75, 小数部分为0.75, 整数部分为0 0.752 = 1.5, 小数部分为0.5, 整数部分为1 0.52 = 1.0, 小数部分为0, 整数部分为1则,每次乘法的整数部分依序为1011,故0.6875=(0.1011)2,再如0.1:0.12 = 0.2, 小数部分为0.2, 整数部分为00.22 = 0.4, 小数部分为0.4, 整数部分为00.42 = 0.8
27、, 小数部分为0.8, 整数部分为00.82 = 1.6, 小数部分为0.6, 整数部分为10.62 = 1.2, 小数部分为0.2, 整数部分为10.22 = 0.4, 小数部分为0.4, 整数部分为00.42 = 0.8, 小数部分为0.8, 整数部分为0由于小数部分始终不能为0,这是无限循环小数,即0.1=(0.00011001100)2,正如对十进制来说,1/7=0.142857是无限循环小数,对二进制来说,1/10=0.1转换为二进制同样也是无限循环小数,即用有限位数的二进制是无法精确表示十进制的0.1,这意味着简单地使用二进制处理小数时,多数情况下会存在误差。二、浮点数的二进制结构
28、简介由于小数点本身不能直接转化为二进制,在小数表示时,小数点的位置是隐含的,以32位二进制表示为例,如果小数点的位置是固定的,即整数部分和小数部分的位数是固定的,称为定点小数,定点方式的优点是处理简单,缺点是表示数字的范围太小,偏大或偏小的数都无法表示。浮点数表示方法允许小数点的位置漂移,它需要额外的二进制位以表示小数点的位置,这部分二进制位称为指数部分,而用于表示有效数字的二进制位称为尾数部分,尾数部分越多,则数的精度越高,有效位数越多;指数部分越多,则所能表示数的范围就越大。以一般32位浮点数据类型为例,其中,数字的符号位占1位(称为数符),指数部分占8位(称为阶码),尾数部分占23位,共
29、32位。例如,要表示实数200.1,首先转化为二进制11001000.0001100110011001,转换为二进制形式的科学计数法,小数部分取23位,其余部分四舍五入,则有:(200.1)10 = (1.100 1000 0001 1001 1001 1010)27由于二进制的整数部分必定是1,尾数取小数点后的部分,则尾数为:100 1000 0001 1001 1001 1010指数部分占8位,用于表示幂,采用公式“127+幂”(注意不是补码方案),本例中,指数部分的值为127+7=134,将134转化为二进制,则指数为:10000110,本例中数值为正数,符号位取0,则+200.1的32
30、位浮点数表示为:0100 0011 0100 1000 0001 1001 1001 1010与整数形式不同的是,浮点数的负数表示不采用类似补码的形式,如-200.1的表示仅仅是将200.1表示中最高位置为1,即-200.1的32位浮点数表示为:1100 0011 0100 1000 0001 1001 1001 1010将32位浮点数转换为十进制数,绝对值部分采用以下公式:(1 + 尾数)2(阶码-127)数的正负由数符决定,0表示正,1表示负。1.2 程序员眼中的计算机1.2.1 数据在计算机中的存储形式一、位、字节、字与地址的概念在计算机主机内的存储器,称为内存诸器,简称内存,计算机运行
31、时的程序和数据都存放在内存中。二进制数据的最基本单位为一个“位”,但一位二进制所能表示的信息量太少,为了有效地组织各种信息,计算机访问内存时是以“字节”为最小单位,一般计算机每个字节为8位二进制,计算机内存就是由很多排列整齐的字节组成,为了访问方便,每个字节都分配一个编号,称为“地址”,在多数计算机中,地址是从低到高连续编址的,最小从0开始,最大到实际内存结束。在表示比较大的整数或实数时,一个字节是不够的,可能需要2个、4个或更多字节来表示一个数,与字节情况不同,一个“字”到底有多少个字节组成是取决于计算机系统,比如在PC微机中,我们说Windows是32位操作系统,是指在Windows环境下
32、,一条典型的计算机指令能处理32位二进制运算,这时32位二进制为一个字,即一个字包含4个字节。而在同样的PC微机中,我们说DOS是16位操作系统,是由于在DOS环境下,处理器处于一种特殊模式(实模式),这时一条典型的指令只处理16位二进制运算,则一个字为16位二进制,它包含2个字节。为了避免字长的这种不确定性,也统一称32位二进制为一个“长字”,而称16位二进制为一个“短字”。不管一个字含多少个字节,这些字节的地址必须是连续的,其中最小的地址称为“首地址”,也称该首地址为字的“地址”。操作系统在对内存进行管理时,可能会说“从内存32K开始的4K空间分配给某某程序使用”,而程序设计时也可能会说“
33、将100地址后第n个字节的数据读出来”,这时就需要对地址本身进行运算,由于32位系统的常规运算是32位,所以地址多半也是32位,则最大内存空量为232=4G字节,而16位系统的地址运算是16位,寻址空间就只有216=64K字节,当然,64K可能太小了,但对简单的程序来说也足够了,通过特殊的影射指令,16位系统可以访问内存中的任一个64K片段,某种意义上也可以说它能访问所有内存,只不过麻烦些罢了。二、程序设计中的变量概念从程序设计的角度看,所有要被处理的数据都是一个个量,称为“变量”,变量存储在内存的一块连续区间中,它可能是一个字节,可能是一个短字,也可能是一个长字或者更多字节,变量自然也相应地
34、会有一个“首地址”,称为变量的“地址”,为了程序描述方便,变量可以被赋予名字。由于内存是计算机的重要资源,内存的主要安排由操作系统严格控制,一般情况下,程序员是没有资格安排变量在内存中的位置,一般是先由程序员明确他所需要的变量个数以及每个变量的位长,然后由操作系统或编译器给每个变量安排地址,地址安排后,一般不会随意变动位置,当变量的使命完成后,所占的内存空间仍由操作系统或编译器回收,以备下次申请使用时重新分配。每个变量的值在一定时间内是明确和固定不变的,通过计算机指令可以修改各个变量的值,这一过程称为对变量“赋值”。要注意程序设计中的变量概念与数学上的变量概念有很大的不同。数学上的出现于方程中
35、的变量,是还未求解量的代名词,而出现在函数中的变量,如y=f(x),变量x与y之间具有连动关系,变量y自动随着x的变化而变化。程序设计上的变量是指可以通过赋值进行变化的量,每个变量都是独立的,变量本身之间不具有连动关系。数学上的变量是抽象的,而程序设计上的变量是非常具体的,每次赋值后都要明确该量的新值是多少。比如,式子“x=x+1”在数学上是不成立的,但在程序设计中是有一定的含义,运算符“=”称为赋值运算符,整个表示将变量x原来的值取出,加上1,结果再赋值给变量x,也就是说,变量x的值增加了1,该式子是要求计算机完成一定的计算与内存值变化工作,与数学上的式子没有任何关系。三、16位系统的内存结
36、构示例图1-1是一个16位系统的内存结构图,内存以字节为基本单位自上向下排列,最上端为地址0,最下端为最高地址(FFFF)16,内存总容量为64K字节,程序中定义一个变量,变量名为x,变量的位长是16位,假设编译器将该变量安排在(2000)16和(2001)16地址,则(2000)16为变量x的首地址,再假设(2000)16地址中的二进制值为(2A)16,(2001)16地址中的二进制值为(F0)16,Intel公司的CPU将一个字的低8位存在低地址,而高8位的数存在高地址中,因此,变量x的二进制数值为(F02A)16,如果x是一个无符号数,则x为61482,而如果x是一个带符号数,那么x的值
37、为-4054。图1-1 内存结构示例(16位系统)1.2.2 计算机的运行方式与特点一、计算机结构图1-2 计算机运行的三大支柱计算机内的结构框图如图1-2所示,主要由三部分构成:处理器(CPU)、内存(RAM)和设备(I/O),其中,所有与外部硬件的交互都在设备I/O子系统完成,如磁盘、网络以及串并口通信等,内存中储存操作系统与程序的指令以及指令运行时相关的各种数据,而处理器是心脏,所有指令由“指令系统”解释并交由“运算器”执行相关计算,计算所需的数据来自内存,计算完成后结果返回给内存,“寄存器组”用于设置工作模式、指示工作状态、缓存常用数据,或储存临时数据等。二、计算机指令的执行内存、处理
38、器和外设是计算机运行的三大支柱,计算机一般将指令码序列以及相关数据事先安排在内存中,程序运行时,依序从内存中将指令码调入到处理器中执行,处理器按照指令要求从内存中取出所需的数据并进行计算,然后将结果返回到内存中去,再接着调入下一条指令直至程序结束,指令还可以从外部设备(键盘等)上输入数据,或者将生成的数据输出到设备(显示屏等)上。具体地,计算机执行一条指令,一般有以下过程。 由指令系统从内存中取得下一条要执行的指令。 指令系统解释要执行的指令。 从内存、寄存器或外设中取出指令所需的数据。 运算器对取出的数据进行运算。 运算结果返送到内存、寄存器或外设中。 计算下一条要执行指令的地址。假设有以下
39、指令序列:指令1:置变量s的值为0。指令2:置变量i的值为0。指令3:变量i的值递增1。指令4:将变量i的值累加到变量s上。指令5:将变量i的值与5做比较。指令6:如果比较结果为“小于”,则转到“指令3”继续执行。指令7:调用系统功能,在屏幕上显示s的值。计算机按指令序列依次执行,指令1与2是直接初始化内存变量的值,指令3与4则是做基本运算后修改变量的值,指令5与6是对变量值的大小进行判断,如果还未到5就转到指令3与4继续运算,否则执行下一指令7,最后一条指令通过操作系统或编译器提供的功能在屏幕上显示运算的结果,一般显示屏、键盘、磁盘文件以及打印机等常见的硬件相关设备,系统或编译器会提供一些与
40、设备无关的通用底层模块,需要时可直接调用。三、计算机指令的特点 指令是计算机执行的最基本单位。 每条指令中的数据个数和运算类型是有限和确定的。 指令的含义是明确和无歧义的。 除非遇到转移类指令否则指令按顺序依次执行。 计算机本质上是一个机器,它严格按照预定的指令行事。 计算机本身并没有智能能力。1.3 程序设计的方法1.3.1 程序设计的两大要素一、两大要素指令的最基本描述形式是“对哪些数据做什么运算”,所以数据和运算是指令的基本要素。广义上说,各种数学意义上的数(如整数与实数)、各种编码(如字符编码与指令码)、批量数据(如数列)、信息化对象(如班级与窗口)等等,都算数据,属于名词范畴,统称为
41、“对象”;而各种数学运算(如四则运算)、数学函数(如三角函数)、处理过程(如成绩排序)、对象上的动作(如窗口的最大化与关闭)等等,都算运算,属于动词范畴,统称为“过程”。任何对于问题本身以及解决问题过程的描述都离不开名词和动词,所以对象与过程是程序设计中的两大要素,在着手解决一个问题之前,对问题本身要进行一定的分析,首先就是要明确问题领域中的关键对象与过程,围绕每一种对象类型,都要清楚它是如何定义、在计算机中怎么表示、有哪些相关运算、如何输入与输出等等,而对每一个过程,要知道过程中的每一个主要步骤。只有这些都搞明白了,再经过有机的组织,才可以解决问题。二、问题分析示例1分析问题:“从键盘上输入
42、整数n,计算1+2+n的值并显示到屏幕上”。键盘与屏幕的处理由系统或编译器提供,程序本身并不直接与它们打交道,除此之外,惟一的数据类型就是“整数”,题目并没有对n的范围进行限定,所以n选择16位或32位二进制都是可以的,从题中还可以隐含地看出n应该是非负整数,不管n选择无符号数或带符号数都不算离题,题目要求为计算累加和,可以使用一个变量来表示这个累加和,按变量含义可以起名为“sum”,该变量的类型可以设定与n相同。不管变量的类型选择哪一种,它总是有范围限定的,比如,若n与sum的类型为16位带符号整数,则n的有效范围为0至255之间,超出这个范围,运算结果就不正确了,这是计算机与数学的不同。题
43、中明确的动词为“输入”与“输出”,即从键盘上输入整数,以及在显示屏上显示整数的值,各种语言都有自己相应的输入出语句,可以查书找到简单的示例。计算式子中还有“+”运算,但计算机指令本身提供的“+”运算为最基本的2数相加,要完成“1到n的累加和”这个过程需要有一个“算法”,即要找到一个步骤序列,使得通过有限的、确定长度的指令流实现不定长度的“+”运算以达到求累加和功能,由于加运算的次数是随着n的变化而不同,但实现累加的指令数必须是固定的,所以有些指令就有可能被重复执行多次,称为“循环”,可以采用一些表示循环的描述,如“一直执行某个指令流片断直到某某条件成立或不成立”,或者“只要某某条件成立就重复执
44、行某某片断直到该条件不成立为止”,或者“总共重复x次,从第1次到第x次,每次执行某片断”,本书1.2.2节的指令示例即是一个1到5累加的算法。在弄懂基本数据与基本运算后,通过算法将复杂过程细化,再了解程序设计计语言的基本程序结构以及基本数据与运算的书写格式等,就可以编写程序代码了,最后再上机进行验证与执行。要注意的是:编写程序时,至少在初期阶段,应尽量避免通过数学方法做太多的优化。比如本例中,应避免把求累加和优化为计算表达式“n*(n+1)/2”,那样就失去算法求解的味道,同时,要知道现实中总有太多的计算过程是无法使用数学方法进行最大限度的优化,即使要优化,也许用于优化与证明的时间要远远超过编
45、写和执行程序的时间,反而得不偿失。三、问题分析示例2分析问题:先输入整数n,再输入n个学生的信息,学生信息包括学号、姓名和成绩,根据学生成绩先计算平均分、最高分和最低分,再以10分为单位计算各分数段的比例,最后分别以学号和成绩顺序输出2个表。基本的类型有整数n、学号、姓名和成绩,其中,整数n的表示与上例相同,学号可以是一个从1开始的顺序编号,也可以是8位数字编号,还可能是8位带其他符号的编码,第一种使用短字即可表示,第二种使用长字,第三种需要使用8个字节的空间,每个字节表示一个字符,姓名是字符串,可以假定最长不超过30个字符,成绩是一个0至100之间的整数或实数,可使用短字或32位二进制浮点数
46、表示方法。除了这些基本类型外,还有学生这个抽象的信息,以及n个学生的批量信息。动作部分包括:输入、计算平均分、计算最高最低分、计算分数段比例、排序,其中排序隐含有比较大小等运算,学号和成绩的排序步骤是一样的,只是学号和成绩的类型不一样,所以在具体细节上有些差别。首先要能够表示各种基本类型以及抽象的和批量等信息,它们相应的基本使用方法以及输入输出等基本过程,再对计算平均分、排序等的算法了解后,两者相结合,那么写出总的程序是完全可能的。四、问题分析示例3分析问题:有个Windows对话框,对话框上有1个下拉选择框、3个按钮和1个文本框,在文本框上可以直接输入数字,通过下拉框可以选择文本的颜色,点击
47、按钮1时,文本框上的数字增加1,点击按钮2时文本框数字减少1,点击按钮3时程序结束。本例有4种对象:对话框、文本框、下拉框和按钮,对话框可以显示和关闭,文本框能显示和输入数字,还能选择文本颜色以及对数字进行递增或递减变化,下拉框能显示可供选择的颜色,下拉框与按钮都可以单击。所有这4种对象都是Windows上的可显示对象,它们有共同的一些特征,如位置、背景颜色、显示或隐藏等共同特性,围绕这些特性,可以创建一种更基本的对象,称为“窗口”,其他对象是该对象的“派生”。同时在这4种对象中,对话框包容其他3种对象,称其他对象“从属于”对话框对象。除开对象的构造以外,本示例的功能部分很简单,仅仅是某些对象
48、在特定事件发生时简单操作一下其他对象就可以了。五、面向过程与面向对象以上示例中,数据或对象的作用越来越重要,而过程或算法的重要性逐步下降。当程序还不是太复杂时,数据类型相对还比较简单,而找到一个解决问题的算法才是关键,这种以过程为主看法就称为面向过程,如示例1和示例2所示。随着对象的逐步抽象,对象的数据组织、对象之间的从属和派生关系、对象相关的动作(如运算与显示)与事件(如鼠标点击)等越来越复杂,这些对象相关的内容统称为对象的“构造”,而除开对象以外的部分可能相对简单,这种强调对象作用的看法称为面向对象,如示例3所示。我们称PASCAL和C等语言为面向过程的程序设计语言,是由于它们提供一些方法
49、,容易将算法翻译成代码,而我们称C+与JAVA等语言为面向对象的程序设计语言,是由于它们额外提供一些手段,使得对对象的构造容易实现。其实,过程与对象这两大要素是并重的,不能只强调其中一个而完全忽视另一个,在分析问题时,不管是面向过程或是面向对象,实际编程时采用任一种语言工具都是可以实现,差别仅仅是工具是否顺手而已。1.3.2 算法的描述一、流程图描述算法的最简单方法是使用流程图,流程图由各种框和线组成,如图1-3所示,最基本的有起止框、处理框、判断框和流程线等。图1-3 流程图的基本组成流程图方式简单明了,计算机运行时总是从“开始”框开始,按流程线顺序依次执行,最后到“结束”框完成整个程序。计
50、算1至n累加和的流程图如图1-4a所示,在“开始”框后,框1输入变量n的值,框2与3对变量的值进行初始化,框4与5累加计算,框6为循环判断,如果还未加到n则转到框4继续累加,否则输出结果,然后“结束”。流程图中,“开始”框只有一个出口流程线,“结束”框只有一个入口线,处理框有一个入口和一个出口线,判断分支框有一个入口和多个带条件的出口线。二、算法的文字描述使用文字方式描述算法中每一个步骤,以取代流程图中的处理框与条件框,通过步骤序号或次序以取代一般流程线,并消去起止框。图1-4a对应的文字描述如下所示。1 输入整数n2 置变量s为03 置变量i为04 变量i递增15 将变量i的值加到s中6 如
51、果i n则转到步骤47 输出s的值显然,文字描述方式比流程图方式简短,它不需要“画图”,但是流程方向不如流程图清晰。图1-4 流程图示例(计算1至n累加和)三、结构化描述在流程图中,太过随意的流程线描绘将增加流程图理解的难度,同样地,在文字描述中,反复出现的“转到步骤”使得每一步的功能不易把握,因此有必要进行适当的限制,使之规范化。上例文字描述中,步骤4到6实际上组成一个“循环”功能,可以设法以子步骤形式将其合并成一个步骤,并消去“转到步骤”描述,同时将步骤编号也消去,结果如下。 输入整数n。 置变量s为0。 置变量i为0。 重复以下直到i n不成立。 变量i递增1。 将变量i的值加到s中。
52、输出s的值。这就是结构化描述形式,步骤之间具有层次关系,同层次各步骤之间总是从上向下依次执行,流程线都是隐含的。如图1-5所示,结构化共有3种结构、6种基本形式。 顺序结构,这是最基本的结构,即指令按先后顺序依次执行。 选择结构(if形式),如果某条件成立时才执行特定指令。 选择结构(if-else形式),条件成立与否做不同指令。 循环结构(do形式),先执行再判断条件,若成立继续执行。 循环结构(while形式),先判断条件再执行。 循环结构(for形式),允许灵活设定循环的起止及步长等。图1-5 结构化的6种基本形式结构化描述具有以下特点: 每种形式都只有一个入口和一个出口。 消除“转到步骤”描述。 每一个执行部分可以是任意6种形式之一,能够互相嵌套。 每种形式在高级语言中都有相应的“语句”。 便于形成功能块、便于功能分析。以for形式重新描述1至n的累加和,我们将变量s看成是一个累加器,初始时其值为0,然后变量i从1到n循环n次,每次将i的值累加到s中,得算法如下: 输入n。 置s为0。 变量i从1到n循环以下,i每次递增1。 将变量i的值加到s中。 输出s。相应的流程图如图1-4b所示。1.3.3 流程的跟踪执行写好流程图后,为了验证流程图的正确性,需要仿照计算机的方式执行流程图,以图1-4b为例,对照问题要求,执行时如果输入4,则应计算1+2+3+4,结果
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 永州师范高等专科学校《录音艺术与声音剪辑》2024-2025学年第二学期期末试卷
- 流动宴席内部管理制度
- 海尔内部奖罚制度
- 海边景区内部管理制度
- 煤矿内部用电管理制度
- 煤矿运输区内部管理制度
- 环保纠纷内部处置制度
- 甲方人员内部管理制度
- 监理内部考核投诉制度
- 科室内部审计制度
- 2024年江西省公务员考试行测真题附答案详解(完整版)
- 统编版高中政治选择性必修2《法律与生活》期末复习必背知识点考点提纲
- 安徽春招历年试题和答案
- 音乐起源课件
- GB/T 45924-2025薄型中空玻璃
- 青岛路灯保护管理办法
- 生命科学与健康
- 中医护理技术的应用与创新
- Unit5OldtoysPartBLet'stalkLet'slearn说课(课件)-人教PEP版级下册
- 水利工程公司管理制度
- 船舶制造行业2025年订单需求与船舶智能航行系统研发报告
评论
0/150
提交评论