C语言学习--程序流程控制

提示:理解和掌握程序流程控制语句对于编写有效、可靠的代码至关重要。

目录

前言

7.1 程序流程控制介绍

7.2 顺序控制

7.2.1顺序控制介绍

7.2.2顺序控制举例和注意事项

7.3 分支控制 if-else

7.3.1分支控制 if-else 介绍

7.3.2单分支

7.3.3双分支

7.3.4单分支和双分支练习题

7.3.5多分支

7.4 嵌套分支

7.4.1基本介绍

7.4.2基本语法

7.4.3应用案例 1

7.4.4应用案例 2

7.5 switch 分支结构

7.5.1基本语法和流程图

7.5.2快速入门

7.5.3switch 细节讨论

7.5.4switch 课堂练习

7.5.5 switch 和 if 的比较

7.6 for 循环控制

7.6.1 看一个实际需求

7.6.2 传统解决方案

7.6.3基本语法

7.6.4for 循环执行流程分析

7.6.5注意事项和细节说明

7.6.6for 循环练习题

7.7 while 循环控制

7.7.1基本语法

7.7.2while 循环执行流程分析

7.7.3注意事项和细节说明

7.7.4课堂练习题

7.8 do..while 循环控制

7.8.1基本语法

7.8.2do...while 循环执行流程分析

7.8.3注意事项和细节说明

7.8.4课堂练习题

7.9 多重循环控制

7.9.1介绍

7.9.2应用实例

7.9.3经典的打印金字塔

7.10 跳转控制语句-break

7.10.1 看下面一个需求

7.10.2 基本介绍

7.10.3 基本语法

7.10.4 以 while 使用 break 为例,画出示意图

7.10.5 快速入门

7.10.6 课堂练习题

7.11 跳转控制语句-continue

7.11.1 基本介绍

7.11.2 基本语法

7.11.3 以 dowhile 使用 continue 为例,画出示意图

7.11.4 快速入门案例

7.11.5 基本案例分析和说明

7.11.6 注意事项和细节说明

7.11.7 课堂练习题

7.12 跳转控制语句-goto

7.12.1 介绍

7.12.2 基本语法

7.12.3 案例演示

7.13 跳转控制语句-return

7.14 课后练习题

总结


前言

在软件开发中,程序的流程控制是编程的核心要素之一。它决定了程序的执行顺序和逻辑路径,直接影响到程序的功能和效果。理解和掌握程序流程控制语句对于编写有效、可靠的代码至关重要。本章节将深入探讨程序流程控制的基本概念,涵盖顺序控制、分支控制和循环控制三大主要方面。通过学习这些基本的控制结构,您将能够编写出更复杂的程序逻辑,并有效地解决各种编程问题。

在本章中,我们首先介绍顺序控制,它是最简单也是最基本的控制方式,程序的语句将按顺序逐行执行。接着,我们探讨分支控制,包括单分支、双分支和多分支语句,这些语句允许程序根据不同的条件选择不同的执行路径。最后,我们会讨论循环控制,它使得代码能够重复执行特定的操作,直到满足某个条件。通过具体的代码示例和实践练习,您将能够更好地掌握这些流程控制结构,并能够在实际编程中灵活运用它们。


7.1 程序流程控制介绍

在程序中,程序运行的流程控制决定程序是如何执行的,是我们必须掌握的,主要有三大流程控制语句。

1) 顺序控制

2) 分支控制

3) 循环控制

7.2 顺序控制

7.2.1顺序控制介绍

程序从上到下逐行地执行,中间没有任何判断和跳转。

4e72ce1ce4d84614a438da4d7da1cd56.png

7.2.2顺序控制举例和注意事项

Java,C 中定义变量时采用合法的前向引用的原则。如:

void main() {

int num1 = 12;

int num2 = num1 + 2;

}

错误形式:

void main() {

int num2 = num1 + 2;

int num1 = 12;

}

7.3 分支控制 if-else

7.3.1分支控制 if-else 介绍

让程序有选择的的执行,分支控制有三种:

1) 单分支

2) 双分支

3) 多分支

7.3.2单分支

Ø 基本语法

if(条件表达式){

执行代码块;

}

说明:当条件表达式为真 (非 0) 时,就会执行 { } 的代码,返回假(0) 时,不会执行{ } 的代码

Ø 案例说明

请大家看个案例[IfDemo.c]:

编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁,则输出 “你年龄大于 18,要对自己的行为负责!”

#include <stdio.h>

void main() {

* 编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁,则输出 “你年龄大于 18,要

对自己的行为负责!”

分析

1. int age 接收输入的年龄

2. 使用 if 单分支来判断,进行相应处理

*/

int age = 0;

printf("请输入年龄");

scanf("%d", &age);

//根据 age 的值来处理

if(age > 18) {

printf("\n 你年龄大于 18,要对自己的行为负责!");

printf("\n 你年龄大于 18,要对自己的行为负责!");

printf("\n 你年龄大于 18,要对自己的行为负责!");

printf("\n 你年龄大于 18,要对自己的行为负责!");

}

printf("ok~~~");

getchar();//接收回车

getchar();//暂停控制台

}

Ø 单分支对应的流程图(可以更加形象的说明程序执行的流程)

2a4aa88e3afd41e295176c0b1624f2b7.png

7.3.3双分支

Ø 基本语法

if(条件表达式){

执行代码块 1;

}

else{

执行代码块 2;

}

说明:当条件表达式成立(为真),执行代码块 1,否则执行代码块 2.

Ø 案例演示

请大家看个案例[IfDemo2.c]:

编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁,则输出 “你年龄大于 18,要对自己的行为负责!”。否则 ,输出”你的年龄不大这次放过你了。”

#include <stdio.h>

void main() {

/*编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁,则输出 “你年龄大于 18,要对自己的行为负责!”。否则 ,输出”你的年龄不大这次放过你了.”

分析:

1. int age 接收输入的年龄

2. 使用 if-else 双分支来判断,进行相应处理

*/

int age = 0;

printf("请输入年龄");

scanf("%d", &age);

if(age > 18) {

printf("\n 你年龄大于 18,要对自己的行为负责!");

} else {

printf("\n 你的年龄不大这次放过你了");

}

printf("ok~~~");

getchar();

getchar();

}

Ø 双分支对应的流程图

4e9c1d77c7344b8093e7bb05e7424db6.png

e9ca31cc68ff45b68a2a81e61c22fd84.png

7.3.4单分支和双分支练习题

1) 对下列代码,若有输出,指出输出结果。

int x = 4;

int y = 1;

if (x > 2) {

if (y > 2) {

printf("x+y=%d", x + y);

}

printf("atguigu");

} else // 如果 if – else 中的代码块,只有一条语句,则可以省略 {}

printf("x is =%d" , x);

//结果是 atguigu

2) 编写程序,声明 2 个 int 型变量并赋值。判断两数之和,如果大于等于 50,打印“hello world!” [if 语句可以]

3) 编写程序,声明 2 个 double 型变量并赋值。判断第一个数大于 10.0,且第 2 个数小于 20.0,打印两数之和。

void main() {

//编写程序,声明 2 个 double 型变量并赋值。判断第一个数大于 10.0,且第 2 个数小于 20.0,打印两数之和

//分析

//1. 定义 2 个 double d1 和 d2

//2. 使用逻辑与

//3. 使用 if

double d1 = 146.7;

double d2 = 23.3;

if(d1 > 10.0 && d2 < 20.0) {

printf("d1+d2=%.2f", (d1 + d2));

}

}

 

4)【选作】定义两个变量 int,判断二者的和,是否既能被 3 又能被 5 整除,打印提示信息

5)判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被 4 整除,但不能被 100 整除;(2)能被 400 整除

void main() {

//判断一个年份是否是闰年,闰年的条件是符合下面二者之一:

//(1)年份能被 4 整除,但不能被 100 整除;(2)能被 400 整除

//分析

//1. 定义以变量 year

//2. 有逻辑与 和 逻辑或的综合使用

//3. if-else

int year = 2020;

if( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {

printf("%d 是 闰年", year); //闰年是 366 天, 平年 365

} else {

printf("%d 不是 闰年", year);

}

getchar();

}

 

7.3.5多分支

Ø 基本语法

if(条件表达式 1){

执行代码块 1;

}

else if (条件表达式 2){

执行代码块 2;

}

……

else{

执行代码块 n;

}

Ø 多分支的流程图(重要!)

说明:

1) 当条件表达式 1 成立时,即执行代码块 1

2) 如果表达式 1 不成立,才去判断表达式 2 是否成立,

3) 如果表达式 2 成立,就执行代码块 2

4) 以此类推如果所有的表达式都不成立,则执行 else 的代码块,注意,只能有一个执行入口。

20f7ab2836294ee9b748de8262fe17f1.png

Ø 案例演示 1

请大家看个案例[IfDemo3.c]:

岳小鹏参加 C 二级考试,他和父亲岳不群达成承诺:

如果:

成绩为 100 分时,奖励一辆 BMW;

成绩为(80,99]时,奖励一台 iphone7plus;

当成绩为[60,80]时,奖励一个 iPad;

其它时,什么奖励也没有。

请从键盘输入岳小鹏的 C 二级考试,并加以判断, 输出提示

代码演示:

#include <stdio.h>

void main() {

/*

岳小鹏参加 C 二级考试,他和父亲岳不群达成承诺:

如果:

成绩为 100 分时,奖励一辆 BMW;

成绩为(80,99]时,奖励一台 iphone7plus;

当成绩为[60,80]时,奖励一个 iPad;

其它时,什么奖励也没有。

请从键盘输入岳小鹏的 C 二级考试,并加以判断, 输出提示

分析

1. 定义一个 double 保存成绩

2. 因为判断条件有多个,因此我们使用多分支处理

*/

double score = 0.0;

printf("请输入成绩");

scanf("%lf", &score);

if( score == 100) {

printf("奖励一辆 BMW");

} else if (score > 80 && score <= 99) {

printf("奖励一台 iphone7plus");

} else if (score >= 60 && score <= 80) {

printf("奖励一台 iPad");

} else {

printf("没有奖励");

}

getchar();//得到的回车

getchar();//控制暂停

}

Ø 案例演示 2

int b = 1;

if(b = 0) //如果写成 if(b==0)能编译通过吗?如果能,结果是?

printf("a");

else if(b)

printf("b");

else if(!b)

printf("c");//c

else

printf("d");

可以编译,并运行,结果是 c

Ø 案例演示 3

求 ax2+bx+c=0 方程的根。a,b,c 分别为函数的参数,如果:b2-4ac>0,则有两个解;

b2-4ac=0,则有一个解;b2-4ac<0,则无解;

提示 1:x1=(-b+sqrt(b2-4ac))/2a

X2=(-b-sqrt(b2-4ac))/2a

提示 2:sqrt(num),需要 #include <math.h>

代码演示:

#include <stdio.h>

#include <math.h>

void main() {

/*

求 ax2+bx+c=0 方程的根。a,b,c 分别为函数的参数,如果:b^2-4ac>0,则有两个解;

b2-4ac=0,则有一个解;b2-4ac<0,则无解;

提示 1:x1=(-b+sqrt(b^2-4ac))/2a

X2=(-b-sqrt(b^2-4ac))/2a

提示 2:sqrt(num),需要 #include <math.h>

分析

1. 定义三个 double a,b,c,x1,x2

2. b^2-4ac 的值在程序中使用很多次(>=3),因此我们可以使用一个变量来保存,从而避免重复计算

3. sqrt(num),需要 #include <math.h>

4. 使用到多分支

走代码

*/

double a=3,b=2,c=6,x1=0,x2=0;

double t = b * b - 4 * a * c;

if( t > 0 ) {

x1=(-b + sqrt(t)) / (2 * a);

x2=(-b - sqrt(t)) / (2 * a);

printf("\nx1=%.2f", x1);

printf("\nx2=%.2f", x2);

} else if (t == 0) {

x1=(-b + sqrt(t)) / (2 * a);

printf("\nx1=%.2f", x1);

} else {

printf("无解");

}

getchar();

}

Ø 案例演示 4[课后练习,自己完成]

大家都知道,男大当婚,女大当嫁。那么女方家长要嫁女儿,当然要提出一定的条件:高:180cm 以上;富:财富

1 千万以上;帅:是。条件从控制台输入。

1) 如果这三个条件同时满足,则:“我一定要嫁给他!!!”

2) 如果三个条件有为真的情况,则:“嫁吧,比上不足,比下有余。”

3) 如果三个条件都不满足,则:“不嫁!”

int height ; double money; int handsome;

7.4 嵌套分支

7.4.1基本介绍

在一个分支结构中又完整的嵌套了另一个分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。嵌套分支不适合过多,最多不要超过 3 层。

7.4.2基本语法

if(){

if(){ //被包含的可以是单分支,双分支,多分支

}else{

}

}

7.4.3应用案例 1

参加百米运动会,如果用时 8 秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。 输入成绩和性别,进行判断。

double second; char gender;

代码演示

#include <stdio.h>

void main() {

/*

参加百米运动会,如果用时 8 秒以内进入决赛,否则提示淘汰。并且根据性别提示进入男子组或女子组。

【可以让学员先练习下】, 输入成绩和性别,进行判断。1 分钟思考

分析

1. 变量 double time 保存时间

2. 变量 char gender 保存性别

3. 使用嵌套分支

*/

double time = 0.0;

char gender = ' ';

printf("请输入跑步成绩(s) ");

scanf("%lf", &time);

//根据 time 判断是否进入决赛

if( time <= 8 ) {

//进入

printf("请输入性别(m/f)");

scanf("%c", &gender); // 接收到上次回车

scanf("%c", &gender); // 这次才接收到性别

if(gender == 'm') {//male 男

printf("请进入男子组");

} else {

printf("请进入女子组");

}

} else {

printf("你被淘汰");

}

getchar(); //回车

getchar(); //暂停

}

7.4.4应用案例 2

出票系统:根据淡旺季的月份和年龄,打印票价 [考虑学生先做]

4_10 旺季:

成人(18-60):60

儿童(<18):半价

老人(>60):1/3

淡季:

成人:40

其他:20

自己做:

7.5 switch 分支结构

7.5.1基本语法和流程图

79930f0d14a6405e8406849dc8c2bdd3.png

911b65578baa4f2f80736b75183d5e6e.png

7.5.2快速入门

Ø 案例:

请编写一个程序,该程序可以接收一个字符,比如: a,b,c,d,e,f,g,a 表示星期一,b 表示星期二 … 根据用户的输入显示相依的信息.要求使用switch 语句完成

代码演示

#include <stdio.h>

void main() {

/*

案例:

请编写一个程序,该程序可以接收一个字符,比如: a,b,c,d,e,f,g

a 表示星期一,b 表示星期

二 … 根据用户的输入显

示相依的信息.要求使用

switch 语句完成

*/

char c1 = ' ';

char c2 = 'a';

printf("请输入一个字符(a,b,c,d)");

scanf("%c", &c1);

//switch

//表达式: 任何有值都可以看成是一个表达式

switch(c1) {

case 'a' : //'a' => 97

printf("今天星期一, 猴子穿新衣");

break; //退出 switch

case 'b' :

printf("今天星期二, 猴子当小二");

break;

case 'c' :

printf("今天星期三, 猴子爬雪山");

break;

case 'd' :

printf("今天星期四, 猴子有急事");

break;

default : //default 是可选择,不是必须的

printf("没有匹配到任何值~");

}

printf("switch 结束~");

getchar();

getchar();

}

 

7.5.3switch 细节讨论

1) switch 语句中的 expression 是一个常量表达式,必须是一个整型(char、short, int, long 等) 或枚举类型

2) case 子句中的值必须是常量,而不能是变量

3) default 子句是可选的,当没有匹配的 case 时,执行 default

4) break 语句用来在执行完一个 case 分支后使程序跳出 switch 语句块;

5) 如果没有写 break,会执行下一个 case 语句块,直到遇到 break 或者执行到 switch 结尾, 这个现象称为穿透.

7.5.4switch 课堂练习

1) 使用 switch 把小写类型的 char 型转为大写(键盘输入)。只转换 a, b, c, d, e. 其它的输出 “other”。

2) 对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。(注:输入的成绩不能大于 100)

3) 根据用于指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季

4) 根据用户输入显示对应的星期时间(char[]),如果“星期一”,显示“干煸豆角”如果“星期二”,显示“醋溜土豆”如果“星期三”,显示“红烧狮子头”如果“星期四”,显示“油炸花生米”如果“星期五”,显示“蒜蓉扇贝”如果“星期六”,显示“东北乱炖”如果“星期日”,显示“大盘鸡”[自己完成]

5) 课堂练习答案

#include <stdio.h>

void main() {

// 使用 switch 把小写类型的 char 型转为大写(键盘输入)。只转换 a, b, c, d, e. 其它的输出 “other”。

/*char c1 = 'u';

switch(c1) {

case 'a' :

printf("A");

break;

case 'b' :

printf("B");

break;

case 'c' :

printf("C");

break;

case 'd' :

printf("D");

break;

case 'e' :

printf("E");

break;

default :

printf("other");

}

getchar();*/

//对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。(注:输入的成绩不能大于 100)

//double d1 = 0.0;

//printf("请输入成绩");

//scanf("%lf", &d1);

//switch( (int)(d1/60) ) { //即 switch() 括号中,可以是一个复杂表达式

//case 0 :

// printf("不合格");

// break;

//case 1:

// printf("合格");

// break;

//default :

// printf("输入成绩有误");

//}

//getchar();

//getchar();

//根据用于指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季

int month = 0;

printf("请输入月份");

scanf("%d", &month);

switch(month){

case 3: //switch 穿透来简化

case 4:

case 5:

printf("春季");

break;

case 6: //switch 穿透来简化

case 7:

case 8:

printf("夏季");

break;

case 9: //switch 穿透来简化

case 10:

case 11:

printf("秋季");

break;

case 12: //switch 穿透来简化

case 1:

case 2:

printf("冬季");

}

getchar();

getchar();

}

 

7.5.5 switch 和 if 的比较

1) 如果判断的具体数值不多,而且符合整型 、枚举类型。虽然两个语句都可以使用,建议使用 swtich 语句。

2) 其他情况:对区间判断,对结果为 真假 的判断,使用 if,if 的使用范围更广

7.6 for 循环控制

基本介绍:听其名而知其意,就是让你的代码可以循环的执行.

7.6.1 看一个实际需求

请大家看个案例[forTest.c]:

编写一个程序, 可以打印 5 句

“你好,尚硅谷!”。请大家想想怎么做?

7.6.2 传统解决方案

void main() {

printf("你好,尚硅谷!");

printf("你好,尚硅谷!");

printf("你好,尚硅谷!");

printf("你好,尚硅谷!");

printf("你好,尚硅谷!");

}

如果不使用循环控制,代码的维护性很差 => for 循环

 

7.6.3基本语法

循环变量定义

for(①循环变量初始化;②循环条件;④循环变量迭代){

③循环操作(多条语句);

}

7.6.4for 循环执行流程分析

1) 使用 for 循环完成前面的题

//定义循环变量

int i;

for( i = 1; i <= 5; i++) {

printf("\n 你好,尚硅谷 i=%d", i);

}

2) 画出流程图

3) 代码执行内存分析图

10b62704d46547d7b91b7807dfdcb274.png

7.6.5注意事项和细节说明

1) 循环条件是 返回一个表示真(非 0)假(0) 的表达式

2) for(;循环判断条件;) 中的初始化和变量迭代可以不写(写到其它地方),但是两边的分号不能省略。

3) 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开。

for(i = 0, j = 0; j < count; i++, j += 2)

4) 代码演示

void main() {

//写法 2: 可以将 变量的初始化和迭代放在其他地方.

int i = 1;

for( ; i <= 5; ) {

printf("\n 你好,尚硅谷~ i=%d", i);

i++;

}

//循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开,

//循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开

//分析输出

// i = 0 j = 0

// i = 1 j = 2

// i = 2 j = 4

// i = 3 j = 6

int i;

int j;

for ( i = 0, j = 0; i <= 3;i++, j += 2) {

printf("\ni=%d j=%d", i, j);

}

printf("\n 最后 i=%d j=%d", i, j); // i = 4 j =8

getchar();

}

7.6.6for 循环练习题

1) 打印 1~100 之间所有是 9 的倍数的整数的个数及总和. [使用 for 完成]

void main() {

//打印 1~100 之间所有是 9 的倍数的整数的个数及总和. [使用 for 完成]

//分析

//1. 定义变量 count 记录 个数

//2. 定义变量 sum 记录 总和

int i = 0;

int count = 0;

int sum = 0;

for ( i = 1; i <= 100 ; i++) {

//判断 i 是不是 9 的倍数

if( i % 9 == 0 ) { //是

count++; //统计个数

sum += i; //累计到 sum

}

}

printf("\n count=%d sum=%d", count, sum);

}

  1. 完成下面的表达式输出

902324ba7df84d0a82705b62cca0acad.png

void main() {

//完成下面的表达式输出

//分析

//1. 先接收用户的输入 num

//2. 使用 for 循环来输出 0 --》 num 的各种组合方式

//3. 使用先死后活 方式来编程和思考 , 假定 num 就是 6 =》 然后再在把 6 改成变量

//4. 当我们的编程思维建立后,就可以一步到位

int num = 10; // 使用 scanf 让用户输入 num,

int i = 0;

for( i = 0; i <= num; i++) {

printf("\n %d + %d = %d", i, num-i, num);

}

getchar();

}

7.7 while 循环控制

7.7.1基本语法

①循环变量初始化;

while(②循环条件){

③循环体(多条语句);

④循环变量迭代;

}

7.7.2while 循环执行流程分析

1) 画出流程图

3e0f7e42ed8d4d9bbf600ba39bc18850.png

2) 使用 while 循环完成前面的题 (输出 你好 尚硅谷)

#include <stdio.h>

void main() {

//输出

int i = 1; //循环变量初始化

while( i <= 5) { //循环条件

printf("\n 你好 尚硅谷 i=%d", i); //循环语句

i++; // 变量迭代

}

getchar();

}

7.7.3注意事项和细节说明

1) 循环条件是返回一个表示真(非 0)假(0) 的表达式

2) while 循环是先判断再执行语句

7.7.4课堂练习题

1) 打印 1—100 之间所有能被 3 整除的数

void main() {

// 打印 1—100 之间所有能被 3 整除的数

int i = 1;

int max = 100;

while(i <= max) {

if( i % 3 == 0 ) {

printf("\n i=%d 能被 3 整除", i);

}

i++;

}

getchar();

}

2) 打印 40—200 之间所有的偶数

void main() {

//打印 40—200 之间所有的偶数

int i = 40;

int max = 200;

while(i <= max) {

if( i % 2 == 0 ) {

printf("\n i=%d 是偶数", i);

}

i++;

}

getchar();

}

3) 不断输入姓名,直到输入 "exit" 为止[使用 while 完成]

void main() {

//不断输入姓名,直到输入 "exit" 为止[使用 while 完成]

//分析

//1. 需要接受用户的输入,字符串[字符数组]

//2. 提示: <string.h> 有一个 strcmp 函数,判断两个字符串是否相同

// int strcmp(const char *str1, const char *str2) // 返回 0 表示相等,非 0 表示不相等

char name[10] = "";

while( strcmp(name,"exit") != 0) { // exit = > 0 != 0

printf("\n 请输入名字");

scanf("%s", name); // 这里不需要 加 &name, 因为 数组的名称就是地址

printf("\n 你输入的名字是=%s", name);

}

printf("退出 while");

getchar(); //过滤 回车

getchar(); // 暂停控制台

}

7.8 do..while 循环控制

7.8.1基本语法

①循环变量初始化;

do{

②循环体(多条语句);

③循环变量迭代;

}while(④循环条件);

注意:do – while 后面有一个 分号,不能省略.

7.8.2do...while 循环执行流程分析

  1. 画出流程图

238a04f27572463d81f4ccd8d2a9a4e0.png

2) 使用 do...while 循环完成前面的题

#include <stdio.h>

void main() {

//5 句话

int i = 1; //循环变量初始化

int max = 5; //循环的最大次数

do {

printf("\n 你好,尚硅谷 i=%d", i); //循环体

i++; //循环变量迭代

}while(i <= max); //循环条件

printf("\ni=%d", i); // i= 6

getchar();

}

7.8.3注意事项和细节说明

1) 循环条件是返回一个表示真(非 0)假(0) 的表达式

2) do..while 循环是先执行,再判断

7.8.4课堂练习题

1) 打印 1—100

2) 计算 1—100 的和

3) 统计 1——200 之间能被 5 整除但不能被 3 整除的个数

void main() {

//统计 1——200 之间能被 5 整除但不能被 3 整除的个数

//分析

//1. 使用 do - while

//2. 定义一个 count 保存满足条件的数的个数

//3. 定义 i = 1 max=200 控制循环的次数

int i = 1;

int max = 200;

int count = 0;

do {

//判断

if((i % 5 == 0) && (i % 3 != 0)) {

count++;//累积

}

i++;

}while(i <= max); // 循环条件

printf("1——200 之间能被 5 整除但不能被 3 整除的个数 count= %d", count);

getchar();

}

 

4) 如果老公同意老婆购物,则老婆将一直购物,直到老公说不同意为止

[printf("老婆问:我可以继续购物吗?y/n")]

void main() {

/*

如果老公同意老婆购物,则老婆将一直购物,

直到老公说不同意为止

[printf("老婆问:我可以继续购物吗?y/n")]

*/

char answer = ' ';

do {

printf("老婆问:我可以继续购物吗?y/n");

scanf("%c", &answer); // 获取用户输入

getchar(); //过滤掉 回车符

} while(answer == 'y');

printf("老婆终于退出购物~~~~");

getchar();

}

7.9 多重循环控制

7.9.1介绍

1) 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while 均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过 3 层】, 如果嵌套循环过多,会造成可读性降低

2) 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false 时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环, 举例说明。

3) 设外层循环次数为 m 次,内层为 n 次,则内层循环体实际上需要执行 m*n 次

7.9.2应用实例

1) 统计 3 个班成绩情况,每个班有 5 名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。

2) 统计三个班及格人数,每个班有 5 名同学。

#include <stdio.h>

void main() {

//统计 3 个班成绩情况,每个班有 5 名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]。

//分析

// 编程技巧 1. 先死后活 2. 先简单再复杂(分解) 3. 根据需要增加或修改相应的代码

//1. 各个班的平均分

//2. 所有班级的平均分, 得到所有班级的总分 allClassTotalScore

//3. 定义变量表示 班级个数 classNum , 定义变量表示 学生个数 stuNum

//4. 定义变量 classTotalScore 每个班级总分

//5. 定义变量 score , 接收学生成绩

//6. 使用两层 for 循环

//增加新功能 统计三个班及格人数,每个班有 5 名同学

//分析

//1. 定义一个变量 count ,保存及格人数

//2. 当接收到一个学生成绩后,就看看是否及格,如果及格,则累计到 count

int stuNum = 5;

int classNum = 3;

double classTotalScore= 0.0;

double score = 0.0;

double allClassTotalScore = 0.0; //所有班级总成绩

int count = 0; //及格人数

int i, j;

for ( i = 1; i <= classNum; i++) { //控制班级循环次数

//每次给一个班级输出成绩时,需要清零

classTotalScore = 0.0;

for( j = 1; j <= stuNum; j++) { //控制学生循环次数

printf("\n 请输入第%d 班级的 第%d 个学生的成绩", i , j);

scanf("%lf", &score);

if(score >= 60) {

count++;

}

classTotalScore += score; //累计成绩

}

allClassTotalScore += classTotalScore; //累计所有班级成绩

//当内层的 for 循环结束后,就得到了该班级 的总成绩

printf("\n 第%d 个班级的 平均分 = %.2f", i, classTotalScore / stuNum);

}

//输出所有班级的成绩

printf("\n 所有班级的 平均分 = %.2f", allClassTotalScore / (stuNum * classNum));

printf("\n 所有班级的 及格人数 = %d", count);

getchar();

getchar();

}

 

3) 打印出九九乘法表

#include <stdio.h>

void main() {

//99 乘法表

//分析

//1. 先打印 1 列

//2. 在打印多列,注意分析,

//3. 先死后活, 功能逐步完成

int i,j;

for(i = 1; i <= 9; i++) {

//因为每一行都在增加算式, 所以使用 for 循环控制

for(j=1; j <= i; j++) {

printf("%d * %d = %d ", j, i , i * j);

}

printf("\n");

}

getchar();

}

7.9.3经典的打印金字塔

1) 使用 for 循环完成下面的案例

2) 请编写一个程序,可以接收一个整数,表示层数(totalLevel),打印出金字塔。(stars.c) [化繁为简, 先死后活]

3) 思路分析

0afc574b27e642588461f850c9ce0f05.png

4) 代码完成

#include <stdio.h>

void main() {

//打印空心金字塔

//化繁为简, 先死后活

//分析

//1. 打印矩形

/*

*****

*****

*****

*****

*****

*/

//2. 打印半个金字塔

/*

*

**

***

****

*****

*/

//3. 打印整个金字塔

/*

* // 1 个 * (2 * i - 1) = 2 * 1 - 1= 1 空格有 4 (总的层数-i) = 5-1=4

*** // 3 个 * (2 * i - 1) = 2 * 2 - 1= 3 空格有 3 (总的层数-i) = 5-2=3

***** // 5 个 * (2 * i - 1) = 2 * 3 - 1= 5 空格有 2 (总的层数-i) = 5-3=2

******* // 7 个 * (2 * i - 1) = 2 * 4 - 1= 7 空格有 1 (总的层数-i) = 5-4=1

********* // 9 个* (2 * i - 1) = 2 * 5 - 1= 9 空格有 0 (总的层数-i) = 5-5=0

*/

//4. 打印空心金字塔

//在输出 * 号的时候,需要考虑是否输出的*还是空格

//分析

/*

* // i = 1 该输入* 就输入 *

* * // 如果是 第一个* 和最后一个* 输出的*, 其它应该输入 空格

* * // 如果是 第一个* 和最后一个* 输出的*, 其它应该输入 空格

* * // 如果是 第一个* 和最后一个* 输出的*, 其它应该输入 空格

********* // i = 5 该输入* 就输入 *

*/

//将 5 层,改成一个变量 totalLevel

//5. 打印空心菱形, 使用老师思路,完成

/*

*

* *

* *

* *

*

*/

//1. 打印矩形

int i,j,k, totalLevle = 20;

for(i = 1; i <= totalLevle; i++) {//控制层

//输出空格, 使用 k 控制空格的循环

for (k=1; k <= totalLevle - i; k++) {

printf(" ");

}

for(j = 1; j <= 2 * i - 1; j++) {

if(j == 1 || j == 2 * i - 1 || i == totalLevle) { //i ==5 表示最下层

printf("*");

} else {

printf(" ");

}

}

printf("\n");

}

getchar();

}

7.10 跳转控制语句-break

7.10.1 看下面一个需求

随机生成一个数,直到生成了 97 这个数,看看你一共用了几次?

提示使用

1) rand() 返回一个范围在 0 到 RAND_MAX 之间的伪随机数

2) rand() 函数 在 stdlib.h 头文件.

通过该需求可以说明其它流程控制数据的必要性,比如 break

在执行循环的过程中,当满足某个条件时,可以提前退出该循环, 这时,就可能使用 break

7.10.2 基本介绍

break 语句用于终止某个语句块的执行,一般使用在 switch 或者循环[三大循环]中。

7.10.3 基本语法

{ ……

break;

……

}

7.10.4 以 while 使用 break 为例,画出示意图

66d0b73b23c14361a5b262f61c926f16.png

7.10.5 快速入门

int i;

for(i = 0; i < 10; i++) {

if(i ==3) { break;}

printf("i=%d\n", i);}

//输出 i = 0 i = 1 i =2

7.10.6 课堂练习题

1) 分析下面的代码输出内容是什么

void main() {

int j,i;

for( j = 0; j < 4; j++) {

for( i = 0; i < 10; i++) {

if(i == 2){ break ; }

printf("i = %d \n" , i);

}

}

getchar();

}

i = 0

i = 1

i = 0

i = 1

i = 0

i = 1

i = 0

i = 1

 

2) 100 以内的数求和,求出 当和 第一次大于 20 的当前数【for】

void main() {

//100 以内的数求和,求出 当和 第一次大于 20 的当前数【for】

int i = 1;

int sum = 0;

for(i = 1; i <= 100; i++) {

sum += i;

if(sum > 20) {

printf("当和 第一次大于 20 的当前数 = %d", i);

break;

}

}

getchar();

}

3) 实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,否则提示还有几次机会。

请使用 for 循环完成

void main() {

//实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,

//否则提示还有几次机会,请使用 for 循环完成

//分析

//1. 首先要定义一个变量,保存登录的机会(次数) chance

//2. 定义两个字符数组,接收 用户名和密码

//3. 使用 for 循环+break , 如果登录成功,就提前退出

int chance = 3;

int loginCount = chance; //值传递

char name[10] = "";

char pwd[10] = "";

int i ; //循环变量

for(i = 1; i <= loginCount; i++) {

printf("\n 请输入名字");

scanf("%s", name);//字符数组,不要加&

printf("\n 请输入密码");

scanf("%s", pwd);

//判断字符串相同使用 strcmp

if(strcmp("张无忌", name) == 0 && strcmp("888", pwd) == 0){

printf("\n 登录成功");

break; // for + break

} else {

//机会次数减少

chance--;

printf("\n 你还有%d 次登录机会", chance);

}

}

getchar();

getchar();

}

 

7.11 跳转控制语句-continue

7.11.1 基本介绍

continue 语句用于结束本次循环,继续执行下一次循环。

7.11.2 基本语法

{ ……

continue;

……

}

7.11.3 以 dowhile 使用 continue 为例,画出示意图

1a6a1cfa1a374320bf65debd58081f2c.png

7.11.4 快速入门案例

void main() {

int i = 1;

while(i <= 4) {

i++;

if( i == 3) {

continue;

}

printf("i=%d\n", i );

}

getchar();

}

7.11.5 基本案例分析和说明

void main() {

int i,j;

for( j = 0; j < 4; j++){

for( i = 0; i < 10; i++){

if(i == 2){

//看看分别输出什么值,并分析

continue ;

}

printf("i = %d\n" , i);

}

printf("================\n");

}

getchar();

}// 输出 4 次 i=0, 1 ,3,4,5,6,7,8,9

7.11.6 注意事项和细节说明

continue 语句,只能配合循环语言使用,不能单独和 switch/if 使用。

void main() {

int i = 0;

switch(i) {

case 1: continue; //错误

}

if(i > 1) {

continue; //错误

}

}

7.11.7 课堂练习题

1) 从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为 0 时结束程序【使用 for 循环 ,break, continue 完成】 【positive 正数,negative】

void main() {

//从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,

//输入为 0 时结束程序【使用 for 循环 ,break, continue 完成】 【positive 正数,negative】

//分析

//1. 定义变量 positive 保存正数的个数

//2. 定义变量 negative 保存负数的个数

//3. 使用 for + break + continue

int positive = 0;

int negative = 0;

int num = 0; //接收从控制台输入的数

for(; ;) { // 是一个死循环

printf("请输入数");

scanf("%d", &num);

if(num == 0) {

break; //跳出 for

}

if(num > 0 ) {//正数

positive++; //累计

continue;

}

//num 是一个负数

negative++;

}

printf("正数个数%d 负数个数%d", positive,negative );

getchar();

getchar();

}

 

2) 某人有 100,000 元,每经过一次路口,需要交费,规则如下:

当现金>50000 时,每次交 5%

当现金<=50000 时,每次交 1000

编程计算该人可以经过多少次路口,使用 while break 方式完成

void main() {

/*某人有 100,000 元,每经过一次路口,需要交费,规则如下:

当现金>50000 时,每次交 5%

当现金<=50000 时,每次交 1000

编程计算该人可以经过多少次路口,使用 while break 方式完成

分析

1. money 保存 金额

2. 定义变量 count 统计可以经过多少个路口

3. while break

4. break 条件是 money < 1000 时

*/

int count = 0; //路口数

int money = 100000; //现有的钱

while(1){ //死循环

//判断是否该退出

if(money < 1000) { //退出 while 条件

break;

}

//当现金>50000 时,每次交 5%

if(money >50000) {

money = money * 0.95;

} else if(money <= 50000) {

money -= 1000;

}

count++; //经过的路口增加 1

}

printf("100,000 元 可以经过 %d 个路口 剩余 %d 元", count, money);

getchar();

}

7.12 跳转控制语句-goto

7.12.1 介绍

1) C 语言的 goto 语句可以无条件地转移到程序中指定的行。

2) goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。

3) 在 C 程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难

7.12.2 基本语法

goto label

.. .

label: statement

cd10037bdf474d159f5cea72656c6ea0.png

7.12.3 案例演示

void main() {

printf("start\n");

goto lable1; //lable1 称为标签

printf("ok1\n");

printf("ok2\n");

lable1:

printf("ok3\n");

printf("ok4\n");

getchar();

} //输出 ok3 和 ok4

7.13 跳转控制语句-return

1) return 使用在函数,表示跳出所在的函数,在讲解函数的时候,

2) 会详细的介绍,这里我们简单的提一下。

7.14 课后练习题

1) 实现判断一个整数,属于哪个范围:大于 0;小于 0;等于 0 (多分支)

2) 判断一个年份是否为闰年 [课堂上讲过]

3) 判断一个整数是否是水仙花数,所谓水仙花数是指一个 3 位数,其各个位上数字立方和等于其本身。例如: 153= 1*1*1 + 5*5*5 + 3*3*3

void main() {

/*判断一个整数是否是水仙花数,所谓水仙花数是指一个 3 位数,

其各个位上数字立方和等于其本身。例如: 153 = 1*1*1 + 5*5*5 + 3*3*3

思路分析

1. 先获取到一个三位数的各个位的数字 使用 / 和 %

2. 将得到各个数字(百位,十位,个位) 立方,并求和判断是否和原数相等

代码实现

*/

int num = 154;

int num1 = num / 100; //百位

int num2 = num % 100 / 10; //十位

int num3 = num % 10; //个数

if(num == num1 * num1 * num1 + num2 * num2 * num2 + num3 * num3 * num3) {

printf("%d 就是水仙花数" , num);

} else {

printf("%d 不是水仙花数" , num);

}

getchar();

}

4) 写出输出结果

int m=0,n=3;

if(m>0){

if(n>2)

printf("A");

else

printf("B");

}

//没有输出

5) 保存用户名和密码,判断用户名是否为“张三”,密码是否为 1234,如果是,提示登录成功,否则提示登录失败

6) 编写程序,根据输入的月份和年份,求出该月的天数(1-12), 就是需要考虑闰年(2 月份 29)和平年(2 月份 28)

void main() {

//编写程序,根据输入的月份和年份,求出该月的天数(1-12),

//就是需要考虑闰年(2 月份 29)和平年(2 月份 28)

//规则

//1,3,5,7,8,10,12 --- 31

//2 月份 :闰年(2 月份 29)和平年(2 月份 28)

//其它月份都是 30

int year = 2019;

int month = 2;

switch(month) {

case 1:

case 3:

case 5:

case 7:

case 8:

case 10:

case 12:

printf("%d 年的 %d 月是%d", year, month, 31);

break;

case 2:

//判断 year 是闰年还是平年

if( (year % 4 == 0 && year % 100 !=0) || year % 400 == 0) {

printf("%d 年的 %d 月是%d", year, month, 29);

} else{

printf("%d 年的 %d 月是%d", year, month, 28);

}

break;

default:

printf("%d 年的 %d 月是%d", year, month, 30);

break;

}

getchar();

}

7) 定义变量保存一个数,判断(if)是否能被 3 整除或(||)能被 7 整除(%),如果是,则提示:能,否则提示:不能

8) 输入星期几,如果是星期一到星期三,打印:AAA,星期四到星期五,打印:BBB,星期六到星期日,打印CCC, 如果都不是,提示,输入错误(提示 switch+穿透)

9) 看下面代码输出什么?

int b1=0,b2=0;

// 将 b2==5>0 改成 b2=5>0 又输出什么

// 充分考虑运算符的优先级问题

if((b1==2>3) && (b2=5>0)){

printf("\n(b1=2>3) && (b2=5>0)为真"); //输出

}

printf("\nb1= %d ;b2= %d", b1,b2);// b1=0 b2=1

getchar();

10) 如下的 c 代码输出的结果是

int a=2;

while(a<2){ //先判断

printf("\n 执行 while");

}

do{

printf("执行 do-while");

}while(a<2); //输出一次 "执行 do-while "

11) 复习:请使用 for、while、do—while 三种形式打印 1000——9999 年内所有的闰年

12) 输出小写的 a-z 以及大写的 Z—A

void main() {

//输出小写的 a-z 以及大写的 Z—A

char c1,c2;

for(c1 = 'a'; c1 <= 'z'; c1++) {

printf("%c ", c1);

}

printf("\n=====================\n");

for(c2 = 'Z'; c2 >= 'A'; c2--) {

printf("%c ", c2);

}

getchar();

}

13) 求出 1-1/2+1/3-1/4…..1/100 的和

void main() {

//求出 1-1/2+1/3-1/4…..1/100 的和

//思路分析,找到算式的规律,并求解

// 1-1/2+1/3-1/4…..1/100 = (1/1)-(1/2)+(1/3)-(1/4)..... (1/100)

// 分母为奇数, 则符号时 +

// 分母为偶数, 则符号时 -

//定义一个变量 sum 来统计和

double sum = 0.0;

int i ;

for(i = 1; i <= 100; i++) {

//如果 i 是奇数

if(i % 2 != 0) {

sum += 1.0/i; // 注意,考虑保留小数 1.0 而不是 1

} else {

sum -= 1.0/i;

}

}

printf("sum=%.2f", sum);

getchar();

}


总结

在本章中,我们详细探讨了程序流程控制的各个方面。顺序控制作为最基本的流程控制方式,它按顺序逐行执行代码,是所有程序的基础。分支控制则通过条件判断使程序具备选择不同执行路径的能力,单分支、双分支和多分支结构使得程序能够根据不同的条件做出不同的响应。循环控制则允许代码在特定条件下重复执行,从而实现更复杂的功能和逻辑处理。

掌握这些流程控制结构不仅有助于编写更高效的程序,还能帮助我们更好地解决实际问题。在实际编程中,这些控制结构将被广泛应用于各种场景,如数据处理、用户输入的验证、游戏逻辑的实现等。通过反复练习和实际应用,您将能够熟练运用这些流程控制语句来实现各种编程需求。

理解和掌握程序流程控制是编程学习中的关键步骤,它为我们编写复杂程序奠定了坚实的基础。希望通过本章的学习,您能够在编程实践中游刃有余,写出更高效、更可靠的代码。

附录

参考:【尚硅谷C语言零基础快速入门教程-哔哩哔哩】 https://b23.tv/vS3vTDp

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值