1、什么是控制语句
控制语句用于控制程序的执行流程,以实现程序的顺序结构、选择结构和循环结构,它们由特定的语句定义符组成。
C语言有九种控制语句,可以分为以下3类:
(1)分支语句:if语句、switch语句
(2)循环执行语句:do while语句、while语句、for语句;(3)转向语句:break语句、goto语句、continue语句、return语句。
2、分支语句
2.1if语句
if语句用来判定是否满足所给的条件,根据判定结果来执行后续操作。if语句有三种基本形式,分别为单分支if语句、双分支if语句和多分支if语句。
单分支if语句基本形式为:
if(表达式) 语句;
执行过程:若表达式为真,则执行语句;否则不执行。
代码示例:
int main() { int age = 0; scanf("%d", &age); if (age < 18) //当只有单个语句时,可以不加大括号 printf("未成年\n"); return 0; }
双分支if语句基本形式为:
if(表达式) 语句1; else 语句2;
执行过程:若表达式为真,则执行语句1;否则执行语句2。
代码示例:
int main() { int age = 0; scanf("%d", &age); if (age < 18) printf("未成年\n"); else printf("成年\n"); return 0; }
多分支if语句基本形式为:
if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; ... else if(表达式n) 语句n; else 语句n+1;
执行过程:若表达式1为真,则执行语句1;若表达式2为真,则执行语句2;以此类推。如果所有的表达式均为假,则执行语句n+1。
代码示例:
int main() { int score = 0; scanf("%d", &score); if (score < 60) printf("不及格\n"); else if (score >= 60 && score < 70) printf("及格\n"); else if (score >= 70 && score < 85) printf("良好\n"); else printf("优秀\n"); return 0; }
注意,else总是与距离它最近的if匹配。下面这段代码乍一看输出结果可能是“haha”,实际输出结果为空,因为else与最近的if匹配。
int main() { int a = 0; int b = 2; if(a == 1) if(b == 2) printf("hehe\n"); else printf("haha\n"); return 0; }
加上适当的{ }可以使代码逻辑更加清楚。所以在写代码的时候要养成良好的习惯,增强代码的可读性。
int main() { int a = 0; int b = 2; if(a == 1) { if(b == 2) printf("hehe\n"); else printf("haha\n"); } return 0; }
2.2switch语句
一个switch语句允许测试一个变量等于多个值时的情况,每个值称为一个case。
switch语句的基本形式为:
switch(表达式) { case 常量表达式1: 语句1; break; case 常量表达式2: 语句2; break; case 常量表达式3: 语句3; break; ... default: 语句n; break; }
执行过程:首先计算表达式的值,然后逐次与常量表达式比较。当表达式的值与某个常量表达式的值相等时,执行后面的语句,然后跳出switch case语句;若表达式的值与所有常量表达式的值都不相等,则执行default后的语句。
注意:(1)switch后面表达式必须为整型表达式;
(2)case后面跟的是整型常量表达式,可以使用字符类型,因为字符在内存中以ASCII码值存储;
(3)case后的各常量表达式不能相同;
(4)case后允许有多个语句,可以不用{ }括起来;
(5)case和default的先后顺序可以变动;
(6)每个switch语句中只能出现一条default子句,default子句可以省略。
代码示例:
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; case 6: printf("星期六\n"); break; case 7: printf("星期日\n"); break; default: break; } return 0; }
switch语句为如下形式时,case的值为1、2、3、4、5时输出的结果是相同的,case的值为6、7时输出的结果是相同的。
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default: break; } return 0; }
switch语句还可以嵌套使用。下面代码中,输出结果为m = 5,n = 3。
n = 1,进入case 1语句,此时m = 3,然而并没有遇到break,所以继续执行下面case语句;进入case 2语句,n = 2;进入case 3语句,此时嵌套了一个switch语句,n为2,进入case 2语句中,m = 4,n = 3,这里的break是跳出嵌套的switch语句,而外层的switch语句还要继续;进入case 4语句,m = 5,n = 3,break跳出外出swtich语句。
int main() { int n = 1; int m = 2; switch (n) { case 1:m++; case 2:n++; case 3: switch (n) { case 1:n++; case 2: m++;n++; break; } case 4: m++; break; default: break; } printf("m = %d, n = %d\n", m, n); return 0; }
3、循环语句
3.1do while语句
do while循环的基本形式为:
do { 循环体语句; } while(表达式);
执行过程:先执行循环体语句,再判断表达式是否为真,若为真,则继续循环;若为假,则跳出循环。
3.2while语句
while循环的基本形式为:
while(表达式) { 循环体语句; }
执行过程:先判断表达式,若为真,则执行循环体语句;若为假,则跳出循环。
代码示例:打印0~9的数字。
int main() { int i = 0; while (i < 10) { printf("%d ", i); i++; } return 0; }
while循环中的break和continue:
break永久终止循环;continue终止本次循环,进行下一次循环。下面通过代码观察一下break和continue的区别。
代码1:int main() { int i = 0; while (i < 10) { if (i == 5) break; printf("%d ", i); i++; } return 0; }
代码2:
int main() { int i = 0; while (i < 10) { if (i == 5) continue; printf("%d ", i); i++; } return 0; }
代码1中当i=5时,直接终止循环,运行结果为0 1 2 3 4。
代码2中当i=5时,跳过本次循环后面的语句,进入下次循环,i的值并没有改变,所以陷入死循环。
3.3for语句
for循环的基本形式为:
for(初始化表达式;条件表达式;更新表达式) { 循环体语句; }
执行过程:先求解初始化表达式,然后求解条件表达式,若为真,则执行循环体语句,接着执行更新表达式;若为假,则跳出循环。
注意:(1)for循环中的三个表达式都可以省略,但“;”不能省略;
(2)初始化表达式和更新表达式可以是一个简单表达式,也可以是逗号表达式;
(3)条件表达式一般是关系表达式或者逻辑表达式,也可以是数值表达式或者字符表达式;
(4)一个for循环可以有多个循环控制变量。
代码示例:
int main() { int i = 0; int k = 0; for (i = 0, k = 0; k = 0; i++, k++) k++; return 0; }
这个代码循环0次,首先条件表达式"k=0"是赋值而不是判等,其次表达式的值为0,而0为假,所以循环一次都不会进入。
for循环中的break和continue:
break和continue在for循环中和在while循环中的作用相同,但在使用时结果有些差异。
代码1:
int main() { int i = 0; for (i = 0; i < 10; i++) { if (i == 5) break; printf("%d ", i); } return 0; }
代码2:
int main() { int i = 0; for (i = 0; i < 10; i++) { if (i == 5) continue; printf("%d ", i); } return 0; }
代码1的执行结果为0 1 2 3 4,代码2的执行结果为0 1 2 3 4 6 7 8 9。可以看出,使用break时,当i=5直接终止循环,使用continue时,当i=5跳过当前循环,执行更新表达式进入下一次循环。
4、goto语句
goto语句的基本形式为:
goto 语句标号; ... 语句标号: 语句;
执行过程:无条件跳到语句标号处,然后执行后面代码。
注意:(1)语句标号可由字母、数字和下划线组成,第一个字符必须是字母或者下划线;
(2)goto语句可以用来跳出深层循环,但也会让代码结构层次模糊,不易读,所以要合理运用goto语句。
5、练习
1、计算n!
int main() { int n = 0; scanf("%d", &n); int mul = 1; for (int i = 1; i <= n; i++) { mul *= i; } printf("mul = %d\n", mul); return 0; }
2、计算1!+2!+3!+...+10!
方法一:
int main() { int sum = 0; for (int i = 1; i <= 10; i++) { int mul = 1; for (int j = 1; j <= i; j++) { mul *= j; } sum += mul; } printf("sum = %d\n", sum); return 0; }
方法二(优化):
int main() { int mul = 1; int sum = 0; for (int i = 1; i <= 10; i++) { mul *= i; sum += mul; } printf("sum = %d\n", sum); return 0; }
3、折半查找
int main() { int arr[] = { 0,1,2,3,4,5,6,7,8,9 }; int len = sizeof(arr) / sizeof(arr[0]); int left = 0; int right = len - 1; int k =7; int flag = 0; while (left <= right) { //int mid = (right + left) / 2; //当left和right过大时,二者的和可能会超出整型所能表示的最大范围,发生越界 //所以采用下面这种方式 int mid = left + (right - left) / 2; if (arr[mid] < k) { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1; } else { printf("找到了!下标是%d\n", mid); flag = 1; break; } } if (flag == 0) printf("没找到!\n"); return 0; }
4、实现多个字符从两端移动,向中间汇聚
#include <stdio.h> #include <string.h> #include <Windows.h> int main() { char arr1[] = "hello world!"; char arr2[] = "************"; int left = 0; int right = strlen(arr1) - 1; while (left <= right) { arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%s\n", arr2); Sleep(1000); //停止1000毫秒 system("cls"); //清屏 left++; right--; } printf("%s\n", arr2); return 0; }
5、猜数字游戏(1~100)
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu() { printf("********************\n"); printf("******1.0 start*****\n"); printf("******0.0 exit*****\n"); printf("********************\n"); } void game() { //设置随机数 int ret = rand() % 100 + 1; //猜数字 int input = 0; while (1) { printf("请输入->"); scanf("%d", &input); if (input < ret) { printf("猜小了\n"); } else if (input > ret) { printf("猜大了\n"); } else { printf("猜对了!\n"); break; } } } int main() { int input = 0; //随机数生成器 srand((unsigned)time(NULL)); do { menu(); printf("请选择->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }