目录
3.3.2 do...while循环中的break和continue
一、什么是语句?
C语言的语句可以分为一下五大类:
1、表达式语句
2、函数调用语句
3、控制语句
4、复合语句
5、空语句
本篇文章讲解的是控制语句:用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。
可以分为以下三种:
1. 条件判断语句也叫分支语句:if语句、switch语句;
2. 循环执行语句:do while语句、while语句、for语句;
3. 转向语句:break语句、goto语句、continue语句、return语句。
2. 分支语句(选择结构)
二、分支语句(选择结构)
2.1 if语句
2.1.1 语法结构
if语句的语法结构有以下几种:
if(表达式)
语句;
if(表达式)
语句1:;
else
语句2;
//多分支
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
代码演示:
if:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if(age<18)
{
printf("未成年\n");
}
return 0;
}
if~else:
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("未成年\n");
}
else
{
printf("未成年\n");
}
return 0;
}
多分支:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("未成年\n");
}
else if(age>= 18 && age<= 40)
{
printf("青年\n");
}
else
{
printf("中老年\n");
}
return 0;
}
注意:如果表达式的结果为真,则语句执行;
在C语言中 0 表示假,非零表示真。
再多分支语句中,要注意代码块的使用:
#include<stdio.h>
int main()
{
if (表达式)
{
语句1;
}
else
{
语句2;
}
return 0;
}
2.1.2 悬空else
思考下列代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
答案:啥也不是
解析:else会与最近的if相匹配,所以上列代码写成下列形式就跟容易理解了。
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
{
if (b == 2)
printf("hehe\n");
else
printf("haha\n");
}
return 0;
}
所以,适当的使用 {} 可以使代码逻辑更加清晰,养成良好的代码风格。
2.2 switch语句
2.2.1 语法结构
那语句项是什么呢?
是一些case语句:
case 整形常量表达式 :
语句;
2.2.2 在switch语句中的 break
在switch语句中,我们无法真正的实现分支,搭配break才能真正的实现分支:
#include <stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期1\n");
break;
case 2:
printf("星期2\n");
break;
case 3:
printf("星期3\n");
break;
case 4:
printf("星期4\n");
break;
case 5:
printf("星期5\n");
break;
case 6:
printf("星期6\n");
break;
case 7:
printf("星期天\n");
break;
}
return 0;
}
如果要求变了,1~5输出工作日,6~7输出休息日呢?
我们的代码应该这样实现:
#include <stdio.h>
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;
}
return 0;
}
break语句的实际作用就是把语句列表划分为不同的分支部分。
注:编程好习惯——在最后一个 case 语句的后面加上一条 break语句。
2.2.3 default子句
如果表达的值与所有的case标签都不匹配怎么办呢?
这时程序并不会终止和报错,可以再语句列表中增加default:
当switch 表达式的值并不匹配所有case 标签的值时,这个default子句后面的语句就会执行。
所以,每一个switch语句中只能出现一条default子句。
注:编程好习惯——在每一个switch 语句中都放一条default子句,甚至可以在后面加一个break。
练习:
#include <stdio.h>
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;
}
答案:5 3
解析:进入循环,n=1,执行case 1:,m++,然后因为没有break,就继续执行case 2:,case 3:这时的n=2,执行嵌套switch的case 2:,这时n=3,m=4,然后break跳出嵌套switch,执行case 4:,因为case 4:有break所以跳出循环,打印m和n的值,结果就是m=5,n=3;
三、循环语句
3.1 while循环
3.1.1 语法结构
例如:在屏幕上打印1~10个数字
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
return 0;
}
3.1.2 while语句中的break和continue
思考break 例:
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if(5 == i)
break;
printf("%d ", i);
i++;
}
return 0;
}
答案:1 2 3 4
解析:在while循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。
思考continue 例:
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (5 == i)
continue;
printf("%d ", i);
i++;
}
return 0;
}
结果:1 2 3 4 死循环
解析:continue在while循环中用于终止本次循环的,也就是continue后面的代码不会执行,而直接跳转到while语句的判断部分,进行下一次循环的入口判断。
思考下列代码:
#include <stdio.h>
int main()
{
int ch = 0;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
//代码2
#include <stdio.h>
int main()
{
char ch = '\0';
while ((ch = getchar()) != EOF)
{
if (ch < ‘0’ || ch > ‘9’)
continue;
putchar(ch);
}
return 0;
}
这个代码的作用是只打印数字字符跳过其他字符,其中while ((ch = getchar()) != EOF)用来清理缓存区的。
3.2 for循环
3.2.1 语法结构
例如:
3.2.2 for循环中的break和continue
思考下列代码:
//代码1
#include <stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
//代码2
#include <stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
代码1 答案: 1 2 3 4
解析: 在for循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。
代码2 答案:1 2 3 4 6 7 8 9 10
解析:continue在for循环中用于终止本次循环的,也就是continue后面的代码不会执行,而直接跳转到下一次循环的入口判断,并没有跳过i++。
3.2.3 for语句中的循环控制变量
建议:
1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。
2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法。
//前闭后开的写法
for(i=0; i<10; i++)
{}
//两边都是闭区间
for(i=0; i<=9; i++)
{}
思考代码1打印几个hehe呢?
#include <stdio.h>
int main()
{
int i = 1;
int j = 1;
for (; i <= 10; i++)
{
for (; j <= 10; j++)
{
printf("hehe\n");
}
}
return 0;
}
答案:
解析:循环外 i=1,j=1;进入第一个for循环后,i=1<10,进入第二个for循环,
j=1<10,打印 hehe,打印10个hehe 之后,跳转到第一个for循环,此时i=2,j=10;
就不再进入第二个for循环了。
思考代码2,问循环执行多少次?
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++)
k++;
return 0;
}
答案: 0次;
解析:因为在for循环的判断部分 k=0 把0赋值给k,k为0,及判断部分为假,循环不执行。
3.3 do...while循环
3.3.1 语法结构
循环至少执行一次,使用场景有限,所以不经常使用;
3.3.2 do...while循环中的break和continue
思考下列代码:
//代码1
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (5 == i)
break;
printf("%d\n", i);
i++;
} while (i < 10);
return 0;
}
//代码2
#include <stdio.h>
int main()
{
int i = 1;
do
{
if (5 == i)
continue;
printf("%d\n", i);
i++;
} while (i < 10);
return 0;
}
代码1 答案:1 2 3 4
解析:在do...while循环中,遇到break就停止后期所有的循环,直接终止循环, 所以结果是1 2 3 4。
代码2 答案:1 2 3 4 死循环
解析:continue在do...while循环中用于终止本次循环的,也就是continue后面的代码不会执行,而直接跳转到while语句的判断部分,进行下一次循环的入口判断,由于跳过了i++部分,所以 i 始终是5,一直循环下去。
3.3.3 练习
猜数字游戏:
#include <stdio.h>
#include<stdlib.h>
#include <time.h>
void game()
{
int ret = rand() % 100 + 1;
int i = 0;
while (1)
{
printf("请猜数字:> ");
scanf("%d", &i);
if (i < ret)
{
printf("猜小了,再猜一次\n");
}
else if (i > ret)
{
printf("猜大了,再猜一次\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
void menu()
{
printf("******************************\n");
printf("******** 1: play ***********\n");
printf("******** 0: exit ***********\n");
printf("******************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)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;
}
二分查找法:
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int right = sz - 1;
int k = 0;
printf("请输入要查找的数字:");
scanf("%d", &k);
while (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);
break;
}
}
if (left > right)
{
printf("找不到了\n");
}
return 0;
}
四、goto语句
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如关机小程序:
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的
while (1)
{
printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
scanf("%s", input);
//判断
if (strcmp(input, "我是猪") == 0)
{
system("shutdown -a");//取消关机
break;
}
}
return 0;
}