二级c语言课本.pdf
《二级c语言课本.pdf》由会员分享,可在线阅读,更多相关《二级c语言课本.pdf(175页珍藏版)》请在冰点文库上搜索。
第一章程序设计基本概念1.1程序和程序设计1.1.1C程序当今,计算机已广泛应用于社会生活的各个领域,成为大众化的现代工具。
但是,不熟悉计算机的人仍然把它想象得十分神秘。
其实,计算机不过是一种具有内部存储能力、由程序自动控制的电子设备。
人们将需要计算机做的工作写成一定形式的指令,并把它们存储在计算机的内部存储器中,当人们给出命令之后,它就按指令操作顺序就自动进行。
人们把这种可以连续执行的一条条指令的集合称为“程序”。
可以说,程序就是人与机器进行“对话”的语言,也就是我们常说的“程序设计语言”。
目前,在社会上使用的程序设计语言有上百种,它们都被称为计算机的“高级语言”,如BASIC、PASCAL以及本书将介绍的C语言等。
这些语言都是用接近人们习惯的自然语言和数学语言做为语言的表达形式,人们学习和操作起来感到卜分方便。
但是,对于计算机本身来说,它并不能直接识别由高级语言编写的程序,它只能接受和处理由0和1的代码构成的二进制指令或数据。
由于这种形式的指令是面向机器的,因此也称为“机器语言”。
我们把由高级语言编写的程序称为“源程序”,把由二进制代码表示的程序称为“目标程序”。
如何把源程序转换成机器能够接受的目标程序,软件工作者编制了一系列软件,通过这些软件可以把用户按规定语法写出的语句一一翻译成二进制的机器指令。
这种具有翻译功能的软件称为“编译程序”。
卷一种高级语言都有与它对应的编译程序。
例如,c语言编译程序就是这样的种软件,C语言编译程序的功能如图1.1所示。
图1.1我们所写的每条C语句,经过编译(Compile)最终都将转换成二进制的机器指令。
由C语言构成的指令序列称C源程序,按C语言的语法编写C程序的过程,称C语言的代码编写。
C语言源程序经过C语言编译程序编译之后生成一个后缀为.OBJ的二进制文件(称为目标文件夹)。
最后还要由称为“连接程序”(Link)的软件,把此.OBJ文件与C语言提供的各种库函数连接起来生成一个后缀为.EXE的可执行文件。
在DOS状态下,只须打入此文件的名字(而不必打入后缀.EXE),该执行文件就可运行。
1.1.2程序设计简单的程序设计一般包括以下几个部分。
1.确定数据结构。
根据任务书提出要求、指定的输入数据和输出的结果,确定存放数据的数据结构。
2.确定算法。
针对存放数据的数据结构来确定解决问题、完成任务的一步一步的步骤。
有关算法的概念将在下一节中介绍。
3.编码。
根据确定的数据结构和算法,使用选定的计算机语言编写程序代码,输入到计算机并保存在磁盘上,简称编程。
4.在计算机上调试程序。
消除由于疏忽而引起的语法错误或逻辑错误;用各种可能的输入数据对程序进行测试,使之对各种合理的数据都能得到正确的结果,对不合理的数据能进行适当的处理。
5.整理并写出文档资料。
1.2算法学习计算机程序设计语言的目的,是要用语言作为工具,设计出可供计算机运行的程序。
在拿到一个需要求解的问题之后,怎样才能编写出程序呢?
除了选定合理的数据结构外,一般来说,十分关键的步是设计算法,有了一个好的算法,就可以用任何一种计算机高级语言把算法转换为程序(编写程序)。
算法是指为解决某个特定问题而采取的确定且有限的步骤。
个算法应当具有以卜五个特性:
I.有穷性。
一个算法应包含有限个操作步骤。
也就是说,在执行若干个操作步骤之后,算法将结束,而且每一步都在合理的时间内完成。
2.确定性。
算法中每一条指令必须有确切的含义,不能有二义性,对于相同的输入必能得出相同的执行结果。
3.可行性。
算法中指定的操作,都可以通过己经实现的基木运算执行有限次后实现。
4.有零个或多个输入。
在计算机上实现的算法,是用来处理数据对象的,在大多数情况下这些数据对象需要通过输入来得到。
5.有个或多个输出。
算法的目的是为了求“解”,这些“解”只有通过输出才能得到。
算法可以用各种描述方法来进行描述,最常用的是伪代码和流程图。
伪代码是种近似高级语言但又不受语法约束的种语言描述方式,这在英语国家中使用起来更方便。
流程图也是描述算法的很好的工具,传统的流程图由图1.2中所示的几中基本框组成。
开始或终止处理框输入输出框判断框流程线连接点图1.2由这些框和流程线组成的流程图来表示算法,形象直观,简单方便,但是这种流程图对于流程线的走向没有任何限制,可以任意转向,在描述复杂的算法时所占篇幅较多,费时费力且不易阅读。
随着结构化程序设计方法的出现,1973年美国学者LNassi和B.Shneiderman提出了一种新的流程图形式。
这种流程图完全去掉了流程线,算法的每一步都用一个矩形框来描述,把一个个矩形框按执行的次序连接起来就是一个完整的算法描述。
这种流程图用两位学者名字的第一个英文字母命名,称为N-S流程图。
我们将在下一节中结合结构化程序设计中的一种基本结构来介绍这种流程图的基本结构。
本书中的例题,由于比较简单,因此大都采用文字来进行描述,但要求读者读懂这两种流程图。
1.3结构化程序设计和模块化结构1.3.1结构化程序结构化程序由三种基本结构组成。
1.顺序结构。
在本书第三章中将要介绍的如赋值语句,输入、输出语句都可构成顺序结构。
当执行由这些语句构成的程序时,将按这些语句在程序中的先后顺序逐条执行,没有分支,没有转移。
顺序结构可用图1.3所示的流程图表示,(a)是一般的流程图,(b)是N-S流程图。
(a)(b)图1.32.选择结构。
在本书第四章中将要介绍的if语句、switch语句都可构成选择结构。
当执行到这些语句时,将根据不同的条件去选择执行不同分支中的语句。
选择结构可用图1.4所示的流程图表示,(a)是一般的流程图,(b)是N-S流程图。
图1.43.循环结构。
在本书第五章中将介绍不同形式的循环结构。
它们将根据各自的条件,使同组语句重复执行多次或次也不执行。
循环结构的流程图如图L5和图1.6所示,其中(a)是一般流程图,(b)是N-S流程图。
图1.5是当型循环。
当型循环的特点是:
当指定的条是:
执行循环体直到指定的条件满足(成立),就不再执行循环。
件满足(成立)时,就执行循环体,否则就不执行。
图1.6是直到型循环,该循环的特点(b)图1.5当型循环已经证明,由三种基本结构组成的算法结构可以解决任何复杂的问题。
由三种基本结构成的算法称为结构化算法;由三种基本结构所构成的程序称为结构化程序。
(a)(b)图1.6直到型循环例1先后输入若干个整数,要求打印出其中最大的数,当输入的数小于0时结束。
用N-S流程图表示算法。
解题思路是:
先输入一个数,在没有其它数参加比较之前,它显然是当前最大的数,把它放到变量max中。
让max始终存放当前已比较过的数中的最大值。
然后输入第二个数,并与max比较。
如果第二个数大于max,则将第二个数取代max中原来的值。
如此先后输入和比较,每次比较后都将大者放在max中,当输入的数小于0时结束。
最后max中的值就是输入的数中的最大者。
根据此思路,画图N-S流程图(见图1.7)。
变量x用来控制循环次数,当x0时,执行循环体;在循环体内进行两个数比较和输入x值。
从图1.7可见,在循环体的矩形框内包含一个选择结构。
1.3.2模块化结构当计算机在处理较大的复杂任务时,所编写的应用程序经常由上万条语句所组成,需要由许多人共同完成。
这时常常把这个复杂的任务分解成若干下子任务,每个子任务又分成很多小子任务,每个小子任务只完成一项简单的功能。
在程序设计时.,用一个个小模块来实现这些功能。
程序设计人员分别完成一个或多个小模块。
我们称这样的程序设计方法为“模块化”的方法,由一个个功能模块构成的程序结构为模块化结构。
由于已把一个大程序分解成若干相对独立的子程序,每个子程序的代码一般不超过一页纸,因此对程序设计人员来说,编写程序代码J变得不再困难。
这时只须对程序之间的数据传递作出统一规范,同一软件可由一组人员同时进行编写,分别时行调试,这就大大提高了程序编制的效率。
软件编制人员在进行程序设计的时候,首先应当集中考虑主程序中的算法,写出主程序后再动手逐步子程序的调用。
对于这些“子”程序也可用调试主程序的同样方法逐步完成其下一层子程序的调用。
这就是自顶向下、逐步细化、模块化的程序设计。
c语言是一种结构化程序设计语言。
它直接提供了三种基本结构的语句;提供了定义“函数”的功能,在C语言中没有子程序的概念,它提供的函数可以完成子程序的所有功能;C语言允许对函数单独进行编译,从而可以实现模块化;另外还提供了丰富的数据类型。
这些都为结构化程序设计提供了有力的工具。
习题1.1在TURBOC环境中用RUN命令运行一个C程序时,所运行的程序的后缀是。
1.2C语言源程序文件名的后缀是,经过编译后,生成的后缀是,经过连接后,生成文件的后缀是。
1.3结构化程序由____、______三种基本结构组成。
第二章C程序设计的初步知识C语言语法简洁,紧凑;使用方便,灵活;具有丰富的运算符和数据结构:
并且能够通过函数实现程序的模块化。
它既具有高级语言的一切功能,也具有低级语言的一些功能。
因此它既可以用来编写系统软件,也可以用来编写应用软件。
它是当前国际上广泛流行的一种计算机高级语言。
2.1简单C语言程序的结构和格式本节将通过一个简单的程序例子,介绍C程序的一些基本构成和格式,使读者对C语言程序有一个初步了解。
例2.1输入矩形的两条边长,求矩形的面积。
程序如下:
#includestdio.hmain()floata,b,area;a=1.2;/*给矩形的两条边赋值*/b=3.6;area=a*b;/*f求出矩形的面积放入变量area*/printf(a=%f,b=%f,area=%fn”,a,b,area);/*输出短形的两条边长和面积*/)以上程序的运行结果如下:
a=1.200000,b=3.600000,area=4.320000以上程序中,main是主函数名,C语言规定必须用main作为主函数名。
其后的一对圆括号中间可以是空的,但这一对圆括号不能省略。
程序中的第2行:
main()是主函数的起始行。
一个C程序可以包含任意多个不同名的函数,但必须有一个而且只能有一个主函数。
一个C程序总是从主函数开始执行。
在函数的起始行后面是函数体。
函数体用左花括号“”开始,用右花括号“”结束。
其间可以有定义(说明)部分和执行语句部分。
以上程序中的第4行就是程序的定义部分;第5行到第8行是程序的执行部分,执行部分语句称为可执行语句,必须放在说明部分之后,语句的数量不限,程序中由这些语句向计算机系统发出操作指令。
定义语句用分号结束,在以上程序中只有一个定义语句,对程序中所用到的每一个变量a、b、area进行定义并且说明它们为float类型。
程序的第5、6行用两条语句分别给两条国赋值,第7行计算出矩形面积并赋给变量area,第8行按设计的格式把a、b、area的值输出到终端屏幕。
C程序中的每一条执行语句都必须用分号“;”结束,分号是C语句的一部分,不是语句之间的分隔符。
C语言程序有比较自由的书写格式,但是过于“自由”的程序书写格式,往往使人们很难读懂程序,初学者应该从一开始就养成良好的习惯,使编写的程序便于阅读。
在程序中可以对程序进行注释,注释部分必须用符号“/*”和“*/”括起来。
“/*”和“*/”必须成对地出现,“/*”和“*/”之间不可以有空格。
注释可以用西文,也可以用中文。
注释可以出现在程序中任意合适的地方。
注释部分对程序的运行不起作用。
在注释中可以说明变量的含义、程序段的功能,以便帮助人们阅读程序。
因此一个好的程序应该有详细的注释。
程序中的第1行:
include“stdio.h”通常称为命令行,命令行必须用“#”号开关,最后不能加“;”,因为它不是C程序中的语句。
一对双引号中的stdio.h是系统提供的文件名,该文件中包含着有关输入输出函数的信息;调用不同的标准库函数,应当包含不同的文件,以便能包含有关库函数的信息;应该调用哪个文件,将在以后章节中陆续介绍.2.2常量、变量和标识符2.2.1标识符在C语言中,标识符可用作变量名、符号名、函数名和后面将要学到的数组名、文件名以及一些具有专门含义的名字。
合法的标识符由字母、数字或下划线组成,并且第一个字符必须为字母或下划线。
下面的标识符都是合法的:
area、PR_ini、a_array、sl234、PlOlp以下都是非法的标识符:
456Pcade-yw.w、a&b在C语言的标识符中,大写字母和小写字母被认为是两个不同的字符,因此page和Page是两个不同的标识符。
对于标识符的长度(即一个标识符允许的字符个数),一般的计算机系统规定取前8个字符有效,如果长于8个字符,多作的字符将不被识别。
如numberlOl和number102在计算机系统内则被认为是具有相同的标识符number。
有些系统允许取较长名字,读者在取名时应当了解所用系统的具体规定。
C语言的标识符可分为以下三类。
-关键字C语言规定了一批标识符,它们在程序中都代表着固定的含义,不能另作它用。
例如,用来说明变量类型的标识符int、float以及if语句中的if、else等都已有专门的用途,它们不能再用作变量名或函数名。
C语言中的关键字请参考附录一。
二.预定义标识符这些标识符在C语言中也都有特定的含义,如C语言提供的库函数的名字(如printf)和预编译处理命令(如define)等。
C语言语法允许用户把这类标识符另作它用,但这将使这些标识符失去系统规定的愿意。
鉴于目前各种计算机系统的C语言都一致把这类标识符作为固定的函数名或预编译处理中的专门命令使用,因此为了避免误解,建议用户不要把这些预定义标识符另作它用。
三.用户标识符由用户根据需要定义的标识符称为用户标识符。
一般用来给变量、函数、数组或文件等命名。
程序中使用的用户标识符除要遵循起名规则外,还应注意做到“见名知义”,即选具有相关含义的英文单词或汉语拼音,如numberlred、yellow,green、work,以增加程序的可读性。
如果用户标识符与关键字相同,程序在编译时将给出出错信息;如果与预定义标识符相同,系统并不报错,只是该预定义标识符将失去原定含义,代之以用户确认的含义;或者会引发些运行时错误。
2.2.2常量在程序运行过程中,其值不能改变的量,称为常量。
在C语言中,常量有不同的类型,有整型常量,实型常量,字符常量和字符串常量;即使是整型常量也还有短整型、长整型。
整型常量和实型常量也称数值型常量,它们有正值和负值区分。
基本整型常量只用数字表示,必须不带小数点;如:
12、-1、0等。
实型常量通常用带小数点的数表示,如:
3.14159、-2.17828、0.0等。
A,d则是字符型常量。
由此可见,常量的类型从字面形式即可区分,C编译程序就是以此来确定数值常量的类型的。
2.2.3用定义一个符号名的方法来代表一个常量可以用一个符号名来代表一个常量,但是这个符号名必须在程序中进行特别的“指定”。
例2.2计算圆面积。
#includestdio.h#definePI3.14159/*定义符号名PI为3.14159*/main()floatr,s;r=5.0;s=PI*r*r;printf(s=%fn”,s);)程序运行结果如下:
s=78.539749程序中用#define命令行(注意:
不是语句)定义PI代表-串字符3.14159,在对程序进行编译时,凡本程序中出现PI的地方,编译程序均用3.14159这一串字符来替换,在这里,PI是一个用户自己选择的符号名,本程序中,可以把PI视为3.14159的替身。
为了使之比较醒目,这种符号通常采用大写字母。
用define进行定义时,必须用#号作为一行的开头,在#define命令行的最后不得加分号结束。
有关#define命令行的作用,将在后续篇章中介绍,读者可以先按上述方法简单地使用。
在很多C语言书中把#define命令行中定义的符号名也称为符号常量。
2.2.4变量其值可以改变的量称为变量。
程序中所用到的每一个变量都应该有一个名字作为标识,它是属用户标识符。
如例2.1中的a、b和area就是山用户定义的变量名。
变量名的命名规则应遵守标识符命名规则。
一个变量实质上是代表了内存中的某个存储单元。
程序中的变量a,就是指用a命名的某个存储单元,用户对变量a进行的操作就是对该存储单元进行操作;给变量a赋值,实质上就是把数据存入该变量所代表的内存单元中。
C语言规定,程序中所要用到的变量应该先定义后使用。
通常,对变量的定义放在函数的开头部分,但也可以放在函数的外部或复合语句的开头。
象常量一样,变量也有类型的区分,如整型变量、实型变量、字符型变量等。
C语言在定义变量的同时说明该变量的类型,系统在编译时就能根据定义及其类型为它分配相应数量的存储空间。
2.3整型数据2.3.1整型常量在C语言中,整型常量可以用十进制、八进制和十六进制形式来表示。
十进制基本常量用一串连续的数字来表示,如:
32767、-32768、。
等。
八进制数用数字0开头(注意:
不是字母。
)。
例如:
010,011、016都是八进制数,它们分别代表十进制数8、9、14。
因此,在C程序中不能在一个十进制整数前面加前导零。
例如,不能把十进制数11写作011.注意:
八进制数只能用合法的八进制数字表示,如,不能写成018,因为数字8不是八进制数字,但C编译程序对此并不报错,只是得不到正确的结果。
十六进制数用数字0和字母x(或大写字母X)开头。
例如:
0x10、OXde、Oxf都是十六进制数,它们分别代表十进制数16、222、15。
注意:
十六制数只能用合法的十六进制数字表示,字母a、b、c、d、e、f,既可用大写也可用小写。
整型常量又有短整型(shortint)、基本整型(int)、长整型(longint)和无符号型(unsigned)的区分。
2.3.2整型变量整型变量可以分为基本型、短整型、长整型和无符号型四种。
本节只介绍基本类型的整型变量。
基本型的整型变量用类型名关键字int进行定义,定义形式如下:
intk;/*定义变量k为整型*/一个定义语句必须以一个“;”号结束。
在一个定义语句中也可以同时定义多个变量,变量之间用逗号隔开。
如:
intij.k;/*定义变量i、j、k为整型*/一般微机为基本型变量开辟2个字节(16个二进制位)的内存单元,并按整型数的存储方式存放数据。
整型的变量只能存放整型数值。
基本型整型变量中允许存放的数值范围是.3276832767(S|J-2I5(2I5-1)O当在程序中用以上方式定义变量i、j和k时,编译程序为变量i,j和k都开辟存储单元,但是并没有在存储单元中放置任何初值,因此在这些存储单元中,原有的信息(垃圾)并没有被清除,这时变量中的值是无意义的,称变量值“无定义”。
C语言规定,可以在定义变量的同时给变量赋初值,也称变量初始化。
如:
main()inti=l,j=0,k=2;/*定义i、j、k为整型变量,它们的初值分别为1、0和2*/)2.3.3整型数据的分类在前两节中已经介绍过int类型的整型常量和整型变量。
通常称int类型为基本整型。
除此以外,C语言中还包括其它三种整数类型,它们是短整型(shortint)、长整型(longint)、无符号型(unsigned),若不指定为无符号型,隐含的即为有符号型(signed),不同的计算机系统对这几类整型所占用的字节数和数值范围有不同规定,表2.1列出了微型机(IBMPC机)中这些类型的整型数所占用的字节数和数值范围,表中方括号内的单词可写也可不写,各单词的先后次序无关紧要。
signed用来说明“有符号”,不写signed也隐含为有符号。
表2.1类型名称占用的字节数数值范围signedint2-32768-32767signedshortint2-32768-32767signedlongint4-2147483648-2147483647unsignedint2065535unsignedshortint20-65535unsignedlongint404294967295若要表示个长整型常量,则应该在一个整型常量后面加一个字母后缀KL的小写)或L,如123L、3451、OL、123456L等,这些常量在内存中占四个字节。
注意:
一个足够大的数,如465356,虽然其面值是在长整型数的范围内,但由于数字后面未加后缀字母L,因此并不能代表一个长整型数。
无论是短整型还是长整型数,都被识别为有符号整数,无符号整数在数字的末尾应该加上字母后缀u或U,若是长整型无符号整数常量,则应该加后缀lu或LU;短整型无符号常量的取值应在065535范围内,长整型无符号常量的取值则在04294967295的范围内。
注意:
无符号常量不能表示成小于0的负数,例如:
-200U是不合法的。
2.3.4整数在内存中的存储形式计算机中,内存储器的最小存储单位称为“位(bite)”,每一个位中或者存放0,或者存放1,因此称为二进制位。
大多数计算机把8个二进制位组成一个“字节(byte)”,并给每个字节分配一个地址。
若干字节组成一个“字(word)”,用一个字来存放一条机器指令或一个数据。
一个字含多少个字节随机机器而不同。
如果一台计算机系统以两字节(16个二进制位)来存放一条机器指令,就称这台计算机的字长为16位;例如:
16位微机,就是指以16位二进制位作为一个字的微型计算机。
一个字节一般有8个二进制位,本书中把最右边的一位称为最低位,把最左边的一位称为最高位。
在C语言中,一个int整数通常用两个字节存放;其中最高位(最左边的一位)用来存放整数的符号,若是正整数,最高位放置0,若是负整数,最高位放置1。
因此,从最高位就立刻能判别出存放的一个整数是正整数还是负整数。
正整数C语言中,当用两个字节存放一个整数时,例如整数5在内存中的二进制码为:
0000000000000101对于正整数的这种存储形式称为用“原码形式”存放。
因此用两个字节存放的最大正整数是:
0111111111111111它的值为32767.为简单起见,书中对于整数5用一个字节00000101来表示。
二.负整数1.C语言中,对于负整数,在内存中是以整数的“补码”形式存放。
取某个二进制码的补码,如:
00000101(十进制数5)的补码,步骤如下:
(1)求原码的反码。
即:
把1转换成0,把0转换成1.因此00000101的反码为11111010.
(2)把所求得的反码加1,即得原码的被码。
因此11111010加1得1111011,这就是-5在内存中的二进制码。
用两个字节表示即为:
11111111111110112.要把内存中以补码形式存放的二进制码转换成十进制的负整数,步骤如下:
(1)先对各位取反。
例如,有补码11111010,取反后为00000101.
(2)将所得二进制数转换成卜进制数。
例如,00000101的十进制数为5.(3)因为11111010的最高位为1,因此在所得的十进制数前面加负号,得-5.(4)对所求得的数再减1,即为-6.由以上分析可知,山两个字节存放的最小整数是100000000000000000,它的十进制数为-32768;而-1的二进制码为1111111111111111。
读者可按以上步骤进行换算。
三、无符号整数用两个字节存放一个整数时,若说明为无符号整数,其中最高位不再用来存放整数的符号,16个二进制位全部用来存放整数,因此无符号整数不可能是负数,这时,16个二进制位中全部都是1时,它所代表的整数就不再是-1而是65535,对此请读者动手自己验证。
2.4实型数据2.4.1实型常量实型常量又称实数。
在C语言中可以用两种形式表示一个