第一章
C 语言概述 本章要求:
(1)C语句概述; (2)程序的三种基本结构; (3)赋值语句; (4)数据的输入与输出。
教学重点:
1. C语言的特点。
2. C语言的编程环境。
教学难点:
掌握编程环境的使用方法 教学方法:
采用多媒体教学的方法进行讲授,学生在教师指导下通过计算机进行操作练习。
课时数:4 (讲授 2 节课,上机练习 2 节课)
1.1 C 语言的发展及特点 1.1.1
C 语言的发展过程
1、C 语言是国际上流行的、很有发展前途的计算机高级语言。C 语言适合于作为“系统描述语言”。它既可以用来编写系统软件,也可以用来编写应用程序。
以前操作系统等系统软件主要采用汇编语言编写。汇编语言依赖于计算机硬件,程序的可读性、可移植性都比较差。为了提高可读性和可移植性,人们希望采用高级语言编写这些软件,但是一般的高级语言难以实现汇编语言的某些操作,特别是针对硬件的一些操作(如:内存地址的读写-直接硬件、二进制位的操作)。人们设法寻找一种既具有一般高级语言特性,又具有低级语言特性的语言,C 语言就在这种情况下应运而生。
2、C 语言的发展见下图:
注:最初 Unix 操作系统是采用汇编语言编写的,B 语言版本的 Unix 是第一个用高级语言编写的 Unix。在 C 语言诞生后,Unix 很快用 C 语言改写,C 语言良好的可移植性很快使Unix 从 PDP 计算机移植到其它计算机平台,随着 Unix 的广泛应用,C 语言也得到推广。从此C 语言和 Unix 像一对孪生兄弟,在发展中相辅相成,Unix 和 C 很快风靡全球。
ALGOL60 -> CPL -> BCPC -> B -> C -> 标准 C -> ANSI C -> ISO C ? ALGOL60:一种面向问题的高级语言。ALGOL60 离硬件较远,不适合编写系统程序。
? CPL(Combined Programming language,组合编程语言):CPL 是一种在ALGOL60 基础上更接近硬件的一种语言。CPL 规模大,实现困难。
? BCPL(Basic Combined Programming language,基本的组合编程语言):BCPL是对 CPL 进行简化后的一种语言。
? B 语言:是对 BCPL 进一步简化所得到的一种很简单接近硬件的语言。B 语言取BCPL 语言的第一个字母。B 语言精练、接近硬件,但过于简单,数据无类型。B
3、从 C 语言的发展历史可以看出,C 语言是一种既具有一般高级语言特性(ALGOL60 带来的高级语言特性),又具有低级语言特性(BCPL 带来的接近硬件的低级语言特性)的程序设计语言。C 语言从一开始就是用于编写大型、复杂系统软件的,当然 C 语言也可以用来编写一般的应用程序。也就是说:C 语言是程序员的语言!
IBM PC 微机 DOS、Windows 平台上常见的 C 语言版本有:
? Borland 公司:
Turbo C,Turbo C++,Borland C++ C++ Builder(Windows 版本) ? Microsoft 公司:
Microsoft C Visual C++(Windows 版本) 1.1.2
C 语言的特点
C 语言是从“组合编程语言”CPL 发展而来,C 语言既具有一般高级语言特性(ALGOL60带来的高级语言特性),又具有低级语言特性(BCPL 带来的接近硬件的低级语言特性)。C 语言具有下面特点(其中 1-6 属于高级语言特性,7,8 属于低级语言特性)
1、 C 语言的语言成分简洁,紧凑,书写形式自由 例:将 C 语言程序段与实现同样功能的 PASCAL 语言程序段进行比较。
C 语言 PASCAL 语言 含义 说明 1 {…} BEGIN…END 复合语句 (或:语句块) PASCAL 显得罗嗦 2 if(e)S; IF(e)THEN S; 条件语句 PASCAL 至少多了一个 THEN关键词 3 int i; VAR i:INTEGER 定义 i 为整型变量 PASCAL 至少多了一个 VAR 关键词 4 int a[10]; VAR a:ARRAY[1..10] OF INTEGER 定义 a 为整型一维数组,10 个元素 PASCAL 多了 VAR、ARRAY、OF 等关键词 5 int f(); FUNCTION f():INTEGER 定义 f 为返回值为整型的函数 PASCAL 至 少 多 了 一 个FUNCTION 关键词 6 int *p; VAR p:^INTEGER 定义 p 为指向整型变量的指针变量 PASCAL 至少多了一个 VAR 关键词
7 i+=2; i:=i+2 赋值语句 C 中如果将一个变量与另外一个操作数运算后赋值给原来的变量,使用复合的运算符可以不要重复书写此变量。C 形式上更加简洁。
8 I++ I=I+1 I 自增 1 C 定义了常用的自增 1、自减 1 运算符。形式上显得相当简洁 2、 C 语言拥有丰富的数据类型 C 语言具有整型、实型、字符型、数组类型、指针类型、结构体类型、共同体类型等数据类型。能方便地构造更加复杂的数据结构(如:使用指针构造链表、树、栈)。
3、 C 语言的运算符丰富、功能更强大 例如:
(1) C 语言具有复合的赋值运算符“+[-*/%]=”(加等、减等、乘等、除等) ,“>>=”“<<=”(右移等、左移等),“&[^|]=”(与等、或等、非等)。
x+=5 等价于 x=x+5 (2) C 语言有条件运算符“:”可代替简单的 if/else 语句。
如果需要表示:“如果 x 小于或等于 0,y 为 0;否则 y 为 1”可以采用:
y=x<=00:1; 如果用一般的程序设计语言表示就应该像下面这样表示:
if(x<=0)y=0;
else y=1; C 语言避免了一切可能的罗嗦, (3) C 语言中连赋值这种操作都定义为运算符,也就是说赋值操作本身可以作为表达式的一部分,参与运算。如:
if((p=malloc(sizeof(int)))==NULL){printf(“Error!”);exit(1);} 如果改写为一般形式:
p=malloc(sizeof(int));
if(p==NULL){printf(“Error!”);exit(1);} 又如下面算式是正确的:
x=y=z=6;
如果改写为一般形式:
z=6;y=6;x=6; 4、 C 语言是结构化的程序设计语言 ? C 语言具有结构化的控制语句(if/else,switch/case,for,while,do…while) ? 函数是 C 语言程序的模块单位。
5、 C 语言对语法限制不严格,程序设计灵活 C 语言不检查数组下标越界,C 语言不限制对各种数据转化(编译系统可能对不合适的转化进行警告,但不限制),不限制指针的使用,程序正确性由程序员保证。
实践中,C 语言程序编译时会提示:“警告错”“严重错误”。警告错误表示你使用的语法可能有问题,但是你有时可以忽略,你的程序仍然可以完成编译工作,然后运行。(但是一般情况下警告错,往往意味着程序真的有问题,你应该认真地检查)“严重错”是不能忽略的,编译系统发现严重错误,就不会产生目标代码。
灵活和安全是一对矛盾,对语法限制的不严格可能也是 C 语言的一个缺点,比如:黑客可能使用越界的数组攻击你的计算机系统。JAVA 语言是优秀的网络应用程序开发语言,它必须保证安全性,它绝对不允许数组越界。此外 JAVA 不使用指针,不能直接操作客户计算机上的文件,语法检查相当严格,程序正确性容易保证,但是 JAVA 在编程时却缺乏灵活。
6、 C 语言编写的程序具有良好的可移植性 编制的程序基本上不需要修改或只需要少量修改就可以移植到其它的计算机系统或其它的操作系统。
7、 C 语言可以实现汇编语言的大部分功能 ? C 语言可以直接操作计算机硬件如寄存器,各种外设 I/O 端口等。
? C 语言的指针可以直接访问内存物理地址。
? C 语言类似汇编语言的位操作可以方便地检查系统硬件的状态。
C 语言适合编写系统软件。
8、 C 语言编译后生成的目标代码小,质量高,程序的执行效率高 有资料显示只比汇编代码效率低 10%-20%。
1.2 C 语言程序的基本结构 1.2.1
简单的 C 程序介绍
例 1.1:
main() {
printf(“This is a C program.\n”); } 说明:本程序的功能是输出一行信息:This is a C program. 其中:
1、main 表示“主函数”。每个 C 语言程序都必须有一个 main 函数,它是每一个 C 语言程序的执行起始点(入口点)。main()表示“主函数”main 的函数头。
2、用{}括起来的是“主函数”main 的函数体。main 函数中的所有操作(或:语句)都在这一对{}之间。也就是说 main 函数的所有操作都在 main 函数体中。
3、“主函数”main 中只有一条语句,它是 C 语言的库函数,功能是用于程序的输出(显示在屏幕上),本例用于将一个字符串“This is a C program.\n”的内容输出。即在屏幕上显示:
This is a C program. _
(回车/换行) 4、注意:每条语句用“;”号结束语句。
例 1.2: main()
/* 计算两数之和 */ {
int a,b,sum;
/* 这是定义变量 */
a=123;b=456;
/* 以下 3 行为 C 语句 */
sum=a+b;
printf(“sum=%d\n”,sum); } 说明:本程序计算两数之和,并输出结果。
1、同样此程序也必须包含一个 main 函数作为程序执行的起点。{}之间为 main 函数的函数体,main 函数所有操作均在 main 函数体中。
2、/* */括起来的部分是一段注释,注释只是为了改善程序的可读性,在编译、运行时不起作用(事实上编译时会跳过注释,目标代码中不会包含注释)。注释可以放在程序任何位置,并允许占用多行,只是需要注意“/*”、“*/”匹配,一般不要嵌套注释。
3、int a,b,sum;是变量声明。声明了三个具有整数类型的变量 a,b,sum。C 语言的变量必须先声明再使用。
4、a=123;b=456;是两条赋值语句。将整数 123 赋给整型变量 a,将整数 456 赋给整型变量 b。a,b 两个变量分别为 123,456。注意这是两条赋值语句,每条语句均用“;”结束。
也可以将两条语句写成两行,即:
a=123; b=456; 由此可见 C 语言程序的书写可以相当随意,但是为了保证容易阅读要遵循一定的规范。
5、sum=a+b;是将 a,b 两变量内容相加,然后将结果赋值给整型变量 sum。此时 sum 的内容为579。
6、printf(“sum=%d\n”,sum);是调用库函数输出 sum 的结果。%d 为格式控制表示 sum 的值以十进制整数形式输出。程序运行后,输出(显示):
sum=579 _
(回车/换行) 例 1.3
说明:输入两个整数,计算两者较大的数,并输出。
1、本程序包括两个函数。其中主函数 main 仍然是整个程序执行的起点。函数 max 计算两数中较大的数。
2、主函数 main 调用 scanf 函数获得两个整数,存入 a,b 两个变量,然后调用函数 max 获得两个数字中较大的值,并赋给变量 c。最后输出变量 c的值(结果)。
3、int max(int x,int y)是函数 max 的函数头,函数 max 的函数头表明此函数获得两个整数,返回一个整数。
main()/* 主函数 */ {/* main 函数体开始 */
int a,b,c; /*声明部分定义变量*/
scanf(“%d,%d”,&a,&b);
/* 调用 max,将调用结果赋给 c */
c=max(a,b);
printf(“max=%d”,c); }/* main 函数体结束 */
int max(int x,int y)/* 计算两数中较大的数 */ {/* max 函数体开始 */
int z;
/* 声明部分,定义变量 */
if(x>y)z=x;
else z=y;
return z;
/* 将 z 值返回,通过 max 带回调用处 */ }/* max 函数体结束 */
4、函数 max 同样也用{}将函数体括起来。max 的函数体是函数 max 的具体实现。从参数表获得数据,处理后得到结果 z,然后将 z 返回调用函数 main。
5、本例还表明函数除了调用库函数外,还可以调用用户自己定义,编制的函数。
1.2.2
C 程序结构
综合上述三个例子,我们对 C 语言程序的基本组成和形式(程序结构)有了一个初步了解:
1、C 程序由函数构成(C 是函数式的语言,函数是 C 程序的基本单位)(以例 1.3 说明)
? 一个 C 源程序至少包含一个 main 函数,也可以包含一个 main 函数和若干个其它函数。函数是 C 程序的基本单位。
? 被调用的函数可以是系统提供的库函数,也可以是用户根据需要自己编写设计的函数。C 是函数式的语言,程序的全部工作都是由各个函数完成。编写 C 程序就是编写一个个函数。
? C 函数库非常丰富,ANSI C 提供 100 多个库函数,Turbo C 提供 300 多个库函数。
2、main 函数(主函数)是每个程序执行的起始点(以例 1.3 说明)
一个 C 程序总是从 main 函数开始执行,而不论 main 函数在程序中的位置。可以将 main函数放在整个程序的最前面,也可以放在整个程序的最后,或者放在其它函数之间。
3、一个函数由函数首部和函数体两部分组成(以例 1.3 的 max 函数说明) (1)函数首部:一个函数的第一行。
返回值类型 函数名([函数参数类型 1 函数参数名 1][,…,函数参数类型 2,函数参数名 2])
注意:函数可以没有参数,但是后面的一对()不能省略,这是格式的规定。
(2)函数体:函数首部下用一对{}括起来的部分。如果函数体内有多个{},最外层是函数体的范围。函数体一般包括声明部分、执行部分两部分。
{
[声明部分]:在这部分定义本函数所使用的变量。
[执行部分]:由若干条语句组成命令序列(可以在其中调用其它函数)。
} 4、C 程序书写格式自由 ? 一行可以写几个语句,一个语句也可以写在多行上。
? C 程序没有行号,也没有 FORTRAN,COBOL 那样严格规定书写格式(语句必须从某一列开始)。
? 每条语句的最后必须有一个分号“;”表示语句的结束。
5、可以使用/* */对 C 程序中的任何部分作注释 注释可以提高程序可读性,使用注释是编程人员的良好习惯。
实践中, ? 编写好的程序往往需要修改、完善,事实上没有一个应用系统是不需要修改、完善的。很多人会发现自己编写的程序在经历了一些时间以后,由于缺乏必要的文档、必要的注释,最后连自己都很难再读懂。需要花费大量时间重新思考、理解原来的程序。这浪费了大量的时间。如果一开始编程就对程序进行注释,刚开始麻烦一些,但日后可以节省大量的时间。
? 一个实际的系统往往是多人合作开发,程序文档、注释是其中重要的交流工具。
6、C 语言本身不提供输入/输出语句,输入/输出的操作是通过调用库函数(scanf,printf)完成。
输入/输出操作涉及具体计算机硬件,把输入/输出操作放在函数中处理,可以简化 C 语言和 C 的编译系统,便于 C 语言在各种计算机上实现。不同的计算机系统需要对函数库中的函数做不同的处理,以便实现同样或类似的功能。
不同的计算机系统除了提供函数库中的标准函数外,还按照硬件的情况提供一些专门的函数。因此不同计算机系统提供的函数数量、功能会有一定差异。
1.3
算法及其描述 1、算法:为解决一个问题而采取的方法和步骤称为“算法”。
对于同一个问题可以有不同的解题方法和步骤,也就是有不同的算法。算法有优劣,一般而言,应当选择简单的、运算步骤少的,既运算快、内存开销小的算法(算法的时空效率)。
2、算法的 5 大特性 (1)有穷性:一个算法应当包含有限的步骤,而不能是无限的步骤;同时一个算法应当在执行一定数量的步骤后,算法结束,不能死循环。
事实上“有穷性”往往指“在合理的范围之内”的有限步骤。如果让计算机执行一个历时1000 年才结束的算法,算法尽管有穷,但超过了合理的限度,人们也不认为此算法是有用的。
(2)确定性 算法中的每一个步骤都应当是确定的,而不是含糊的、摸棱两可的。也就是说不应当产生歧义。特别是算法用自然语言描述时应当注意这点。
例如:“将成绩优秀的同学名单打印输出”就是有歧义的。“成绩优秀”是要求每门课程都90 分以上,还是平均成绩在 90 分以上?不明确,有歧义,不适合描述算法步骤。
(3)有 0 个或多个输入(即:可以没有输入,也可以有输入)
所谓输入是指算法执行时从外界获取必要信息。(外界是相对算法本身的,输入可以是人工键盘输入的数据,也可以是程序其它部分传递给算法的数据)
例如:
例如:不需要输入任何信息,就可以计算出 5!;(0 个输入)
例如:输入一个正整数 n,然后判断 n 是否为素数;(1 个输入)
例如:如果要计算两个整数的最大公约数,则需要输入 2 个整数 m,n。(2 个输入)
(4)有 1 个或多个输出(即算法必须得到结果)
算法的输出:算法得到的结果。算法必须有结果,没有结果的算法没有意义。(结果可以是显示在屏幕上的,也可以是将结果数据传递给程序的其它部分)
(5)有效性 算法的每个步骤都应当能有效执行,并能得到确定的结果。例如:b=0,则执行 a/b 是不能有效执行的。
3、算法的表示方法 为了表示一个算法,可以用不同的方法。常用的算法表示方法:自然语言,传统流程图,结构化流程图(N-S 流程图),伪代码、计算机语言等。(重点:传统流程图,N-S 流程图)
(1)
用自然语言表示算法 算法可以用自然语言描述的。自然语言就是人们日常使用的语言,可以是汉语、英语或其它语言。用自然语言表示通俗易懂,但文字冗长,容易出现歧义。自然语言表示的含义往往不太严格,要根据上下文才能准确判断其含义。此外,用自然语言描述分支和循环的算法,不是很直观。因此,除了简单问题,一般不采用自然语言描述算法。
(2)
用流程图表示算法 流程图表示算法:用一些图框表示各种操作,用箭头表示算法流程。用图形表示算法直观形象,易于理解。
美国标准化协会 ANSI 规定了一些常用的流程图符号,已为世界各国程序工作者普遍采用。
? 起止框:表示算法的开始和结束。一般内部只写“开始”或“结束”。
? 处理框:表示算法的某个处理步骤,一般内部常常填写赋值操作。
? 输入输出框:表示算法请求输入输入需要的数据或算法将某些结果输出。一般内部常常填写“输入…”,“打印/显示…” ? 菱形框(判断框):作用主要是对一个给定条件进行判断,根据给定的条件是否成立来决定如何执行其后的操作。它有一个入口,两个出口。
? 连接点:用于将画在不同地方的流程线连接起来。同一个编号的点是相互连接在一起的,实际上同一编号的点是同一个点,只是画不下才分开画。使用连接点,还可以避免流程线的交叉或过长,使流程图更加清晰。
? 注释框:注释框不是流程图中必须的部分,不反映流程和操作,它只是对流程图中某些框的操作做必要的补充说明,以帮助阅读流程图的人更好地理解流程图的作用。
流程图是表示算法的较好的工具。流程图包括以下几个部分:表示相应操作的框,带箭头的流程线,框内、框外必要的文字说明。注意:流程线一定不要忘记箭头,因为它反应流程执行的先后次序。
传统流程图采用流程线指出各框的执行顺序,对流程线的使用没有严格限制。因此,使用者可以不受限制地使流程转来转去,使流程图变得毫无规律。人们对这种流程图进行改进,规定几种基本的结构,然后由这些基本结构按一定规律组成算法结构,整个算法结构是由上而下地将各个基本结构顺序排列起来。这样可以在一定程度上,提高算法的质量。
三种基本结构,有以下共同点:
? 只有一个入口:不得从结构外随意转入结构中某点。
? 只有一个出口:不得从结构内某个位置随意转出(跳出)。
? 结构中的每一部分都有机会被执行到。(没有“死语句”)
? 结构内不存在“死循环”(无终止的循环)
已经证明:由三种基本结构顺序组成的算法结构,可以解决任何复杂问题。由基本结构组成的算法属于“结构化”算法。
用流程图表示的算法直观形象,比较清楚地显示出各个框之间的逻辑关系,因此得到广泛使用。每一个程序编制人员都应当熟练掌握流程图,会看会画。(软件专业水平、资格考试也用这种流程图表示)。
绘制流程图可以使用 Visio 3,4…等流程图设计工具。
(3)
用 N-S 流程图表示算法(盒图)
既然基本结构的顺序组合可以表示任何复杂的算法结构,那么,基本结构之间的流程线就属于多余的了。美国学者 I.Nassi,B.Shneiderman 提出了一种新的流程图 N-S 流程图。这种流程图中,完全去掉了带箭头的流程线。每种结构用一个矩形框表示。
N-S 流程图的流程图符号:
? 顺序结构:先执行 A 操作,再执行 B 操作。
? 选择结构:当 p 条件成立,执行 A 操作,当 p 条件不成立,执行 B 操作。A,B 操作允许空操作,即什么都不做。注意选择结构是一个整体,代表一个基本结构。
? 循环结构:a)当型循环:当条件 p 成立时,反复执行 A 操作,直到 p 条件不成立为止。当型循环先判断,再决定是否执行循环体,所以在条件 p 一次都不满足时,循环体 A 可能一次都不执行。b)直到型循环:当条件 p 不成立时,反复执行 A 操作,直到 p 条件成立为止。直到型循环先执行循环体 A,然后再判断条件 p,所以循环体至少执行一次。
一般情况循环算法既可以用当型循环,也可以用直到型循环实现(可以实现等价算法)。循环结构也是一个整体,同样也代表一个基本结构。
注意:
三种结构中的 A、B 框可以是一个简单的操作,也可以是 3 个基本结构之一。也就是说基本结构可以嵌套。
N-S 流程图表示算法的优点:(未找到计算机绘盒图的工具,smartdraw)
? 比文字描述更加直观、形象,易于理解; ? 比传统的流程图紧凑易画; ? 废除流程线,整个算法结构是由各个基本结构按顺序组成。N-S 流程图的上下顺序就是执行时的顺序。N-S 图表示的算法都是结构化的算法。
(4)
用伪代码表示算法(常常用于算法设计)
用传统流程图、N-S 图表示算法,直观易懂,但绘制比较麻烦,在设计一个算法时,可能要反复修改,而修改流程图是比较麻烦的,因此,流程图适合表示算法,但在设计算法过程中使用不是很理想。为了设计算法方便,常使用伪代码工具。
伪代码是用介于自然语言和计算机语言之间的文字和符号来描述算法。伪代码不用图形符号,书写方便,格式紧凑,便于向计算机语言算法过渡。
(5)
用计算机语言表示算法 用计算机语言表示算法实际上就是实际的程序。用计算机语言表示算法必须严格遵守所使用的语言的语法规则。
结构化算法或程序由三种基本结构顺序组成:
1、顺序结构 2、选择结构 3、循环结构
在基本结构之间不存在向前或向后的跳转,流程的转移只存在于一个基本结构中。可以用改进流程图,或 N-S 图表示。
例 1:计算 1x2x3x4x5。(即 5!)
解:
算法 1:直接写出算式 S1:
result<=1x2x3x4x5 很简单,一步就完成了。但是考虑一下如果要计算 100!,是否写都写得累死了。
算法 2:
考虑到 1x2x3x4x5 可以改写为:(((1x2)x3)x4)x5), S1:p1<=1x2 S2: p2<=p1x3 S3: p3<=p2x4 S4: p4<=p3x5
结果在 p4 里。
考虑计算 100!,同样此算法也一样麻烦,要写 99 步。本算法同样不适合编程。
但是可以从本算法看出一个规律。即:每一步都是两个数相乘,乘数总是比上一步乘数增加 1 后参与本次乘法运算,被乘数总是上一步乘法运算的乘积。可以考虑用一个变量 i 存放乘数,一个变量 p 存放上一步的乘积。那么每一步都可以写成:pxi,然后让 pxi 的乘积存入 p,即:每一步都是 p<=pxi。也就是说 p 既代表被乘数又代表乘积。这样可以得到算法 3。
算法 3:
S0: p<=1,i<=2 S1: p<=pxi, i<=i+1 S2: p<=pxi, i<=i+1 S3: p<=pxi, i<=i+1 S4: p<=pxi, i<=i+1 从算法 3 表面上看与算法 2 差不多,如果要计算 100!,同样要写 99 步。但是从算法 3 可以看出 S1-S4 步骤实际上是一样的,也就是说 S1-S4 同样的操作重复做了 4 次。计算机对同样的操作可以用循环完成,循环是计算机工作的强项(计算机高速度运算)。算法 4 就是在算法3 的基础上采用循环功能的算法实现。
算法 4:
S0: p<=1,i<=2 S1: p<=pxi, i<=i+1
S2: 如果 i 小于或等于 5,返回重新执行步骤 S1 及 S2;否则,算法结束,此时 p 中的值就是5!的值。
显然算法 4 简洁,通用性好。如果要计算 100!只要将 S2 中的循环判断条件改为:“…i小于或等于 100…”,算法其余部分不需要做任何修改。
如果要计算 1x3x5x7x9x11,只要将 S0:“i<=2”修改为“i<=3”,S1:“i<=i+1”修改为“i<=i+2”, 循环判断条件改为:“…i 小于或等于 11…”即可。
从本例可以看出,同样的问题,算法实现可以不同。同一问题的不同的算法在算法通用性、算法的简洁程度上有较大的差异。计算机处理有规律的事情比较方便,尽量考虑将算法某个部分统一,以便采用循环处理。
求 5!的算法(传统流程图表示)
求 5!的算法(N-S 流程图表示)
p<=1 i<=2 p<=p*i i<=i+1
直到 i>5 例 2:
对于一个大于或者等于 3 的正整数,判断它是不是一个素数。(素数,是指除了 1 和该数本身之外,不能被其它任何整数整除的数)(疑问?1,2 是否是素数)
解:
分析:根据素数定义,对于一个≥3 的正整数 n,如果 n 只能被 1,n 整除,那么 n 是素数;也就是素数必须满足两个条件:
1、是≥3 的正整数 2、只能被 1 和自身整除(被 1 和自身是肯定可以整除的),不能被其它 2-(n-1)的正整数整除(全部不能整除)。
反过来理解:任何≥3 的正整数 n,如果能够被 2-(n-1)的任何一个正整数整除,那么它一定不是素数。
假设给定的正整数 n,根据题意,判断一个正整数是否素数,可以用 n 作为被除数,分别将 2,3,4…n-1 各个正整数作为除数,如果有任何一个可以整除,那么 n 不是素数,如果全部都不能整除,那么 n 是素数。
算法:
S0: 输入 n
S1: i<=2 S2: n 被 i 除得到余数 r S3: 如果余数 r=0,表示 n 能被 i 整除,则打印 n“不是素数”,算法结束;否则继续执行 S4 S4: i<=i+1 S5: 如果 i≤n-1,返回执行 S2,否则打印 n“是素数”,算法结束。
实际上,n 不必被 2 到(n-1)的整数除,只需要被 2 到 n/2 之间的整数除即可,甚至只需被 2到 sqrt(n)之间的整数除即可。
判断素数算法(N-S 流程图表示)
输入 n i<=2,w<=0 r<=n%i
y
r=0
n
w<=1
i<=i+1 直到 i>n-1 或 w=1
y
w=0
n 不是素数
是素数 判断素数算法(传统流程图表示)
1.4
C 语言程序的上机步骤 1、源程序、目标程序、可执行程序的概念(补充)
? 程序:为了使计算机能按照人们的意志工作,就要根据问题的要求,编写相应的程序。程序是一组计算机可以识别和执行的指令,每一条指令使计算机执行特定的操作。
? 源程序:程序可以用高级语言或汇编语言编写,用高级语言或汇编语言编写的程序称为源程序。C 程序源程序的扩展名为“.c” 事实上我们编写的程序,不管采用什么计算机语言,都是源程序,有几个人还会用机器语言去编程!
源程序不能直接在计算机上执行,需要用“编译程序”将源程序翻译为二进制形式的代码。
? 目标程序:源程序经过“编译程序”翻译所得到的二进制代码称为目标程序。目标程序的扩展名为“.obj”
目标代码尽管已经是机器指令,但是还不能运行,因为目标程序还没有解决函数调用问题,需要将各个目标程序与库函数连接,才能形成完整的可执行的程序。
? 可执行程序:目标程序与库函数连接,形成的完整的可在操作系统下独立执行的程序称为可执行程序。可执行程序的扩展名为“.exe”(在 dos/windows 环境下) 2、C 语言程序的上机步骤 输入与编辑源程序->编译源程序,产生目标代码-> 连接各个目标代码、库函数,产生可执行程序->运行程序。
3、Turbo C 的使用(DOS 环境) Turbo C2.0 是 Borland 公司开发的微机上一个 C 语言集成开发环境。可以在 Turbo C 中完成 C语言程序的编辑、编译、连接、运行、调试。
具体操作上机时演示(重点:启动,退出,重要的菜单项)
重点菜单项:
File->new,load,save,write to Compile->compile to obj,make exe file,build all Run->run,go to cursor,trace into,step over,user screen,program reset Debug->Evaluate 4.Visual C 的使用(Windows 环境)
Visual C 是 windows 环境下的 C 应用程序,C++应用程序,Windows 应用程序集成开发环境。
作业:
书后习题 实验一:熟悉 C 语言程序开发环境