第二章 程序基本结构
2.1 分支结构
2.2 关系运算和逻辑运算
2.3 循环结构
2.4 break和 continue语句
2.6 经典算法举例
2.1 分支结构
分支结构的引入
请编程求解分段函数,
-1 x<0
0 x=0
1 x>0
y =
顺序结构只能解决一些简单的问题,遇到需要进行条件判断的问题,就必须采用分支结构来处理。
请输出 2个数中的较大的数。
根据“体指数”判断某人的肥胖程度:
体指数 t= w / h2,其中,w—体重 (千克 ),h—身高 (米 )
t<18 低体重 (偏瘦 )
t>=18 & t<25 正常体重
t>=25 & t<27 高体重 (偏胖 )
t>=27 肥胖
2.1.1 单分支结构
1、语法形式,
if ( 表达式 ) 语句
2、执行过程,
先计算表达式的值,
若为真 (非 0值 ),则执行其后的语句,
若值为 0,则继续向下执行语句真
P
P
A
真 (非 0)
假 (0)
2.1.1 单分支结构例 2-1,输入 2个整数,按由小到大的顺序输出
#include <stdio.h>
void main( )
{ int a,b,t;
printf(,input a,b:,);
scanf(“%d %d”,&a,&b);
if (a>b)
{ t=a;
a=b;
b=t;
}
printf(“%d,%d\n”,a,b);
}
输入 a,b
t=a
a>b?
输出 a,b
真 假
a=b
b=t
例 2-2,输入 3个整数,按由小到大的顺序输出输入 a,b,c
输出 a,b,c
a>b?
ab
真 假
a>c?
ac
真 假
b>c?
bc
真 假
#include <stdio.h>
void main( )
{ int a,b,c,t;
printf(,input a,b,c:,);
scanf(“%d%d%d”,&a,&b,&c);
if (a>b)
{ t=a; a=b; b=t; }
if (a>c)
{ t=a; a=c; c=t; }
if (b>c)
{ t=b; b=c; c=t; }
printf(“%d,%d,%d\n”,a,b,c);
}
2.1.1 单分支结构
1、语法形式,
if ( 表达式 ) 语句 1
else 语句 2
2、执行过程,
先计算表达式的值,若为真 (非 0值 ),执行语句 1;
若值为 0,执行 else后的语句 2
语句 1 语句 2
真 假
P
2.1.2 双分支结构
P
A B
真 (非 0) 假 (0)
2.1.2 双分支结构例 2-3,输入 2个整数,请输出其中的较大的数输入 x,y
x>=y?真 假输出 x 输出 y
#include <stdio.h>
void main( )
{ int x,y;
printf(,input x,y:,);
scanf(“%d%d”,&x,&y);
if (x>=y)
printf(“max=%d\n”,x);
else
printf(“max=%d\n”,y);
}
#include <stdio.h>
#include <math.h>
void main( )
{ int x,y;
printf(,input x:,);
scanf(“%d”,&x);
if (x<=0) y=0;
else y=pow(x,3)+x+1;
printf(“y=%d\n”,y);
}
输入 x
输出 y
x<=0?
y=0
真 假
y=x3+x+1
2.1.2 双分支结构例 2-4:编程求解函数 0 X<=0
X3+X+1 X>0Y=
2.1.4 if语句的嵌套
if 的嵌套,在 if 语句中又包括一个或多个 if 语句
嵌套的作用,对复杂条件进行判断,实现多分支选择
嵌套的形式多种多样
1,if (表达式 1)
if (表达式 2) 语句
2,if (表达式 1) 语句 1
else if (表达式 2) 语句 2
3,if (表达式件 1) 语句 1
else if (表达式 2) 语句 2
else 语句 3
4,if① (表达式 1)
if② (表达式 2) 语句 1
else 语句 2
(1) if① (表达式 1)
{ if ② (表达式 2) 语句 1
else② 语句 2
}
(2) if① (表达式 1)
{ if② (表达式 2) 语句 1 }
else① 语句 2
对第 4种形式可以有两种理解方式,
规定,在 if 嵌套结构中,
else是与其前面最近的尚未配对的 if 配对
2.1.4 if语句的嵌套例 2-5,编程求解分段函数,
-1 x<0
0 x=0
1 x>0
y =
方法 1
if (x<0) y=-1;
else if (x==0) y=0;
else y=1;
方法 3
if (x>=0)
if (x>0) y=1;
else y=0;
else y=-1;
方法 4
y=-1;
if (x!=0)
{ if(x>0) y=1; }
else y=0;
方法 2
if (x==0) y=0;
else if (x<0) y=-1;
else y=1;
2.1.4 if语句的嵌套
2.1.4 if语句的嵌套例 2-6 判断某人的肥胖程度,体指数 t= w / h2
w-体重 (千克 ),h-身高 (米 )
t<18 低体重 (偏瘦 )
t>=18 & t<25 正常体重
t>=25 & t<27 高体重 (偏胖 )
t>=27 肥胖输入 w,h
计算 t=w/(h*h)
输出低体重 输出正常体重输出高体重输出肥胖
t<18?真 假
t<25?真 假
t<27?真 假
#include<stdio.h>
void main( )
{ float t,w,h;
scanf(“%f%f”,&w,&h);
t=w/(h*h); printf(“t=%f,,t);
if(t<18)
printf(“lower weight!\n”);
else
if(t<25)
printf(“normal weight!\n”);
else
if(t<27)
printf(“higher weight!\n”);
else
printf(“too fat!\n”);
}
2.1.5 条件运算符
1、条件运算符?,( 唯一的三目运算符 )
优先级仅高于赋值类,是右结合性
3、执行过程,
先计算表达式 1,
若表达式 1的值为真 (非 0),则计算表达式 2的值,
该条件表达式的值即为表达式 2 的值 ;
若表达式 1的值为假 (零 ),则计算表达式 3 的值,
该条件表达式的值即为表达式 3 的值
2、条件表达式的一般形式,
表达式 1? 表达式 2,表达式 3
例 max=a>b? a,b+1
a>b? a,c>d? c,d
注意,
(1)表达式 1,表达式 2和表达式 3 的数据类型可以不相同
(2) 条件表达式的值的数据类型与表达式 2,表达式 3中数据类型较高的那个保持一致如 7>5? 10,1.4 条件表达式的值为 10.0
a>b? a,(c>d? c,d )
max=(a>b? a,b+1)
2.1.5 条件运算符用条件表达式实现
#include<stdio.h>
void main( )
{ int max;
max=x>y? x,y ;
max=z>max? z,max;
printf(“max=%d”,max);
}
当 if 中的语句为简单赋值语句时,
可以用条件表达式来取代 if 语句例 求 3个数中的最大数
#include<stdio.h>
void main( )
{ int max;
if (x>y) max=x;
else max=y;
if (z>max) max=z;
printf(“max=%d”,max);
}
2.1.5 条件运算符
2.1.6 switch语句
请将输入的百分制成绩,转换成五分制成绩输出,
转换标准如下:
grade =
A 90≤ s ≤100
B 80≤ s < 90
C 70≤ s < 80
D 60≤ s < 70
E 0≤ s < 60
对于这种类型的问题,需要讨论的情况比较多,
如果用 if 嵌套的层次会比较多,程序可读性不好,
这时通常会使用多分支选择语句 switch
2.1.6 switch语句
1,switch语句的格式
switch ( 表达式 )
{ case 常量表达式 1,语句 1; [break;]
case 常量表达式 2,语句 2; [break;]
:,,
case 常量表达式 n,语句 n; [break;]
[ default,语句序列 n+1 ]
} 注意,(1) switch后的表达式一般多为整型或字符型表达式
(2) case后常量表达式的值必须互不相同
(3) 语句 1至语句 n+1为多条语句时可省略 { }
(4) 多个 case可以共用一组执行语句
(5) switch语句可以嵌套
[…] 代表可选项
2.1.6 switch语句
2,switch的执行过程 ( 语句 1--语句 n后没使用 break; )
switch ( 表达式 )
{ case 常量表达式 1,语句 1;
case 常量表达式 2,语句 2;
:,,
case 常量表达式 n,语句 n;
default,语句 n+1;
}
(1) 计算 switch后表达式的值
(2) 如果表达式的值与某个
case常量表达式的值相等时,
就执行此 case后的语句,执行完后将继续执行下一个 case
后的语句,如果表达式的值与所有 case常量表达式的值都不同,就执行 default后的语句,
执行后结束整个 switch语句
2.1.6 switch语句例 void main ( )
{ int x,y ;
scanf(“%d”,&x) ;
switch (x)
{ case 1,y=10 ; printf(“%d\n”,y) ;
case 2,y=20 ; printf(“%d\n”,y) ;
case 3,y=30 ; printf(“%d\n”,y) ;
default,y=0 ; printf(“%d\n”,y) ;
}
} 注意,switch中没有使用 break;
输入 x为 2
输出,20
30
0
输入 x为 6
输出,0
2.1.6 switch语句注意,执行一个 case 分支后,应用 break结束 switch语句
void main ( )
{ int x,y ;
scanf(“%d”,&x) ;
switch (x)
{ case 1,y=10 ; printf(“%d\n”,y) ; break;
case 2,y=20 ; printf(“%d\n”,y) ; break;
case 3,y=30 ; printf(“%d\n”,y) ; break;
default,y=0 ; printf(“%d\n”,y) ;
}
}
输入 x为 2
输出,20
2.1.6 switch语句例 2-7 将输入的百分制成绩 s,转换成五分制成绩输出
#include<stdio.h>
void main( )
{ int s;
printf(“input s:”);
scanf(“%d”,&s);
switch(s/10)
{ case 10:
case 9,printf(“grade is A”); break;
case 8,printf(“grade is B”); break;
case 7,printf(“grade is C”); break;
case 6,printf(“grade is D”); break;
default,printf(“grade is E”);
}
}
两个 case共用一组执行语句
grade =
A 90≤ s ≤100
B 80≤ s < 90
C 70≤ s < 80
D 60≤ s < 70
E 0≤ s < 60
2.2 关系运算和逻辑运算注意,(1) 字符数据按其 ASCII码值进行比较
(2) 应避免 2个实数作 = = 或 != 的比较一、关系运算符 > >= < <= == !=
1、优先级,低于纯算术类,高于赋值类
2、结合性,左结合性二、关系表达式,用关系运算符连接起来的式子关系表达式的值只有 2个,1 表示真,0 表示假注意,(3) 5>2>7>8 是允许的,它相当于 ((5>2)>7)>8
(4) 可以将关系表达式看成是一种整型表达式三,逻辑运算符 ! && ||
1,3个运算符的优先级由高到低为,!? &&? ||
2,! 的优先级高于关系运算,&&和 || 的优先级低于关系运算
3,! 是右结合性,&& 和 || 是左结合性,
四、逻辑表达式
1、逻辑表达式的值应该是,逻辑真,或,逻辑假,,
逻辑运算的结果以数值 1代表“真”,以数值 0代表
“假” ;
进行判断时,非零值代表“真”,零值代表“假”例,表示 x∈ [-1,1]区间 应写为,x>= -1 && x<=1
2.2 关系运算和逻辑运算
2,逻辑运算中的规律
(1) 在 && 表达式中,若左端为 0,则不必再计算右端,
表达式值为 0 即,0 && a == 0
(2) 类似有 1 || a == 1
规律,
0||a ==a 0&&a==0
1||a==1 1&&a==a
a||a==a a&&a==a
a||!a==1 a&&!a==0
!(a||b)==!a&&!b !(a&&b)==!a||!b
2.2 关系运算和逻辑运算例 #include <stdio.h>
void main( )
{ int x,y,z ;
x = y = z = 0 ;
++x || ++y && ++z ;
printf(“%d,%d,%d\n”,x,y,z);
x = y = z = -1 ;
++x && ++y || ++z ;
printf(“%d,%d,%d\n”,x,y,z);
}
(++x) || ( (++y)&&(++z) )
输出结果,
1,0,0
0,-1,0
(++x) && (++y) || (++z)
2.2 关系运算和逻辑运算
2.3 循环结构
程序设计的三种基本结构是什么?
①顺序结构 ②选择结构 ③循环结构
A
B
A
B
P
A B
成立 不成立
A B
成立 不成立
P
不成立
A
P 成立
A
P 成立不成立
A
当 P成立直到 P不成立
A
“当型”循环
“直到型”循环请编程求解以下 2个问题:
1、请在屏幕上输出 20行星号,每行星号由 8个 *组成。
2、请输出 1—200之间的所有偶数。
#include<stdio.h>
void main( )
{ printf("********\n");
printf("********\n");
printf("********\n");
printf("********\n");
}
… …
20

#include<stdio.h>
void main( )
{ printf("2,4,6,8,10,");
printf(“12,14,16,18,20,");
printf(“22,24,26,28,30,");
printf(“192,……,200");
}
… …
2.3 循环结构
#include<stdio.h>
void main( )
{
printf("********\n");
printf("********\n");
printf("********\n");
}
… …
1、什么是循环?
简单的讲,循环就是重复做一件事。
重复部分
printf("********\n");
int i ; // 用 i作计数器
i=1;
while ( i<=20 )
i=i+1;
{
}
#include<stdio.h>
void main( )
{
} 希望重复部分只写一次,
让程序控制它重复执行
20次,怎么实现呢?
2.3.1 循环概述例 2-8:输出 20行星号
2.3.1 循环概述例 2-9:输出 1—200之间的所有偶数
#include<stdio.h>
void main( )
{ printf("2,4,6,8,10,");
printf(“12,14,16,18,20,");
printf(“22,24,26,28,30,");
printf(“192,……,200");
}
… …
#include<stdio.h>
void main( )
{ int i ;
i=1;
while ( i<=20 )
{ printf(" * * * * * *\n");
i=i+1;
}
}
i %d,",i );
i=2;
( i<=200 )
+2
2、循环语句
C语言中的循环语句有三种:
while语句
do-while语句
for语句
while循环是“当型”循环,当条件满足时执行循环体语句,条件不满足时结束循环
do-while循环是“直到型”循环,先执行循环体语句,再判断条件是否满足,
直到条件不满足时结束循环
for循环的功能强大,使用最为广泛它完全可以代替 while循环
2.3.1 循环概述循环体
#include<stdio.h>
void main( )
{ int i ;
i=1;
while ( i<=20 )
{ printf(" * * * * * *\n");
i++;
}
}
1,while的语法格式
while ( 表达式 )
循环体语句 ;
表达式2、执行过程,
先计算表达式的值,
值为真时执行循环体,
值为假时结束循环
A
当 P成立
A
P 成立不成立
2.3.2 while 循环
表达式中使用的循环控制变量必须赋初值
表达式必须用 ( ) 括起来
循环体为多条语句时,必须用 { }把它们括起来
循环体中必须有使循环趋向结束的语句
i=1;
while ( i<=20 )
{ printf(" * * * * * *\n");
i++;
}
循环控制变量 i 赋初值为 1
表达式加小括号使循环趋向结束的语句
3、使用 while语句要注意四点,
2.3.2 while 循环
4、程序举例例 2-10,求 1+2+3+…+100 的和分析,①程序可分为几个步骤?
②输入,输出是什么?
③怎样用循环实现?
②需要输入 1,2,3…100 吗?
这些数有规律,可以让程序自动产生,
所以不需要进行输入输出计算结果
① 程序一般可以分三个步骤,
⑴ 输入数据,或进行数据初始化
⑵ 对数据进行计算、处理
⑶ 输出结果
2.3.2 while 循环
③两数相加是重复做的
3?1+2;
6?3+3;
10?6+4
1?0+1;? =? +? ;
=sum+i ;
被加数需要一个变量,设为 i=1
加数需要一个变量,设为 sum=0
是否需要设一个循环控制变量?
i=i+1;
sum
#include <stdio.h>
void main ( )
{ int i,sum;
sum=0;
i=1;
while ( i<=100 )
{ sum=sum+i ;
i++;
}
printf(“sum=%d\n”,sum);
}
sum=0
i=1
i<=100?
sum=sum+i
i=i+1
输出 sum的值变量 i一方面用来控制循环次数,同时又作为求和运算中的一个运算对象例 2-10的 N-S图:
例 2-10的程序代码:
2.3.2 while 循环
sum=0
i=1
sum=sum+i
i=i+1
输出 sum的值
i<=100?
例 2-11,求 1—n 的和,n为任意正整数,从键盘输入
<=n?
输入 n
#include <stdio.h>
void main ( )
{ int i,sum,n ;
sum=0;
i=1;
scanf(“%d”,&n);
while (i<=n)
{ sum=sum+i;
i++;
}
printf(“sum=%d\n”,sum);
}
2.3.2 while 循环例 2-12,求某个班英语成绩的平均分,该班学生人数和每个学生的成绩由键盘输入分析,
题目的主体结构还是累加求和,不同之处在于累加项不是规律变化的整数,而是学生成绩,每个成绩都可能是不同的
若用 n来表示人数,则输入 n就是输入学生人数
思考:学生成绩需要定义几个变量?
因为 n个学生的成绩之和是通过 n次循环相加得到的,所以可以把“输入成绩”这个步骤放在循环体中,先输入成绩,
再进行加法计算,因此只需定义一个变量 s来保存成绩
最后用 sum除以人数 n就可以得到平均分
2.3.2 while 循环
sum=0
i=1
i<=n?
sum=sum+i
i=i+1
输出 sum值输入 n (n表示人数 )
#include <stdio.h>
void main ( )
{ int i,n ;
float s,sum,ave ;
sum=0; i=1;
scanf(“%d”,&n);
while (i<=n)
{ scanf(“%f,,&s);
sum=sum+s ;
i++ ;
}
ave=sum/n ;
printf(“ave=%6.2f\n”,ave);
}
输入 s (s表示成绩 )
ave=sum/n
s
例 2-12的 N-S图:例 2-12程序代码:
注意变量的类型
ave
2.3.2 while 循环
#include <stdio.h>
#include <conio.h>
void main ( )
{ int i,n ; float s,sum,ave ;
sum=0; i=1;
printf(" please input the number of students:");
scanf("%d",&n);
printf(" please input %d student's score:",n);
while (i<=n)
{ scanf("%f",&s);
sum=sum+s ; i++ ;
}
ave=sum/n ; printf(" ave=%6.2f\n",ave);
getch( );
}
//为了程序使用方便添加一些语句
//提示用户输入学生人数
//提示用户输入 n个学生的成绩
// 该函数的作用是读入一个从键盘输入的字符,但不显示该字符使用它方便用户查看输出结果,用户按任意键时返回编辑环境
//因要使用 getch( ),所以必须包含该头文件
2.3.2 while 循环例 2-13,设计一个歌唱比赛的计分程序,有 10名专家给歌手打分,
歌手的最终成绩为去掉一个最高分和一个最低分的平均分分析,
程序总体思路:将 10个成绩累加求和,设法找出最高分和最低分,从总分中减去最高分和最低分,再除 8得到平均分
如何确定最高分和最低分?
可以设置两个变量 max和 min分别存放最高分和最低分,
输入一个成绩 s后,把 s与 max,min比较,更新 max和 min的值
(思考,这个步骤应放在程序的什么位置?)
max和 min是否要赋初值?
max和 min应该赋初值,并且 max=0; min=10;
2.3.2 while 循环
i<=10?
i=i+1
输出 ave的值输入 s (s表示成绩 )
sum=sum+s
i=1,sum=0
ave=sum/8
#include <stdio.h>
void main( )
{ int i=1;
float s,min,max,sum,ave ;
sum=0; max=0; min=10;
while (i<=10)
{ scanf(“%f”,&s);
if (s>max) max=s;
if (s<min) min=s;
sum=sum+s ;
i++ ;
}
sum=sum-max-min;
ave=sum/8 ;
printf(“ave=%6.2f\n”,ave);
}
max=0,min=10
s>max?
max=s
yes no
s<min?
min=s
yes no
sum=sum-max-min
例 2-13的 N-S图:例 2-13程序代码:
2.3.3 do-while 循环不成立
A
P 成立
1,do-while 的语法格式,
do
循环体语句
while (表达式 ) ;
2、执行过程,先执行循环体,然后计算表达式的值,
若值为真则重复执行循环体,若值为假则结束循环
3、使用 do-while要注意,
表达式中使用的循环控制变量必须赋初值
表达式必须用 ( ) 括起来
循环体语句为多条语句时,必须用 { }把它们括起来
循环体语句中必须有使循环趋向结束的语句直到 P不成立
A
2.3.3 do-while 循环例 2-14,用 do-while语句实现求 1—100 的和
#include <stdio.h>
void main ( )
{ int i,sum;
sum=0;
i=1;
do
{ sum=sum+i;
i++;
} while (i<=100) ;
printf(“sum=%d\n”,sum);
}
sum=0
i=1
i<=100?
sum=sum+i
i=i+1
输出 sum的值
s =0
i=1
i<=100?
sum=sum+i
i=i+1
输出 sum的值
2.3.3 do-while 循环
4,while循环和 do-while循环的比较
while do-while
(1)先判断条件再执行循环体 先执行循环体再判断条件
(2)循环体可能一次也不执行 至少执行一次循环体
void mian( )
{ int sum=0,i ;
scanf(“%d”,&i );
while (i<=10)
{ sum=sum+i ;
i++ ;
}
printf(”%d\n”,sum);
}
void mian( )
{ int sum=0,i ;
scanf(“%d”,&i );
do
{ sum=sum+i ;
i++ ;
} while (i<=10) ;
printf(”%d\n”,sum);
}若输入 i值为 11
则输出,0
若输入 i值为 11
则输出,11
2.3.4 for 循环
sum=0;
i=1;
while(i<=100 )
{ sum=sum+i ;
i++ ;
}
sum=0;
for ( i=1 ; i<=100 ; i++)
sum=sum+i ;
例,将 1—100求和的 while循环转换为用 for循环实现
1,for 的语法格式,
for (表达式 1 ; 表达式 2 ; 表达式 3)
循环体语句 ;
2、执行过程,
(1) 计算表达式 1 (只执行一次 )
(2) 计算表达式 2,
若值为真则执行循环体,
再执行第 (3)步 ;
若值为假则结束循环
(3) 计算表达式 3,
再重复执行第 (2)步
2.3.4 for 循环例 2-15 求正整数 n的阶乘 n!,n由键盘输入
fact=1
i=1
i<=n?
输出 fact的值
#include <stdio.h>
void main( )
{ int n,i ; float fact;
printf(“input n:”);
scanf(“%d”,&n);
fact=1;
for ( i=1 ; i<=n ; i++ )
fact=fact*i;
printf(“%,0f \n”,fact);
}
fact=fact*i
i=i+1
输入 n
2.3.4 for 循环例 2-16,用 for语句实现求某个班英语成绩的平均分
#include <stdio.h>
void main ( )
{ int i,n ;
float s,sum=0,ave ;
scanf(“%d”,&n);
i=1;
while ( i<=n )
{ scanf(“%f”,&s);
sum=sum+s ;
i++ ;
}
ave=sum/n ;
printf(“%6.2f\n”,ave);
}
#include <stdio.h>
void main ( )
{ int i,n ;
float s,sum=0,ave ;
scanf(“%d”,&n);
ave=sum/n ;
printf(“%6.2f\n”,ave);
}
for ( i=1; i<=n ; i++ )
{ scanf(“%f”,&s);
sum=sum+s ;
}
2.3.4 for 循环例 2-17,求 Fibonacci数列 1,1,2,3,5,8,… 的前 20 个数
#include <stdio.h>
void main( )
{ int i,f1,f2,f3;
f1=1; f2=1;
printf(“%8d%8d”,f1,f2);
for ( i=3 ; i<=20 ; i++ )
{ f3=f1+f2;
f1=f2;
f2=f3;
printf(“%8d”,f3);
if ( i%4==0)
putchar(?\n?);
}
}
分析数列的规律,
从第 3个数开始,每个数是其前两个数之和
f1
f2
f3
1
1
2
2
3
2
3
5+
输出结果,
1 1 2 3
5 8 13 21
34 55 89 144
233 377 610 987
1597 2584 4181 6765
1f2
1f1
2.3.4 for 循环例,求 Fibonacci数列的前 40 个数
#include <stdio.h>
void main( )
{ int i ;
long int f1,f2;
f1=1; f2=1;
for ( i=1 ; i<=20 ; i++ )
{ printf(“%12ld%12ld”,f1,f2);
if ( i%2==0) putchar(?\n?);
f1=f1+f2;
f2=f2+f1;
}
}
方法:仅使用 f1和 f2这 2个变量
2
3
5
8
2.3.5 循环嵌套
几种循环的比较,
While Do-while for
循环变量初始化 写在循环之前 写在循环之前 写在表达式 1
循环条件 写在 while后的()内 写在 while后的()内 写在表达式 2
循环变量的修改 写在循环体内 写在循环体内 写在表达式 3
循环体 一般不能省略 一般不能省略 可省略,将对应操作写在表达式 2,3中执行过程 先计算表达式再执行循环体 先执行循环体再计算表达式 先计算表达式 1,2再执行循环体
2.3.5 循环嵌套
循环的嵌套,一个循环体内包含另一个完整的循环结构
按循环嵌套的层数分别称为二重循环,三重循环 …
C语言中 while,do-while,for循环可以互相嵌套例 2-18,输出由 * 组成的如图所示的矩形 *****
*****
*****
*****
方法 1:
#include <stdio.h>
void main( )
{ printf(“*****\n”);
printf(“*****\n”);
printf(“*****\n”);
printf(“*****\n”);
}
方法 2:
#include <stdio.h>
void main( )
{ int j;
for( j=1; j<=4; j++)
printf(“*****\n”);
}
2.3.5 循环嵌套方法 3:
#include <stdio.h>
void main( )
{ int i,j ;
i=1;
while (i<=4)
{ for (j=1; j<=5; j++)
printf(“*”);
printf(“\n”);
i++;
}
}
方法 4:
#include <stdio.h>
void main( )
{ int i,j ;
for( i=1; i<=4; i++)
{ for (j=1; j<=5; j++)
printf(“*”);
printf(“\n”);
}
}
控制行数控制每行的 *个数注意,内外层循环的控制变量不能重名但并列循环的控制变量无此限制
2.3.5 循环嵌套例 2-19,输出 *组成的直角三角形 *
**
***
****
#include <stdio.h>
void main( )
{ int i,j ;
for( i=1; i<=4; i++)
{ for (j=1; j<=i; j++)
putchar(?*?);
putchar(?\n?);
}
}
特点,第 i 行有 i个星号例 2-20,输出 9*9乘法表 1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
… …
9*1=9 9*2=18 9*3=27 … 9*9=81
#include <stdio.h>
void main( )
{ int i,j ;
printf(“\n”);
for( i=1; i<=9; i++)
{ for (j=1; j<=i; j++)
printf(“%d*%d=%-3d”,i,j,i*j);
printf(“\n”);
}
}
2.3.5 循环嵌套例 2-21,输出 *组成的等腰三角形 *
***
*****
*******
#include <stdio.h>
void main( )
{ int i,j,k ;
for ( i=1; i<=4 ; i++)
{
for ( k=1; k<=2*i-1 ; k++)
putchar(?*?);
putchar(?\n?);
}
}
特点,第 i 行有 2*i-1个星号控制星号的个数
2.3.5 循环嵌套
for ( j=1; j<=4-i ; j++)
putchar();
控制空格的个数若有 4行,则第 i 行的第 1个星号前有 4-i个空格例 2-22,输出如图所示的菱形
****
************
********
*
分析,
将图形分为上下两部分上半部分 (前 4行 )
每行的星号个数是 1,3,5,7
每行的空格个数是 3,2,1,0
下半部分 (后 3行 )
每行的星号个数是 5,3,1
每行的空格个数是 1,2,3
#include <stdio.h>
void main( )
{ int i,j,k ;
for ( i=1; i<=4 ; i++)
{ for ( j=1; j<=4-i ; j++)
putchar();
for ( k=1; k<=2*i-1 ; k++)
putchar(?*?);
putchar(?\n?);
}
for ( i=3; i>=1 ; i- -)
{ for ( j=1; j<=4-i ; j++)
putchar();
for ( k=1; k<=2*i-1 ; k++)
putchar(?*?);
putchar(?\n?);
}
}
2.3.5 循环嵌套
2.4 break和 continue语句
break语句,中止循环或 switch结构循环体
P1 真假语句 1
语句 2
P2 break;真假循环体语句 2
P1 真假语句 1
P2 真 continue;

continue语句,结束本次循环,然后再根据是否满足条件来决定是否执行下次循环
for(r =1 ;r <= 10 ; r++)
{ s = 3.14*r*r ;
if (s>100 && s<200 )
break;
printf(,s=%6.2f\n”,s);
}
for(r =1 ;r <= 10 ; r++)
{ s = 3.14*r*r ;
if (s>100 && s<200 )
continue;
printf(,s=%6.2f\n”,s);
}
输出结果,
s= 3.14
s= 12.56
s= 28.26
s= 50.24
s= 78.50
输出结果,
s= 3.14
s= 12.56
s= 28.26
s= 50.24
s= 78.50
s=200.96
s=254.34
s=314.00
2.4 break和 continue语句
2.4 break和 continue语句例 2-23,输入 30个字符,统计其中数字字符的个数
#include <stdio.h>
void main( )
{ int i,sum=0;
char ch;
for (i=1; i<=30; i++)
{ ch=getchar( );
if ( ch<'0' || ch>'9' )
continue;
sum++;
}
printf("%d\n",sum);
}
循环体
sum++
i<=30 真假输入一个字符
ch不是数字?
continue;

sum=0;
i=1;
i++
真例 2-23,不使用 continue 的一般方法
2.4 break和 continue语句
#include <stdio.h>
void main( )
{ int i,sum=0;
char ch;
for (i=1; i<=30; i++)
{ ch=getchar( );
if ( ch>='0' && ch<='9' )
sum++;
}
printf("%d\n",sum);
}
例 2-24:判断一个数 m是否为素数。
2.4 break和 continue语句解题思路:
让 m 被 2 到 √m 之间的任一整数除:
若 m 能被 2 ~ √m 之中的任何一个整数整除,则 m 不是素数,
提前结束循环,此时 i 必然小于或等于 √m ;
若 m 不能被 2 ~ √m 之间的任何一整数整除,则完成最后一次循环,此时 i = √m + 1。
在循环结束之后判断 i 的值是否大于或等于 √m + 1
若是,则表明 m未曾被 2 ~ √m 之间的任一整数整除过,因此是素数,输出结果 ; 否则,说明 m可以被 2 ~ √m 之间的某个整数整除,不是素数
2.4 break和 continue语句
#include <stdio.h>
#include <math.h>
void main( )
{ int m,i,k ;
scanf ( "%d",&m );
k = sqrt ( m+1 ) ;
for ( i=2; i <= k ; i++)
if ( m % i ==0) break;
if ( i >= k+1 )
printf ( " %d is a prime number ",m ) ;
else
printf ( " %d is not a prime number ",m ) ;
}
i从 2到 k依次判断是否能被 m整除若 m 整除 i,则结束循环,说明 i不是素数
2.6 经典算法举例例 2-25,公鸡 5文钱买 1只,母鸡 3文钱买 1只,小鸡 1文钱买 3只,
用 100文钱买 100只鸡,问公鸡、母鸡、小鸡各有几只?
分析:
假设用变量 x,y,z分别代表公鸡数、母鸡数、小鸡数,
根据题目描述可以列出以下两个方程,x+y+z=100
5x+3y+z/3=100?由方程 2可以确定 x,y,z的取值范围:
1≤ x < 20,1≤ y < 33,3≤ z < 100
为找出解答,需逐一验证 x,y,z的取值,看其是否满足条件,
x=1,y=1,z=3 z=99;z 变化
y=2,z=3 z=99;z 变化
y=32,z=3 z=99;z 变化
y 变化
x=2,z=3 z=99;
y=2,z=3 z=99;
y=32,z=3 z=99;
z 变化
z 变化
z 变化
y 变化
x=19,y=1,z=3 z= 9;
y=2,z=3 z= 9;
y=32,z=3 z= 9;
z 变化
z 变化
z 变化
y 变化
x,y,z这种有规律的变化可用循环嵌套实现第 1层的循环体第 2层的循环体
2.6 经典算法举例例 2-25 方法 1,用三层循环实现
#include <stdio.h>
void main( )
{ int x,y,z;
for (x=1; x<20; x++)
for (y=1; y<33; y++)
for (z=3; z<100; z+=3)
if (5*x+3*y+z/3==100 && x+y+z==100)
printf(“x=%d,y=%d,z=%d\n",x,y,z);
}
该方法的缺点,
最内层的 if语句要执行 19*32*33次需要考虑如何减少循环执行的次数
#include <stdio.h>
void main( )
{ int x,y,z;
for (z=3; z<100; z+=3)
{ x=4*z/3-100; y=100-x-z;
if(x>0&&y>0)
if (5*x+3*y+z/3==100 && x+y+z==100)
printf(“x=%d,y=%d,z=%d\n",x,y,z);
}
}
2.6 经典算法举例例 2-25 方法 2,用一层循环实现 x+y+z=100? y=100-x-z
5x+3y+z/3=100
5x+3(100-x-z)+z/3=100
x=4z/3-100
求 z? 求 x?求 y
因此只需要 z作循环变量
2.6 经典算法举例例 2-26 有一本书,撕掉了其中一页,已知剩余页码之和为 140,问这本书原来共有多少页?撕掉的是哪一页?
由此可以写出不定方程,s-x-(x+1)=140 其中
1≤x≤n-1且为奇数 。
分析:
书的页码总是从第 1页开始,每张纸的页码均为奇数开头,结束页未必是偶数,一页纸上有两个连续的页码。设为 x,x+1,由前面的分析知道 x为奇数。设 n
表示原书的页码数,总页码之和为 s,因为页码之和为 140,所以 n<20。
2.6 经典算法举例
#include <stdio.h>
void main()
{
int n=1,s=0,x;
clrsc(); /*清屏函数 */
do
{ s=s+n;
for(x=1;x<=n-1;x+=2)
if(s-x-(x+1)==140)
printf(“%d,%d,%d,%d”,n,s,x,x+1);
n++;
} while(n<=20);
}
这种算法也称为尝试法、枚举法,
其核心是全面排查,找出满足条件的所有情况。程序设计简单,
但只能解决有限情况的场合。
2.6 经典算法举例例 2-27 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第 10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少 桃子?
分析,
假设摘了 x1个桃子,第 1天吃了 x1/2 +1 个,则剩了 x1/2-1个,
如果用 x2表示剩下的桃子数 ( 即 x1/2-1 =x2 ),则 x1= (x2+1)*2
已知第 10天只有一个桃子,可以通过这个公式求出第 9天的桃子数,
再继续用公式求出第 8天的桃子数,…… 直至求出第 1天的桃子数,
这种方法称为 递推法,思路是根据题目的描述发现规律,写出递推公式,由此进行循环操作
2.6 经典算法举例
#include<stdio.h>
void main( )
{ int day,x1,x2;
day=9;
x2=1;
while(day>0)
{ x1=(x2+1)*2;
x2=x1;
day - -;
}
printf("the total is %d\n",x1);
}
第 10天,1
第 9天,(1+1)*2=4
第 8天,(4+1)*2=10
第 7天,(10+1)*2=22
:,
逻辑问题求解例:两个乒乓球队进行比赛,各出三人。
甲队为 a,b,c三人,乙队为 x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。 a说他不和 x比,c说他不和 x,z比。请编程序找出三队赛手的名单。
#include <stdio.h>
void main()
{
char i,j,k;/*i是 a的对手,j是 b的对手,k是 c的对手 */
for(i='x';i<='z';i++)
for(j='x';j<='z';j++)
{
if(i!=j)
for(k='x';k<='z';k++)
{ if(i!=k&&j!=k)
{ if(i!='x'&&k!='x'&&k!='z')
printf("order is a--%c\tb--%c\tc--%c\n",i,j,k);
}
}
}
}