5.1程序流程控制介绍
在程序中,程序运行的流程控制决定程序是如何执行的,其中主要有三大流程控制语句顺序控制、分支控制和循环控制
5.2顺序控制
5.2.1顺序控制介绍
程序从上到下逐行地执行,中间没有任何判断和跳转
5.2.2顺序控制注意事项
C中定义变量时采用合法的前向引用的原则,即在使用变量前应该申明
#include<stdio.h>
void main() {
int a = 97;
int b = a + 7;
printf("b = %d", b);
}
5.3分支控制
5.3.1if-else
5.3.1.1单分支
if (条件表达式){
执行代码块;
}
当条件表达式为真(非0)时,执行代码块;为假时,不会执行代码块
#include<stdio.h>
void main() {
int a1 = 9;
int b1 = 7;
if (a1 > b1) {
printf("ok!!\n");//a1 > b1为真,执行printf("ok!!\n")
}
int a2 = 9;
int b2 = 7;
if (a2 < b2) {
printf("ok??\n");//a2 < b2为假,不执行printf("ok??\n");
}
}
5.3.1.2双分支
当条件表达式成立(为真),执行代码块1,否则执行代码块2
if(条件表达式){
执行代码块1;
}
else{
执行代码块2;
}
#include<stdio.h>
void main() {
int age;
printf("请输入你的年龄");
scanf_s("%d", &age);
if (age > 18) {
printf("你大于18岁了");
}
else {
printf("你还小");
}
}
5.3.1.3练习
- 定义两个变量int,判断二者的和,是否既能被3又能被5整除
#include<stdio.h> void main() { int num1, num2, sum; printf("请输入两个数字:"); scanf_s("%d%d", &num1, &num2); sum = num1 + num2; if ((sum % 3 == 0) && (sum % 5 == 0) ) { printf("%d和%d的和既能被三整除,也能被五整除", num1, num2); } }
-
判断一个年份是否是闰年,闰年的条件是符合下面二者之一:(1)年份能被4整除, 但不能被100整除;(2)能被400整除
#include<stdio.h> void main() { int year; printf("请输入年份:"); scanf_s("%d", &year); if (((year % 4 == 0) && (year % 100 != 0)) || year % 400 == 0) { printf("%d是闰年", year); } else { printf("%d不是闰年", year); } }
5.3.1.4多分支
if(条件表达式1){
执行代码块1;
}
else if (条件表达式2){
执行代码块2;
}
……
else{
执行代码块n;
}
- 当条件表达式1成立时,即执行代码块1
- 如果表达式1不成立,才去判断表达式2是否成立
- 如果表达式2成立,就执行代码块2
- 以此类推如果所有的表达式都不成立 ,则执行 else 的代码块,注意, 只能有一个执行入口
//岳小鹏参加C二级考试,他和父亲岳不群达成承诺:
//如果: 成绩为100分时,奖励一辆BMW; 成绩为(80,99]时,奖励一台iphone7plus;
//当成绩为[60,80]时,奖励一个 iPad; 其它时,什么奖励也没有。
//请从键盘输入岳小鹏的C二级考试,并加以判断, 输出提示
#include<stdio.h>
void main() {
double score;
printf("请输入成绩:");
scanf_s("%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("什么奖励也没有");
}
}
5.3.1.5 嵌套分支
if(){
if(){ //被包含的可以是单分支,双分支,多分支
}else{
}
}
在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层分支外面的分支结构称为外层分支。嵌套分支不适合过多,最多不要超过3层
- 参加百米运动会,如果用时8秒以内进入决赛,否则提示淘汰。并且根据性别提示进入 男子组或女子组。 输入成绩和性别,进行判断。
#include<stdio.h> void main() { char gender; double score; printf("请输入成绩\n"); scanf_s("%lf", &score); printf("请输入性别m/f\n"); scanf_s("%c", &gender, sizeof(gender)); scanf_s("%c", &gender, sizeof(gender)); if (score < 8) { if (gender == 'm') { printf("你进入男子组决赛"); } else { printf("你进入女子组决赛"); } } else { printf("你未能进入决赛"); } }
-
出票系统:根据淡旺季的月份和年龄, 打印票价
4-10月
旺季:成人(18 - 60):60 儿童( < 18):半价 老人(>60):1 / 3
其他
淡季:成人:40 其他:20
#include<stdio.h>
void main() {
int mouth, age;
printf("请输入月份和年龄\n");
scanf_s("%d%d", &mouth, &age);
if (mouth >= 4 && mouth <= 10) {//判断是否在4-10月内,即旺季
if (age < 18) {
printf("票价为30");//小于18岁的票价
}
else if (age>=18 && age < 60){
printf("票价为60");//成年人的票价
}
else {
printf("票价为20");//老人的票价
}
}
else {//非旺季
if (age >= 18 && age < 60) {//成人票价
printf("票价为40");
}
else {//其余人的票价
printf("票价为20");
}
}
}
5.3.1.6 switch分支结构
switch(表达式){
case 常量1: //当表达式值等于常量1
语句块1;
break; //退出switch
case 常量2; // 含义一样
语句块2;
break;
...
case 常量n;
语句块n;
break;
default: //如果之前的常量都不相等,则执行default语句块
default语句块;
break;
}
请编写一个程序,该程序可以接收一个字符,比如: a,b,c,d,e,f,g a表示星期一,b表示星期 二… 根据用户的输入显示相依的信息.要求使用 switch 语句完成
#include<stdio.h>
void main() {
char day;
printf("请输入a,b,c,d,e,f,g其中之一的字符\n");
scanf_s("%c", &day, sizeof(day));
switch (day) {
case 'a'://如果输入的字符与a相等,则printf("星期一"),然后break
printf("星期一");
break;
case 'b'://如果输入的字符不是a,则判断是否与b相等
printf("星期二");
break;
case 'c':
printf("星期三");
break;
case 'd':
printf("星期四");
break;
case 'e':
printf("星期五");
break;
case 'f':
printf("星期六");
break;
case 'g':
printf("星期天");
break;
default://如果a,b,c,d,e,f,g都没有匹配成功,则执行default里的语句
printf("没有匹配到");
}
}
- switch 语句中的 expression 是一个常量表达式,必须是一个整型(char、short, int, long 等) 或枚举类型
#include<stdio.h> void main() { char num = 'a'; switch (num) { case 97://等价于case'a' printf("ok2"); break; } }
-
case 子句中的值必须是常量,而不能是变量
#include<stdio.h> void main() { char num = 'a'; char num1 = 97; switch (num) { case num1://case的值不能是变量 printf("ok2"); break; } }
-
default 子句是可选的,当没有匹配的 case 时,执行 default
-
break 语句用来在执行完一个 case 分支后使程序跳出 switch 语句块;如果没有写 break,会执行下一个 case 语句块,直到遇到 break 或者执行到 switch 结尾,这个现象称为穿透
#include<stdio.h> void main() { char day; printf("请输入a,b,c,d,e,f,g其中之一的字符\n"); scanf_s("%c", &day, sizeof(day)); switch (day) { case 'a': printf("星期一\n"); break; case 'b': printf("星期二\n"); break; case 'c': printf("星期三\n"); break; case 'd': printf("星期四\n"); break; case 'e': printf("星期五\n"); //break; case 'f': printf("星期六\n"); break; case 'g': printf("星期天\n"); break; default: printf("没有匹配到"); } }
5.3.1.7 switch练习
- 使用 switch 把小写类型的 char 型转为大写(键盘输入)。只转换 a, b, c, d, e. 其它的输出 “other”
#include<stdio.h> void main() { char letter; printf("请输入字符:"); scanf_s("%c", &letter, sizeof(letter)); switch (letter) { case 'a': printf("A\n"); break; case 'b': printf("B\n"); break; case 'c': printf("C\n"); break; case 'd': printf("D\n"); break; case 'e': printf("E\n"); break; default: printf("other"); } }
-
对学生成绩大于 60 分的,输出“合格”。低于 60 分的,输出“不合格”。(注:输入的成绩不能大于 100)
#include<stdio.h> void main() { double score; printf("请输入成绩:\n"); scanf_s("%lf", &score); switch ((int)(score/60)) { case 1: printf("合格"); break; case 0: printf("不合格"); break; default: printf("成绩有误"); } }
-
根据用于指定月份,打印该月份所属的季节。3,4,5 春季 6,7,8 夏季 9,10,11 秋季 12, 1, 2 冬季
//根据用于指定月份,打印该月份所属的季节。3, 4, 5 春季 6, 7, 8 夏季 9, 10, 11 秋季 12, 1, 2 冬季 #include<stdio.h> void main() { int mouth; printf("请输入月份:\n"); scanf_s("%d", &mouth); if (mouth > 0 && mouth < 13){ switch (mouth / 3) { case 0: printf("冬季\n"); break; case 1: printf("春季\n"); break; case 2: printf("夏季\n"); break; case 3: printf("秋季\n"); break; case 4: printf("冬季 \n"); } } else{ printf("输入错误"); } }
#include<stdio.h> void main() { int mouth; printf("请输入月份:\n"); scanf_s("%d", &mouth); switch (mouth) { case 3: case 4: case 5: printf("春季\n"); break; case 6: case 7: case 8: printf("夏季\n"); break; case 9: case 10: case 11: printf("秋季\n"); break; case 12: case 1: case 2: printf("冬季\n"); break; default: printf("输入错误"); } }
5.4循环控制
5.4.1for循环控制
5.4.1.1介绍
for循环可以让代码循环进行
5.4.1.2语法
for(1.循环变量初始化;2.循环条件;4.循环变量迭代){
3.循环操作(多条语句);
}
#include<stdio.h>
void main() {
int i;
for (i = 1; i <= 7; i++) {
printf("江南江南江南丶=%d\n", i);
}
}
5.4.1.3 for循环注意事项
- 循环条件是返回一个表示真(非0)假(0) 的表达式
- for(;循环判断条件;) 中的初始化和变量迭代可以不写(写到其它地方),但是 两边的分号不能省略
#include<stdio.h> void main() { int i=1; for (; i <= 7; ) { printf("江南江南江南丶=%d\n", i); i++; } }
- 循环初始值可以有多条初始化语句,但要求类型一样,并且中间用逗号隔开, 循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开
#include<stdio.h> void main() { int a, b; for (a = 0, b = 0; a <= 7; a++, b += 7) { printf("a = %d\t b =%d\n", a, b); } }
5.4.1.4 for循环练习
- 打印1~100之间所有是9的倍数的整数的个数及总和
#include<stdio.h> void main() { int num; for (num = 1; num <= 100; num++) { if (num % 9 == 0) { printf("%d是9的倍数\n", num); } } }
-
完成下面的表达式输出
#include<stdio.h> void main() { int num1, num2, sum; printf("请输入一个整数:"); scanf_s("%d", &num1); for (num2 = 0; num1 >=0 ; num1--, num2++) { sum = num1 + num2; printf("%d+%d=%d\n", num1, num2, sum); } }
5.4.2 while循环
5.4.2.1基本语法
1.循环变量初始化;
while(2.循环条件){
3.循环体(多条语句);
4.循环变量迭代;
}
#include<stdio.h>
void main() {
int a = 1;
while (a <= 7) {
printf("江南江南江南丶 %d\n", a);
a++;
}
}
5.4.2.2 while注意事项
- 循环条件是返回一个表示真(非 0)假(0) 的表达式
- while 循环是先判断再执行语句
5.4.2.3 while练习
- 打印 1—100 之间所有能被 3 整除的数
#include<stdio.h> void main() { int a = 1; while (a <= 100) { if (a % 3 == 0) { printf("%d是3的倍数\n", a); } a++; } }
-
打印 40—200 之间所有的偶数
#include<stdio.h> void main() { int num = 40; while (num <= 200) { if (num % 2 == 0) { printf("%d是偶数\n", num); } num++; } }
- 不断输入姓名,直到输入 "exit" 为止[使用while 完成]
#include<stdio.h> #include<string.h> void main() { char name[20]=""; while (strcmp( name, "exit") != 0) { printf("请输入姓名\n"); scanf_s("%s", name, sizeof(name)); } printf("退出"); }
5.4.3 do while循环
5.4.3.1基本语句
1.循环变量初始化;
do{
2.循环体(多条语句);
3.循环变量迭代;
}while(4.循环条件);//do – while 后面有一个分号,不能省略.
#include<stdio.h>
void main() {
int a = 0;
do {
printf("江南江南江南 %d\n", a);
a++;
} while (a <=7);
}
5.4.3.2 do while注意事项
- 循环条件是返回一个表示真(非 0)假(0) 的表达式
- do..while 循环是先执行,再判断
5.4.3.3 do while 练习
1.打印 1—100
//打印 1—100
#include<stdio.h>
void main() {
int num = 1;
do {
printf("%d\n", num);
num++;
} while (num <= 100);
}
2.计算 1—100 的和
//计算 1—100 的和
#include<stdio.h>
void main() {
int num = 1, sum = 0;
do {
sum = sum + num;
num++;
} while (num <= 100);
printf("1-100的和为%d", sum);
}
3.统计 1——200 之间能被 5 整除但不能被 3 整除的个数
//统计 1——200 之间能被 5 整除但不能被 3 整除的个数
#include<stdio.h>
void main() {
int count = 0, num = 1;
do {
if (num % 5 == 0 && num % 3 != 0) {
count++;
}
num++;
} while (num <= 200);
printf(" 1——200 之间能被 5 整除但不能被 3 整除的个数为%d", count);
}
4.如果老公同意老婆购物,则老婆将一直购物,直到老公说不同意为止
#include<stdio.h>
void main() {
char answer;
do {
printf("请输入是否同意:y/n\n");
scanf_s("%c", &answer, sizeof(answer));
getchar();
} while (answer == 'y');
printf("老公不同意老婆购物,请老婆停止购物");
}
5.4.4多重循环控制
5.4.4.1介绍
- 将一个循环放在另一个循环体内,就形成了嵌套循环。其中,for ,while ,do…while 均可以作为外层循环和内层循环。【建议一般使用两层,最多不要超过 3 层】, 如果嵌套循环过多,会造成可读性降低
- 实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为 false 时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环
- 设外层循环次数为m次,内层为 n 次,则内层循环体实际上需要执行m*n 次
5.4.4.2 多重循环练习
- 统计 3 个班成绩情况,每个班有 5 名同学,求出各个班的平均分和所有班级的平均分[学生的成绩从键盘输入]
#include<stdio.h> void main() { int classNum = 1, studentNum = 1, count = 0; double score = 0.0, augClassScore = 0.0, totalScore = 0.0, augTotalScore = 0.0, sum = 0.0; for (classNum = 1; classNum <= 3; classNum++) {//用于控制输入成绩的班级 for (studentNum = 1; studentNum <= 5; studentNum++) {//用于控制输入成绩的学号 printf("请输入%d班%d号学生的成绩:\n", classNum, studentNum); scanf_s("%lf", &score); sum = sum + score;//计算该班级的总成绩 if (score >= 60) {//如果成绩大于60,则及格人数加1 count++; } } augClassScore = sum / 5;//计算该班级的平均成绩 totalScore = totalScore + sum;//计算所有班级的总成绩 printf("%d班的平均分为%f\n", classNum, augClassScore); sum = 0.0;//计算完该班级总成绩后,该班级的总成绩清零,方便计算下个班级的总成绩 } augTotalScore = totalScore / 15; printf("所有班级的平均分为%f,及格人数有%d人\n", augTotalScore, count); }
-
打印出九九乘法表
//打印出九九乘法表 #include<stdio.h> void main() { int firstNum, secondNum; for (firstNum = 1; firstNum <= 9; firstNum++) { for (secondNum = 1; secondNum <= firstNum; secondNum++) { printf("%d * %d = %d ", firstNum, secondNum, firstNum * secondNum); } printf("\n"); } }
-
请编写一个程序,可以接收一个整数,表示层数(totalLevel),打印出空心金字塔。
//空心金字塔 #include<stdio.h> void main() { int totalLevel, firstLevel, starCount, enterCount; printf("请输入层数:"); scanf_s("%d", &totalLevel); for (firstLevel = 1; firstLevel <= totalLevel; firstLevel++) {//控制层数 for (enterCount = 1; enterCount <= totalLevel - firstLevel; enterCount++) {//每行打印空格的数量 printf(" "); } for (starCount = 1; starCount <= 2 * firstLevel - 1; starCount++) { if (starCount == 1 || starCount == 2 * firstLevel - 1 || firstLevel == totalLevel) {//当第一层、最后一层、每行的一个和最后一个,打星 printf("*"); } else {//其余打空格 printf(" "); } } printf("\n"); } }
5.5 跳转控制语句
5.5.1 break
5.5.1.1 break介绍
break 语句用于终止某个语句块的执行,一般使用在 switch 或者循环中
5.5.1.2代码
#include<stdio.h>
void main() {
int num;
for (num = 1; num <= 10; num++) {
if (num == 7) {//如果num = 7,则跳出循环
break;
}
printf("num = %d\n", num);
}
}
5.5.1.3 break练习
- 100 以内的数求和,求出 当和 第一次大于 20 的当前数
//100 以内的数求和,求出 当和 第一次大于 20 的当前数 #include<stdio.h> void main() { int num=1, sum=0; for (num = 1; num <= 100; num++) { sum += num; if (sum > 20) { printf("当前数为%d", num); break; } } }
-
实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,否则提示还有几次机会, 请使用 for 循环完成
//实现登录验证,有三次机会,如果用户名为”张无忌” ,密码”888”提示登录成功,否则提示还有几次机会, 请使用 for 循环完成
#include<stdio.h>
#include<string.h>
void main() {
char account[20] ="", password[20] ="";
int times = 0;
for (times = 1; times <= 3; times++) {
printf("请输入帐号:");
scanf_s("%s", account, sizeof(account));
printf("请输入密码 :");
scanf_s("%s", password, sizeof(password));
if (strcmp(account, "张无忌") == 0 && strcmp(password, "888") == 0) {
printf("登录成功!\n");
break;
}
else {
printf("登录失败,还剩下%d次机会\n", 3 - times);
}
}
}
5.5.2 continue
5.5.2.1 countinue介绍
continue 语句用于结束本次循环,继续执行下一次循环
5.5.2.2 continue语法
#include<stdio.h>
void main() {
int num1, num2;
for (num1 = 0; num1 <= 3; num1++) {
for (num2 = 0; num2 < 3; num2++) {
if (num2 == 2) {
continue;
}
printf("num1 = %d, num2 = %d\n", num1, num2);
}
}
}
5.5.2.3 continue注意事项
continue 语句,只能配合循环语言使用,不能单独和 switch/if使用
5.5.2.4 continue练习
- 从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为 0 时结束程序【使用 for 循环 ,break, continue 完成】 【positive 正数,negative】
#include<stdio.h> void main() { int positiveCount = 0, negativeCount = 0, count = 0; for (; ;) { printf("请输入数字:"); scanf_s("%d", &count); if (count > 0) { positiveCount++; continue; } else if (count < 0) { negativeCount++; continue; } else if (count == 0) { break; } } printf("正数的个数是%d,负数的个数是%d", positiveCount, negativeCount); }
-
某人有 100,000 元,每经过一次路口,需要交费,规则如下: 当现金>50000 时,每次交 5% 当现金<=50000 时,每次交 1000 编程计算该人可以经过多少次路口,使用 while break 方式完成
#include<stdio.h> void main() { double money = 100000, tax = 0.95; int count = 0; while (money >=1000) { if (money > 50000) { money *= tax; count++; } else if (money <= 50000) { money -= 1000; count++; } } printf("可以经过%d次路口", count); }
5.5.3 goto
5.5.3.1 goto介绍
- C 语言的 goto 语句可以无条件地转移到程序中指定的行
- goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能
- 在 C程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难
5.5.3.2 goto代码
#include<stdio.h>
void main() {
printf("start!\n");
printf("1\n");
goto label;//跳转到label行
printf("2\n");
printf("3\n");
label://label行
printf("4\n");
}