目录
前言
C语言程序是由一句句语句构成,它在C语言中的地位不言而喻,在这篇文章中我们就来深入地学习C语言中的几种语句。
一、什么是语句
在C语言中由一个分号’;‘隔开就是一条语句。如:
int a=0;
其可分为以下五类:
- 表达式语句
- 函数调用语句
- 控制语句
- 复合语句
- 空语句
其中的控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,在C语言中有九种控制语句,可分为三类:
- 条件判断语句(分支语句):if语句、switch语句
- 循环语句:for语句、while语句、do...while语句
- 转向语句:break语句、goto语句、while语句、for语句
二、分支语句
分支语句能够让程序根据特定的条件执行不同的语句,以此来控制程序执行的流程。
1.if语句
我们先通过一个简单的案例来了解if语句。
请看下列程序,该程序读取一列数据,该数据为每日最低温度,要求打印出统计的总天数以及0℃以下的天数。
#include<stdio.h>
int main(void)
{
int FREEZING = 0;
float temperature;
int cold_days = 0;
int all_days = 0;
printf("Please enter the temperatures:\n");
while (scanf("%f", &temperature) == 1)
{
all_days++;
if (temperature < FREEZING)
cold_days++;
}
printf("%d days total!\n", all_days);
printf("%d were below freezing!\n", cold_days);
if (all_days == 0)
printf("No data entered!\n");
return 0;
}
其运行结果如下:
在上面的程序中while循环的条件是根据scanf()函数的返回值来判断,因为scanf()函数在读取到非数字字符时会返回0,这就是为什么在输入时末尾需要输入一个非数字字符。其涉及到的if语句如下:
if (temperature < FREEZING)
cold_days++;
该if语句指示计算机,如果读取temperature的值小于0(FREEZING),就使cold_days加一;如果temperature的值不小于0,则跳过执行cold_days++语句,while循环进行读取下一个值。
接着,在之后的语句中又执行了一次if语句来控制程序的输出。如果cold_days的值为0,则打印结果,反之,不打印。
if语句在程序流程中就相当于一个交叉点,程序需要在两条分支中选择一条执行。其通用形式如下:
if(表达式1)
语句1;
如果表达式1的值为真,则执行语句1,否则,不执行。一般来说表达式1是关系表达式(即x<=0,或y==1),而对于语句1来说,其可以简单语句,也可以是复合语句。
2.if...else语句
1)单选择if else
简单形式的if语句只能让程序选择执行一条语句,或者跳过这条语句。C语言还提供if...else形式,以便可以在两条语句之间作选择。
将上面的部分if语句转化为if...else语句:
if (cold_days != 0)
{
printf("%d were below freezing!\n", cold_days);
}
else
{
printf("No data entered!\n");
}
当执行到上面程序时,若cold_days不等于0,这执行打印天数的程序,当cold_days为0时,则执行打印警告信息程序。
另外需要注意,如果要在if和else之间执行多条语句,必须用花括号把这些语句括起来形成一个块。见下述程序:
编译器只会把第一条printf()语句视为if语句的一部分,而把第二条printf()语句看作单独的语句,它不是if语句的一部分。并发现没有与else配对的if。
2)多选择if else
在现实生活中我们要面对的情况往往有多种选择,而我们上述的if else语句仅仅在有两种情况下的使用。为了解决多选择的情况,我们需要对if else语句扩展一下。在考完试之后我们需要对学生的成绩划分为不同的等级,我们便可以使用if else来处理这种情况。
#include<stdio.h>
int main()
{
float score;
printf("请输入学生的成绩:\n");
scanf("%f", &score);
if (score >= 90 && score <= 100)
printf("该学生的成绩为:优");
else if (score >= 80 && score <= 89)
printf("该学生的成绩为:良");
else if (score >= 70 && score <= 79)
printf("该学生的成绩为:中");
else if (score >= 60 && score <= 69)
printf("该学生的成绩为:及格");
else if (score < 60)
printf("该学生的成绩为:不合格");
return 0;
}
输出示例如下:
3)else的悬空问题
在使用if else语句时最容易出错的便是在使用嵌套时else悬空。在嵌套使用if else语句时程序中可能会出现许多if和else,而编译器如何知道哪个if对应着哪个else呢?我们来看看下面这个例子。
if (x > 0)
if (y < 0)
printf("x与y不同号!\n");
else
printf("x与y同号!\n");
由程序运行的结果来看,上述程序的else与第二个if语句配对。即当x大于等于0时,执行printf("x与y同号!\n");语句,而我们想得到的结果是在x大于0的情况下,讨论y的值的情况。所以可知,else与if的配对的规则为,如果没有花括号,else与离它最近的if配对,除非最近的if被花括号括起来。见下图:
3.switch语句
在多选择的情况下虽然使用if...else语句可以实现,但是大多数情况下还是使用switch语句较为方便。switch语句也是一种分支语句,其通用形式如下:
switch(整型表达式)
{
case 整型常量表达式:
语句;
}
下面程序演示了如何使用switch语句。该程序通过输入2021年3月的任意一天来判断是这一天星期几。
#include<stdio.h>
int main()
{
int date;
printf("请输入2021年3月的任何一天:\n");
scanf("%d", &date);
if (date < 0 || date>31)
printf("请输入正确日期\n");
else
switch (date % 7)
{
case 6:printf("3/%d/2021是星期六 \n", date);
break;
case 5:printf("3/%d/2021是星期五 \n", date);
break;
case 4:printf("3/%d/2021是星期四 \n", date);
break;
case 3:printf("3/%d/2021是星期三 \n", date);
break;
case 2:printf("3/%d/2021是星期二 \n", date);
break;
case 1:printf("3/%d/2021是星期一 \n", date);
break;
default:printf("3/%d/2021是星期天 \n", date);
}
return 0;
}
程序先对switch括号后面的表达式求值,然后根据该值进行扫描标签(如上述程序的case 6:、case 5:等)列表,直到发现一个可匹配的值为止。然后程序跳转到所匹配的那一行语句执行。但是也会出现没有匹配的值的情况,这时有两种情况:
情况一:switch语句中有default标签,则程序跳转至该行执行。
情况二:switch语句中没有default标签,则程序执行switch后面的语句。
在switch语句中需要有一个注意的问题:break的使用
break语句在程序中起着什么?它让程序跳出switch语句而去执行switch语句后面的下一条语句。若把上述程序每个标签中的break删去,所得到的结果如下:
从上图可以看出当没有switch语句时,程序就会从匹配标签开始一直执行到switch末尾。所以对于break语句的使用我们需要根据不同的情况来使用。
switch与if...else的选择:
既然switch与if...else都具有对多选择情况的解决,那么我们该如何选择呢?
- 当根据浮点型的变量或表达式来选择时,就只能使用if...else语句
- 当根据变量在某范围内决定程序的去向时,使用if...else就比使用switch方便。
三、循环语句
在生活中我们有许多事情需要我们重复去做,如果我们编写重复的代码来解决重复的问题,那么就会使代码冗长。而循环语句就是为了解决这个问题。
1.while
while语句的通用形式如下:
while(表达式)
循环语句;
循环语句部分可以是直接以分号结尾的简单语句,也可以是用花括号括起来的复合语句。括号中表达式决定了是否进入while循环,当表达式的值为真时进入while循环,直至表达式的值为假退出循环。在表达式为假之前,循环的判断和执行一直都是重复进行,而每一次循环都被称为一次迭代。流程图表示如下:
在使用while循环时有一点非常重要:在使用while循环时,必须让测试表达式的值有所变化,表达式的值最终为假。我们前面说到循环是否终止取决于括号中表达式的值,若表达式的值一直为真,那么就会进入死循环,如下面这个程序:
int a = 1;
while (a)
{
printf("Love!");
}
这个程序段将打印无数次Love!
2.for
for循环是把初始化、测试、更新组合在一起的循环语句。其通用形式为:
for(表达式1;表达式2;表达式3)
循环语句;
- 表达式1:初始化部分,用于初始化循环变量。
- 表达式2:条件判断部分,用于判断循环时候终止。
- 表达式3:调整部分,用于循环条件的调整。
#include<stdio.h>
int main()
{
int i, sum = 0;
for (i = 1; i <= 100; i++)
sum = sum + i;
printf("sum=%d", sum);
return 0;
}
表达式1(i=1)初始化,只会在循环开始时执行一次,for循环每循环一次就会进行对表达式2部分判断,判断其为真还是为假,若为真继续循环,若为假,循环结束。如上程序,当i小于等于100时继续循环。表达式3(i++)为每次循环结束时求值。
for循环除了上述常规的用法外,还有常见的八种用法:
①可以使用递减运算符来递减计数器——for(i=5;i>0;i--)
②可以让计数器递增任何数值——for(i=0;i<60;i=i+5)
③可以用字符代替数字计数——for(ch='a';ch<‘z’;ch++)
④使用时若更关注限制立方的大小,可使用——for(a=1;a*a*a<=216;a++)
⑤可以让递增的量几何增长,而不是算数增长——for(n=1;n<100;n=n*5)
⑥表达式3可以使用容易合法的表达式——for(x=1;y<100;y=(++x*5)+1)
⑦可以省略一个或多个表达式(分号不能省略)
⑧第一个表达式不一定给变量赋值,也可以使用printf()。只执行一次。
3.do while
while循环和for循环都是入口条件循环,即在循环的每次迭代之前检查测试条件,当条件不符合时不会执行循环体中的程序。而C语言还有出口条件循环,即在循环每次迭代之后检查测试条件,这使得循环体中的内容至少被执行一次。这就是do while循环。
do while循环的通用形式如下:
do
循环语句;
while(表达式);
注意do while循环是以分号结尾。下面的程序是一个简单的do while循环的示例。
#include<stdio.h>
int main()
{
int i=1,sum=0;
do
{
sum=sum+i;
i=i+1;
}while(i<=100);
printf("sum=%d",sum);
return 0;
}
四、goto语句
在C语言中提供了可以随意滥用的goto语句和标记跳转的标号。
goto语句分为两部分goto和标签名。标签的命名遵循变量命名规则,
goto a;
而要上面的程序正常工作,还必须包含一条标为a的语句,该语句以标签名后面紧跟一个冒号开始:
a:printf("Good!");
goto语句只能在本函数中使用,不能跨函数使用。从理论上来说goto语句是没有必要的,因为在写代码时不需要goto语句也能很好地写出代码。
总结
本文主要介绍了C语言中重要的两种语句:分支语句与循环语句。其中分支语句主要讲解了if、switch、if else语句,而循环语句主要为while、do while以及for语句。这两种语句控制着程序的流程,我们需要理解并且熟练地掌握它们。