目录
2.3.2 do while语句中的break与continue
学习完C语言基础篇,该踏上下一步台阶了。
引:什么是语句?
C语言语句可分为五类:
1.表达式语句
2.函数调用语句
3.控制语句
4.符合语句
5.空语句
本篇就主要讲解为控制语句,其用于控制程序的执行流程,以实现程序的各种结构方式,由特定符号表示,共九种,分为以下三类:
(1)条件判断语句(分支语句):if语句、switch语句;
(2)循环执行语句:do while语句,while语句,for语句;
(3)转向语句:break语句,goto语句,continue语句,return语句。
注:这里的语句更趋向于结构,我们一般所说的语句是指由一个分号;分隔的就是一个语句。
一、分支语句
分支语句在基础篇中就有所提及,它可以译为“要么...要么...”,下面咱们进一步学习。
1.1 if语句
if语句是分支语句中的一种,它的基本语法结构如下,
代码1_1,if语句的结构:
①
if(表达式)
语句;
②
if(表达式)
语句;
else
语句;
③
if(表达式1)
语句1;
else if(表达式2)
语句2;
else if(表达式3)
语句3;
......
else
语句n;
if结构比较简单,直接翻译就是“如果表达式成立,即条件为真(非0),就执行下面的语句;如果表达式不成立,即条件为假(0),就执行else if 或者else 或者 跳出该分支语句”。
比如下列示例,代码1_2,输入成绩并判断是否合格:
#include<stdio.h>
int main()
{
int score=0;
scanf("%d",&score);
if(score >= 0 && score < 60)
printf("不合格\n");
else if(score >= 60 && score <= 100)
printf("合格\n");
return 0;
}
说明:
代码1_2就是使用的分支语句,如果分数小于60,那么打印“不合格”;如果分数大于等于60,那么打印“合格”。
与此同时,在if语句中表达式判定为假时,即不满足if 的表达式,然后在其所对应的else if 或者 else 中就可以排除if 的表达式,则代码1_2可改为:
#include<stdio.h> int main() { int score=0; scanf("%d",&score); if(score >= 0 && score < 60) printf("不合格\n"); else if(score <= 100) printf("合格\n"); return 0; }
正如以上代码,当输入score值大于60小于等于100时,程序执行在判断if 的表达式为假(表示score值一定大于60)后,进入else if ,此时就不必再判断score值是否大于60了。
补;
C语言中,表示score大于0小于60不能用:0<score<60,该式不符合逻辑;
而是用:score>0 && score<60来表示,其中 && 为并且的意识,同样还有 || 符号表示或者。
1.1.2 代码块
如果条件成立,需要执行多条语句,应该使用代码块,即应将多条语句用大括号{ }括住。
下列代码1_3,重要的事说三遍:
#include<stdio.h>
int main()
{
int score=0;
scanf("%d",&score);
if(score >= 0 && score < 60){
printf("不合格\n");
printf("不合格\n");
printf("不合格\n");
}
else if(score <= 100){
printf("合格\n");
printf("合格\n");
printf("合格\n");
}
return 0;
}
说明:
(1)由大括号{ }引的部分即称为代码块,只要语法合理均可化为代码块;
(2)默认情况下,if 以及else、else if后只能有一条语句,否则会有编译问题;
(3)如果if 以及else、else if后有多条语句,则需要使用代码块;
1.1.3 if与else的对应规则
见下列代码1_4:(试问程序输出什么?)
#include<stdio.h>
int main()
{
int a=0;
int b=2;
if(1==a)
if(1==b)
printf("hello");
else
printf("world");
return 0;
}
程序执行结果:
说明:
可见代码1_4无输出结果,未进入if或者else.
(1)else 与if 匹配时为就近原则;
(2)这其实是代码缩进问题,正常缩进应该是,(也可以加上代码块{ }):
(3)写代码时要有好的代码风格,特别注意缩进、空行以及分块等,既美观,又不易错误理解,如下列几个代码,
代码1_5,if书写形式的对比:
//代码1, if(condition) { return x; } return y;//条件成立,返回x,否则返回y。 //代码2, if(condition) { return x; } else { return y; }//条件成立,返回x,否则返回y。 *对比代码1和2,哪一个更易于阅读和理解呢? //代码3, int num=5; if(5==num) //当用于判断相等(双等号)时, return x; //可将数值放在前,变量在后; else //若失误只有一个等号,编译会报错。 return y;
1.2 switch语句
switch语句也是一种分支结构,常用于多分支,相当于if 以及多个else if。
代码1_6,switch基本结构:
switch(整形表达式)
{
case 整形1:
语句1;
case 整形2:
语句2;
......
}
下面我们来举例说明,
代码1_7,输入数字1~7并输出对应星期:
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day) {
case 1:
printf("星期一\n");
case 2:
printf("星期二\n");
case 3:
printf("星期三\n");
case 4:
printf("星期四\n");
case 5:
printf("星期五\n");
case 6:
printf("星期六\n");
case 7:
printf("星期天\n");
}
return 0;
}
运行代码1_7,当我们输入值为7时,会打印星期天;但输入1~6时,却会出现打印错误;接下来改进代码。
代码1_7(改1):
#include<stdio.h>
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;
}
return 0;
}
说明:
switch语句常与break连用,意思是,当从其中一个case语句进入后,执行完其中代码后跳出switch,从而达到分支的作用,这样也不会出现运行错误的情况;
但是,当输入值不在1~7之间呢?我们还可以使用default再改进代码。
代码1_7(改2):
#include<stdio.h>
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:
printf("输入错误\n");
}
return 0;
}
说明:
(1)switch语句中加入default后,则表示当进入switch语句的数值没有对应的case进入时,执行default;
(2)default在switch语句中没有必须要求放在最后,可以放前面、后面,或中间。
补:
(1)switch(表达式),其中表达式必须是整型表达式;
(2)case 整形:,其中整形必须是整型常量表达式;
当然,也不是所有case后必须有语句,看下面代码。
代码1_8,输入1~7并判断weekday、weekend:
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday\n");
break;
case 6:
case 7:
printf("weekend\n");
break;
default:
printf("输入错误\n");
}
return 0;
}
二、循环语句
循环语句很好理解,就是当条件满足时,循环执行操作。下面简单介绍三种循环语句、以及循环中break与continue的用法
2.1.1 while语句
---while 循环流程图
下面直接给出while语句的结构,代码2_1:
while(condition)
{
循环语句;
}
说明:
当condition为真时,执行代码块内的语句;为假则不进入while循环。
接下来看一个示例,代码2_2,打印1~10数字:(后文所有示例均为这里的变式)
#include<stdio.h>
int main()
{
int i = 0;//变量初始化
while (i < 10) //判断变量是否进入循环
{
i++;//调整变量值
printf("%d ", i);
}
return 0;
}
说明:
创建变量i,初始化为0;当i小于10时,进入while;每次i自增1后打印;当i等于10时,不满足while的条件,则结束循环。
2.1.2 while语句中的break与continue
下列两段代码,观察代码有何区别,运行结果如何。
代码2_3,break:
#include<stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
i++;
if (5 == i)
break;
printf("%d ", i);
}
return 0;
}
代码2_4,continue:
#include<stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
i++;
if (5 == i)
continue;
printf("%d ", i);
}
return 0;
}
运行结果:
代码2_3,break:1 2 3 4
代码2_4,continue:1 2 3 4 6 7 8 9 10
说明:
(1)break:直接终止本层循环的进行,跳出循环;(当循环有两层及以上嵌套时,break只终止其所在的一层)
(2)continue:终止本次循环,即在本次循环中continent后的代码不再执行,直接跳转至循环的判断部分,判断是否进行下一次循环。
补:
使用continue时,如果continue在调整语句前,如代码2_4中,continue在i++前的话,就会导致死循环,可自行验证。
2.2.1 for语句
从代码2_2,打印1~10数字我们可知,在一次循环中,我们有变量初始化、判断变量是否进入循环、调整变量值,这样多步的操作分开会比较麻烦,那么就可以使用for语句。
---for 循环流程图
代码2_5,for语句结构:
for(表达式1;表达式2;表达式3)
{
循环语句;
}
说明:
(1)表达式1,初始化部分,用于初始化循环变量;
(2)表达式2,条件判断部分,用于判断循环进行;
(3)表达式3,调整部分,用于循环条件的调整。
示例,代码2_2可以改为,代码2_6:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
printf("%d ", i);
}
return 0;
}
代码2_2与代码2_6,执行效果一致。
2.2.2 for语句中的break与continue
观察下面两个代码,并思考运行结果。
代码2_7,break:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (5 == i)
break;
printf("%d ", i);
}
return 0;
}
代码2_8,continue:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (5 == i)
continue;
printf("%d ", i);
}
return 0;
}
说明:
可以看到,break与continue在for语句中使用和作用与在while语句大径相同。只有一点有所不同,在使用continue使,for语句一定不会导致死循环,而while语句中,所放位置不同,就可能导致死循环。
2.2.3 使用语句的注意
建议:
i)建议不在for循环的循环语句中修改循环变量,防止for循环失控;
代码2_9,for死循环:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
i = 0;
printf("%d ", i);
}
return 0;
}
ii)for语句的循环控制变量的取值建议采用“前闭后开区间”;
代码2_10,前闭后开取值:
for (i = 0; i < 10; i++)
{
循环语句;
}
iii)for循环的初始化、调整、判断语句均可省略;若判断部分略去,表示判断结果恒为真,如for( ; ;),表示随意可进入循环;所以,在不能熟练使用语句时,建议不随意省略。对比下列两段代码,输出有何不同?
代码2_11:
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
printf("注意!");
return 0;
}
代码2_12,略去初始化:
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
for ( ; i < 3; i++)
for ( ; j < 3; j++)
printf("注意!");
return 0;
}
代码运行结果:
代码2_11:
代码2_12,略去初始化:
说明:
代码2_11打印了9次“注意!”,而代码2_12只打印了三次。
(1)代码2_11执行次数,
i=0(初始化)=> j=0(初始化) j=1 j=2 j=3(跳出 j 的for循环) => i=1 => j=0(初始化) j=1 j=2 j=3(跳出 j 的for循环) => i=2 => j=0(初始化) j=1 j=2 j=3(跳出 j 的for循环) => i=3(跳出 i 的for循环) 运行结束 执行次数:9次 (2)代码2_12执行次数,
i=0(初始值)=> j=0(初始值) j=1 j=2 j=3(跳出 j 的for循环) => i=1 => 未初始化) j=3(跳出 j 的for循环) => i=2 => 未初始化) j=3(跳出 j 的for循环) => i=3(跳出 i 的for循环) 运行结束 执行次数:3次
2.2.4 一个坑
代码2_13:
#include<stdio.h>
int main()
{
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
k++;
return 0;
}
提问:代码运行了多少次?
提示:判断部分为判断 k 为真还是假。
2.3.1 do while语句
do while语句和while语句的使用差别并不大,这里就只简单介绍一下,不清楚的地方可参考while语句。
---do while循环流程图
代码2_14,do while语句结构:
do{
循环语句;
}while(表达式);
说明:
首先进入执行一次循环语句,再判断表达式真假是否再进入执行循环语句,即do while循环至少会执行一次循环语句。
示例,代码2_2可以改为,代码2_15:
#include<stdio.h>
int main()
{
int i = 0;
do {
i++;
printf("%d ", i);
} while (i < 10);
return 0;
}
代码2_2与代码2_15,执行效果一致。
2.3.2 do while语句中的break与continue
break与continue在do while 语句和while 语句中的使用一致,同样注意continue导致的死循环。
三、练习
讲到这里,分支与循环结构就大致完成了,这里简单给出几道练习题,自行练习,或者,刷题网站练习。毕竟,学习从来不是只看读就能学好的,而这些题还远远不够,记得多练多想。
1.计算n的阶乘;
2.计算1!+2!+3!+...+n!的和(提示,双层嵌套);
3.在有序(从小到大)数组里面查找某个数字n;
4.在屏幕上输出9*9乘法口诀表(提示,双层嵌套);
5.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果(提示,双层嵌套);
6.求10 个整数中最大值(提示:数组)。
7.二分查找法。