第四章 C程序流程设计
§ 4.1 C语句概述
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.2 程序的三种基本结构
结构化程序设计
基本思想:任何程序都可以用三种基本结构表示,限制使用无条件转移语句( goto)
结构化程序:由三种基本结构反复嵌套构成的程序叫
~
优点:结构清晰,易读,提高程序设计质量和效率
三种基本结构
顺序结构
A
B
A
B
流程图 N-S图
P
A B
真 假 P
BA
真 假
选择结构
k
A1 A2 Ai An
k=k2k=k1
k=kn
k=ki
...,..
二分支选择结构
多分支选择结构
循环结构
当型循环结构
直到型循环结构
P
A
假真当 P为真
A
A
P
真假
A
直到 P为真注,A,B,A1….An 可以是一个简单语句,也可以是一个基本结构
§ 4.3 选择型程序设计
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
运行,t t,8?
t i digi
运行,Enter a character,D?
The character is a capital letter
运行,Enter a character,h
he character is a lower let er
运行,Enter a ch racter,F1?
The character 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.4 循环型程序设计
概述
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结束输入,求数据和
/*ch5_11.c*/
#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()
{ ……
}
…...
}
内循环外循环内循环
嵌套循环的跳转禁止:
从外层跳入内层
跳入同层的另一循环
向上跳转
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);
外循环内循环
§ 4.5 辅助控制语句
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;
}
}
continue语句
功能:结束本次循环,跳过 循环体中 尚未执行的语句,进行下一次是否执行循环体的判断
仅用于循环语句中
expr
……
continue;
……
假 (0)
真 (非 0)
while
真 (非 0)
do
……
continue;
…...
expr
假 (0)
while
expr2
……
continue;
…...
假 (0)
真 (非 0)
for
expr1
expr3
例 求输入的十个整数中正数的个数及其平均值
/*ch5_12.c*/
#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);
}
程序举例
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!