4.0 程序设计基本概念
4.1 结构化程序设计
4.2 c 语句概述
4.3 顺序结构及实现
4.4 选择结构及实现
4.5 循环结构及实现
4.6 转向语句
4.7 循环结构程序设计举例第四章 C程序流程设计
4.0 程序设计基本概念程序程序是指为让计算机完成某个任务而设计的,由有限步骤所组成的一个有机的指令序列 。
算法与数据结构计算机科学家沃斯 ( N.Wirth) 提出过一个经典公式:
算法 +数据结构 =程序算法反映了计算机的执行过程,是对解决特定问题的操作步骤的一种描述 。 数据结构是对参与运算的数据及它们之间的关系进行的描述,算法和数据结构是程序的两个重要方面 。
算法算法是由一套明确的规则组成的一些步骤,它指定了操作顺序并通过有限个步骤将问题解决、得出结果。
一个算法应具有以下特性:
有穷性 一个算法必须总是在执行有限个操作步骤和可以接受的时间内完成其执行过程。
确定性 算法中的每一步都必须有明确的含义,不允许存在二义性。
有效性 算法中描述的每一步操作都应该能有效地执行,
并最终得到确定的结果。
输入 一个算法应零个或多个输入数据。
输出 一个算法应有 1个或多个输出数据。没有输出的算法是无意义的。
算法的表示方法
自然语言:
用自然语言表示的算法通俗易懂,但易引起,歧义性,。
传统流程图,
传统流程图是用规定的一组图形符号、流程线和文字说明来表示各种操作的算法表示方法。
N-S结构图,
N-S结构图取消了流程线,不允许有随意的控制流,全部算法写在一个矩形框内,该矩形框以三种基本结构描述符号为基础复合而成。
伪 代码,
伪代码是用一种介于自然语言和计算机语言之间的文字和符号来描述算法,表现形式比较灵活自由,没有严谨的语法格式。
结构化程序设计的三种基本结构
顺序结构顺序结构是最简单的基本结构,要求顺序地执行且必须执行由先后顺序排列的每一个最基本的处理单位。
顺序结构的示意图如下图所示,表示先执行,处理 A”,然后再顺序执行,处理 B”。
处理 A
处理 B
(a) (b)
处理 A
处理 B
(a)图是用传统流程图表示的顺序结构。
(b)图是用 N-S结构图表示的顺序结构。
分支 结构分支结构又称作选择结构。在分支结构中,要根据逻辑条件的成立与否,分别选择执行不同的处理。
分支结构的示意图如下图所示,表示当逻辑条件成立是,执行处理 A,否则执行处理 B。
处理 A 处理 B
真 假条 件
(a)
条 件处理 A 处理 B
成立 不成立
(b)
(a)图是用传统流程图表示的顺序结构。
(b)图是用 N-S结构图表示的顺序结构。
循环结构
当型循环在当型循环结构中,当逻辑条件成立时,就反复执行处理
A,直到逻辑条件不成立时结束。 如下图所示,
处理 A
假真条 件
(a)
当条件成立时继续处理 A
(b)
(a)图是用传统流程图表示的顺序结构。
(b)图是用 N-S结构图表示的顺序结构 。
直到型循环在直到型循环结构中,反复执行处理 A,直到逻辑条件成立时结束,如图所示,
处理 A
假真 条 件
(a)
处理 A
直到条件成立时结束
(b)
(a)图是用传统流程图表示的顺序结构。
(b)图是用 N-S结构图表示的顺序结构 。
4.1 结构化程序设计
4.1.1 程序设计的一般步骤
分析问题,确定解题方案 。
确定算法 。
根据选取的数学模型和确定的解题方案,设计出具体的操作步骤 。 可用 流程图表示 。
编写程序 。
用程序设计语言编制的源程序 。
调试运行程序 。
对编好的程序进行试运行和检验,发现问题即对程序进行修改,直至得出正确的结果 。
建立文档资料 。
整理分析计算结果,并建立相应的文档资料 。
4.1.2 结构化程序设计方法
程序的质量标准是,清晰第一,效率第二,。
程序的设计采用,自顶向下,逐步求精,模块化,
的方法。
程序的结构仅由三种基本结构组合、嵌套而成,
且满足:
每个程序模块只有一个入口和一个出口;
没有死语句(永远执行不到的语句);
没有死循环(永远执行不完的无终止的循环)。
程序的书写必须按一定的规范和格式进行,不能随心所欲地拼凑。
程序的设计风格要以好的可读性为标准,以使用程序的用户为中心,外表美观、结构流畅、语句简洁。
4.1.3 程序设计风格程序的设计风格直接影响到程序的可读性。
表现在以下几个方面:
算法,程序中采用的算法要直接了当、尽可能简单,避免使用过于复杂和技巧性强的算法。
程序正文格式:
标识符要采用有意义的名字命名,达到,见名知意,。
注释:提高程序的可读性;每个函数前面加上描述函数功能的注释;主要语句也加注释。
程序中加注释,提高程序的可读性。
采用一致的缩格书写形式,以突出程序的逻辑结构 。
数据说明与语句构造,数据说明应当标准化,语句构造应以简洁、直接为原则 。
输入输出格式,要以方便用户使用为原则 。
文档整理,尽量使用利于阅读的行文格式,逻辑简单、条理清楚。
语句是向计算机发出指令的基本单位,是 C程序的重要组成部分,它表示程序执行的步骤,实现程序的功能。
C语句用来完成一定的操作任务,一个 C语句经编译后一般会产生若干条机器指令。
但是,声明部分内容不产生机器指令,只是对变量或被调函数的声明,因此严格来说不是语句。
C语句以分号,;,结尾
书写自由,一行多条语句或一语句拆成多行。语句之间用,;,隔开就可以了。
4.2 C语句概述
C语句分类
表达式语句:表达式加分号构成。
空语句,;
程序控制语句 (9种):
if( )~else~
switch
for( )~
while( )~
do~while( )
continue
break
goto
return
分支循环辅助控制如 total=total+limit;
a=3;
func( );
printf(“Hello,world!\n”);
函数调用语句,函数名(实际参数表);
复合语句:用 {… }括起来的一组语句
一般形式,{ [数据说明部分; ]
执行语句部分;
}
说明:
,}”后不加分号
语法上和单一语句相同
复合语句可嵌
4.3.1 顺序结构程序设计的思想顺序结构是结构化程序设计中最简单、最常见的一种程序结构。顺序结构中,程序是按照各语句出现的次序顺序执行的。
顺序结构程序通常由三部分组成:
输入数据,让计算机为用户进行运算,首先必须把已知的数据,即让计算机进行运算的对象,输入到计算机中 。
进行处理,已知数据输入到计算机的基础上,根据问题的需要对其进行相应的运算处理 。
输出结果,让计算机程序进行运算处理的目的是为了得到相应的结果,因此,必须将运算处理的结果输出出来 。
4.3 顺序结构程序设计的思想
4.3.2 实现顺序结构程序设计的基本语句赋值 语句,赋值语句由赋值表达式加上一个分号构成,一般形式为:
变量=表达式;
例如,radius=14.5;
i++;
x+=2;
赋值语句是将右边表达式的值赋给左边的变量中去。赋值语句要先对表达式加以计算求得其值,
而后再将求得的值赋给左边的变量中去,因此可以说赋值语句兼有计算功能。
标准输入输出,(printf,scanf.putchar,getchar)
4.4 选择型程序设计
if语句 (条件选择语句)
if语句的三种形式
形式一:
格式,if (expression)
statement
执行过程:
expr
statement
非 0
=0
例,if (x>y)
printf(“%d”,x);
expr
statement1 statement2
非 0 =0?形式二,
格式,if (expression)
statement1
else
statement2
执行过程,例,if (x>y) max=x;
else max=y;
形式三:
格式:
if ( expr1 ) statement1
else if (expr2 ) statement2
else if (expr3 ) statement3
…...
[ else statementn ]
expr1
statemnt1
非 0
=0
expr2
expr3
statemntnstatemnt3statemnt2
非 0
非 0
=0
=0
执行过程:
例,if (salary>1000) index=0.4;
else if (salary>800) index=0.3;
else if (salary>600) index=0.2;
else if (salary>400) index=0.1;
else index=0;
如,if(a==b&&x==y) printf(“a=b,x=y”);
if(3) printf(“OK”);
if(?a?) printf(“%d”,?a?);
说明:
if后面的表达式类型任意
语句可以是复合语句
if(x)? if(x!=0)
if(!x)? if(x==0)
例 考虑下面程序的输出结果,
#include <stdio.h>
main()
{ int x,y;
scanf(“%d,%d”,&x,&y);
if(x>y)
x=y; y=x;
else
x++; y++;
printf(“%d,%d\n”,x,y);
}
Compile Error!
/*ch4_1.c*/
#include <stdio.h>
main()
{ int x,y;
printf("Enter an integer:");
scanf("%d",&x);
y=x;
if(y<0)
y= -y;
printf("\ninteger:%d--->absolute value:%d\n",x,y);
}
例 求一个数的绝对值运行,Enter an integer:-12?
integer:-12--->absolute value,12
/*ch4_2.c*/
#include <stdio.h>
main()
{ int a,b;
printf("Enter integer a:");
scanf("%d",&a);
printf("Enter integer b:");
scanf("%d",&b);
if(a==b)
printf("a==b\n");
else
printf("a!=b\n");
}
例 输入两个数并判断两数相等否运行,Enter integer a:12?
Enter integer b:12?
a==b
运行,Enter integer a:12?
Enter integer b:9?
a!=b
/*ch4_3.c*/
#include <stdio.h>
main()
{ char c;
printf("Enter a character:");
c=getchar();
if(c<0x20) printf("The character is a control character\n");
else if(c>='0'&&c<='9') printf("The character is a digit\n");
else if(c>='A'&&c<='Z') printf("The character is a capital letter\n");
else if(c>='a'&&c<='z') printf("The character is a lower letter\n");
else printf("The character is other character\n");
}
例 判断输入字符种类运行,Enter a character,?
The character is a control character
运行,Enter a character,8?
The character is a digit
运行,nter a character,D?
cap al letter
运行,Enter a character,h
he character is a lower letter
运行,t r r t r,F1?
T r t r is other character
if语句嵌套,
一般形式:
if (expr1)
if (expr2) statement1
else statement2
else
if(expr3) statement3
else statement4
内嵌 if
内嵌 if
if (expr1)
if (expr2)
statement1
else
statement2
内嵌 if
if (expr1)
if (expr2)
statement1
else
statement3
内嵌 if
if (expr1)
statement1
else
if(expr3)
statement3
else
statement4
内嵌 if
例 输入两数并判断其大小关系
/*ch4_4.c*/
#include <stdio.h>
main()
{ int x,y;
printf("Enter integer x,y:");
scanf("%d,%d",&x,&y);
if(x!=y)
if(x>y) printf("X>Y\n");
else printf("X<Y\n");
else
printf("X==Y\n");
}
运行,Enter integer x,y:12,23?
X<Y
Enter integer x,y:12,6?
X>Y
Enter integer x,y:12,12?
X==Y
if ~ else 配对原则,缺省 { }时,else总是和它上面离它最近的未配对的 if配对
if(……)
if(……)
if(……)
else…...else…...
else…...
例,if (a==b)
if(b==c)
printf(“a==b==c”);
else
printf(“a!=b”);
修改,if (a==b)
{ if(b==c)
printf(“a==b==c”);
}
else
printf(“a!=b”);
实现 if ~ else 正确配对方法:加 { }
例 考虑下面程序输出结果,
main()
{ int x=100,a=10,b=20;
int v1=5,v2=0;
if(a<b)
if(b!=15)
if(!v1)
x=1;
else
if(v2) x=10;
x=-1;
printf(“%d”,x);
}
结果,-1
switch语句 ( 开关分支语句 )
一般形式,switch( 表达式 )
{ case E1:
语句组 1;
break;
case E2:
语句组 2;
break;
…….
case En:
语句组 n;
break;
[default:
语句组 ;
break;]
}
执行过程,
switch
表达式语句组 1 语句组 2 语句组 n 语句组…...
E 1 E 2 En default
case
说明:
E1,E2,… En是 常量表达式,且值必须互不相同
语句标号作用,必须用 break跳出
case后可包含多个可执行语句,且不必加 { }
switch可嵌套
多个 case可共用一组执行语句如,……
case?A?:
case?B?:
case?C?,
printf(“score>60\n”);
break;
……..
例 switch(score)
{ case 5,printf(“Very good!”);
case 4,printf(“Good!”);
case 3,printf(“Pass!”);
case 2,printf(“Fail!”);
default,printf(“data error!”);
}
运行结果,score为 5时,输出:
Very good! Good! Pass! Fail! data error!
例 void main()
{ int x=1,y=0,a=0,b=0;
switch(x)
{ case 1:
switch(y)
{ case 0,a++; break;
case 1,b++; break;
}
case 2,a++;b++; break;
case 3,a++;b++;
}
printf(“\na=%d,b=%d”,a,b);
} 运行结果,a=2,b=1
/*ch4_5.c*/
#include <stdio.h>
main()
{ int c;
printf("Enter m or n or h or other:");
c=getchar();
switch(c)
{ case 'm',printf("\nGood morning!\n");break;
case 'n',printf("\nGood night!\n"); break;
case 'h',printf("\nHello!\n"); break;
default,printf("\n\n"); break;
}
}
例 根据输入字母输出字符串
4.5 循环型程序设计
概述
C语言可实现循环的语句:
用 goto 和 if 构成循环
while 语句
do ~ while 语句
for 语句
goto语句及用 goto构成循环
goto语句一般格式:
goto 语句标号 ;
….…..
标号:语句 ;
功能:无条件转移语句
说明:
不能用整数作标号
只能出现在 goto所在函数内,且唯一
只能加在可执行语句前面
限制使用 goto语句例 用 if 和 goto语句构成循环,求
/*ch5_1.c*/
#include <stdio.h>
main()
{ int i,sum=0;
i=1;
loop,if(i<=100)
{ sum+=i;
i++;
goto loop;
}
printf("%d",sum);
}
sum=0+1
sum==1+2=3
sum=3+3=6
sum=6+4
……
sum=4950+100=5050
循环初值循环终值循环变量增值循环条件循环体例 从键盘输入一组数据,以 0结束输入,求数据和
#include <stdio.h>
main()
{ int number,sum=0;
read_loop,scanf("%d",&number);
if(!number) goto print_sum;
sum+=number;
goto read_loop;
print_sum,printf("The total sum is %d\n",sum);
}
while语句
一般形式,
while(表达式 )
循环体语句;
执行流程,
expr
循环体假 (0)
真 (非 0)
while
特点:先判断表达式,后执行循环体
说明:
循环体有可能一次也不执行
循环体可为任意类型语句
下列情况,退出 while循环
条件表达式不成立(为零)
循环体内遇 break,return,goto
无限循环,while(1)
循环体 ;
例 用 while循环求
/*ch5_2.c*/
#include <stdio.h>
main()
{ int i,sum=0;
i=1;
while(i<=100)
{ sum=sum+i;
i++;
}
printf("%d",sum);
}
循环初值循环终值循环变量增值循环条件循环体例 显示 1~10的平方
/*ch5_21.c*/
#include <stdio.h>
main()
{ int i=1;
while(i<=10)
{ printf("%d*%d=%d\n",i,i,i*i);
i++;
}
}
运行结果:
1*1=1
2*2=4
3*3=9
4*4=16
5*5=25
6*6=36
7*7=49
8*8=64
9*9=81
10*10=100
do~while语句
一般形式,do
循环体语句;
while(表达式 );
执行流程,
do
循环体
expr
假 (0)
真 (非 0) while
特点:先执行循环体,后判断表达式
说明:
至少执行一次循环体
do~while可转化成 while结构
expr
循环体假 (0)
真 (非 0)
循环体
While循环例 用 do~while循环求
/*ch5_3.c*/
#include <stdio.h>
main()
{ int i,sum=0;
i=1;
do
{ sum+=i;
i++;
}while(i<=100);
printf("%d",sum);
}
例 while和 do~while比较
/*ch5_4.c*/
#include <stdio.h>
main()
{ int i,sum=0;
scanf("%d",&i);
do
{ sum+=i;
i++;
}while(i<=10);
printf("%d",sum);
}
main()
{ int i,sum=0;
scanf("%d",&i);
while(i<=10)
{ sum+=i;
i++;
}
printf("%d",sum);
}
for语句
一般形式,for([expr1] ;[ expr2] ;[ expr3])
循环体语句;
执行流程,
expr2
循环体假 (0)
真 (非 0)
for
expr1
expr3
for语句一般应用形式,
for(循环变量赋初值;循环条件;循环变量增值 )
{
循环体语句;
}
说明:
for语句中 expr1,expr2,expr3 类型任意,都可省略,但分号;不可省
无限循环,for(;;)
for语句可以转换成 while结构
expr1;
while(expr2)
{
循环体语句;
expr3;
}
例 用 for循环求
#include <stdio.h>
main()
{ int i,sum=0;
for(i=1;i<=100;i++)
sum+=i;
printf("%d",sum);
}
例,#include<stdio.h>
main( )
{ int i=0;
for(i=0;i<10;i++)
putchar(?a?+i);
}
运行结果,abcdefghij
例,#include<stdio.h>
main( )
{ int i=0;
for(;i<10;i++)
putchar(?a?+i);
}
例,#include<stdio.h>
main( )
{ int i=0;
for(;i<10;)
putchar(?a?+(i++));
}
例,#include<stdio.h>
main( )
{ int i=0;
for(;i<10;putchar(?a?+i),i++);
}
main()
{ int i,j,k;
for(i=0,j=100;i<=j;i++,j--)
{ k=i+j;
printf("%d+%d=%d\n",i,j,k);
}
}
#include<stdio.h>
main()
{ char c;
for(;(c=getchar())!='\n';)
printf("%c ",c);
}
#include <stdio.h>
main()
{ int i,c;
for(i=0;(c=getchar())!='\n';i+=3)
printf("%c ",i+c);
}
例 ( f0r)梯形法求数值积分
0
y
xa a+h a+ih a+(i+1)h b
f(x)
循环的嵌套
三种循环可互相嵌套,层数不限
外层循环可包含两个以上内循环,但不能相互交叉
嵌套循环的执行流程
(1) while()
{ ……
while()
{ ……
}
…...
}
(2) do
{ ……
do
{ ……
}while( );
…...
}while( );
(3) while()
{ ……
do
{ ……
}while( );
…….
}
(4) for( ; ;)
{ ……
do
{ ……
}while();
……
while()
{ ……
}
…...
}
内循环外循环内循环
嵌套循环的跳转禁止:
从外层跳入内层
跳入同层的另一循环
向上跳转例 循环嵌套,输出九九表
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
9 18 27 36 45 54 63 72 81
……………..
i
j
i<10
printf
假 (0)
真 (非 0)
i=1
j++
j=1
j<10
真 (非 0)
假 (0)
i++
for(i=1;i<10;i++)
for(j=1;j<10;j++)
printf((j==9)?"%4d\n":"%4d",i*j);
例 循环嵌套,输出九九表
i
j
/*ch5_5.c*/
#include <stdio.h>
main()
{ int i,j;
for(i=1;i<10;i++)
printf("%4d",i);
printf("\n---------------------------------------\n");
for(i=1;i<10;i++)
for(j=1;j<10;j++)
printf((j==9)?"%4d\n":"%4d",i*j);
}
4.6 辅助控制语句
break语句
功能:在循环语句和 switch语句中,终止并跳出循环体或开关体
说明:
break只能 终止并跳出 最近一层 的结构
break不能用于循环语句和 switch语句之外的任何其它语句之中
expr
……
break;
……
假 (0)
真 (非 0)
while
do
……
break;
…...
expr
假 (0)
真 (非 0) while
expr2
……
break;
…...
假 (0)
真 (非 0)
for
expr1
expr3
switch
expr
语句组 1
break;
语句组 2
break;
语句组 n
break;
语句组
break;
…...
const 1 const 2 const n default
case
例 break举例:输出圆面积,面积大于 100时停止
#define PI 3.14159
main()
{
int r;
float area;
for(r=1;r<=10;r++)
{ area=PI*r*r;
if(area>100)
break;
printf("r=%d,area=%.2f\n",r,area);
}
}
例 break举例:
小写字母转换成大写字母,直至输入非字母字符
#include <stdio.h>
main()
{
int i,j;
char c;
while(1)
{ c=getchar();
if(c>='a' && c<='z')
putchar(c-'a'+'A');
else
break;
}
}
4.6.2 continue语句
功能:结束本次循环,跳过 循环体中 尚未执行的语句,进行下一次是否执行循环体的判断
仅用于循环语句中
expr
……
continue;
……
假 (0)
真 (非 0)
while
真 (非 0)
do
……
continue;
…...
expr
假 (0)
while
expr2
……
continue;
…...
假 (0)
真 (非 0)
for
expr1
expr3
例 求输入的十个整数中正数的个数及其平均值
#include <stdio.h>
main()
{ int i,num=0,a;
float sum=0;
for(i=0;i<10;i++)
{ scanf("%d",&a);
if(a<=0) continue;
num++;
sum+=a;
}
printf("%d plus integer's sum,%6.0f\n",num,sum);
printf("Mean value:%6.2f\n",sum/num);
}
例 4.21,例 4.22,例 4.22、例 4.22
程序举例,求 =1-+-+…
t=1,pi=0,n=1.0,s=1
当 |t|?1e-6
pi=pi+t
n=n+2
s=-s
t=s/n
pi=pi*4
输出 pi
分子,1,-1,1,-1…
分母,1,3,5,7,...
例 求 Fibonacci数列,1,1,2,3,5,8,…… 的前 40个数
f1=1,f2=1
for i=1 to 20
输出 f1,f2
f1=f1+f2
f2=f2+f1
1
5
34
233
1597
10946
75025
514229
3524578
24157817
1
8
55
377
2584
17711
121393
832040
5702887
39088169
2
13
89
610
4181
28657
196418
1346269
9227465
63245986
3
21
144
987
6765
46368
317811
2178309
14930352
102334155
例 判断 m是否素数 读入 m
k=?m
i=2
当 i?k
m被 i整除真 假用 break
结束循环
i=i+1
i?k+1真 假输出,m”是素数,输出,m”不 是素数,
例 译密码例如 Hello,world!
译成密码,Lipps,asvph!