Warning:
为了避免非零基础人群感到身体不适、头晕恶心、易怒及粗口,请不要查看以下内容。
第三章详细讲述常用控制流语句,包含:if-else语句、else-if语句、switch语句、while循环与for循环、do-while循环、break语句与continue语句以及goto语句与标号。
文章目录
第3章 控制流
3.1 语句与程序块
在x=0、i++或printf(…)这样的表达式之后加上一个分号,它们就变成了语句。例如:
x=0;
i++;
printf(…);
在C语言中,分号是语句结束符,而Pascal等语言却把分号用作语句之间的分隔符。
用一堆花括号“{”与“}”把一组声明和语句括在一起就构成了一个复合语句(也叫作程序块),复合语句在语法上等价于单条语句。函数体中被花括号括起来的语句便是明显一例。if、else、while与for之后被花括号括住的多条语句也是类似的例子。(在任何程序块中都可以声明变量,第4章将对此进行讨论。)右花括号用于结束程序块,其后不需要分号。
3.2 if-else语句
if-else语句用于条件判定。其语法如下:
if(表达式)
语句1
else
语句2
其中else部分是可选的。该语句执行时,先计算表达式的值,若其值为真(非0),则执行语句1,若其值为假,则执行语句2。
因为else部分是可选的,所以在嵌套的if语句中省略它的else部分容易产生歧义,解决的办法是将每个else与最近的前一个没有else的配对的if进行匹配。
3.3 else-if语句
在C语言中常用到下列结构:
if(表达式)
语句
else if(表达式)
语句
else if(表达式)
语句
else
语句
这种if语句序列是编写多路判定最常用的方法。其中的各表达式依次求值,若为真,则执行与之相关的语句并终止整个语句序列的执行。
最后一个else用于处理“上述表达式均不成立”的情况或默认情况。有时候并不需要针对默认情况进行显式的操作,这种情况下,可以省略最后一个else部分。
3.4 switch语句
switch语句是一种多路判定语句,它测试表达式是否与一些常量整数值中的某一个值匹配,并执行相应的分支动作。
switch(){
case 常量表达式:语句序列
case 常量表达式:语句序列
default:语句序列
}
每一个分支都由一个或多个整数值常量或常量表达式标记。如果某个分支与表达式的值匹配,则从该分支开始执行。各分支表达式必须互不相同。如果没有拿一分支能匹配表达式,则执行标记为default的分支。default分支是可选的。如果没有default分支也没有其它分支与表达式匹配,则该switch语句不执行任何动作。各分支以及default分支的排列顺序是任意的。
3.5 while循环与for循环
我们在前面已经使用过while循环与for循环语句。
在while循环语句中:
while(表达式)
语句
首先计算表达式的值,如果表达式的值为真则执行语句,并再次计算表达式的值。直到表达式的值为假时,停止执行循环并执行循环后面的部分。
在for循环语句中:
for(表达式1: 表达式2: 表达式3)
语句
它等价于下列用while编写的代码:
表达式1;
while(表达式2){
语句
表达式3:
}
但当while或for循环中包含continue语句时,上述二者就不一定等价了。(即将学习continue语句)
从语法角度看,for循环语句的3个组成部分都是表达式。最常见的情况是,表达式1与表达式3是赋值表达式或函数调用,表达式2是关系表达式。这3个组成部分中的任何部分都可以省略,但分号必须保留。如果在for语句中省略表达式1与表达式3,它就退化成了while循环语句。如果省略表达式2,则认为其值永远是真值。
3.6 do-while循环
while与for这两种循环在循环体执行前对终止条件进行测试,与之相反,C语言中的第三种循环——do-while循环则在循环体执行后测试终止条件,这样保证循环体至少被执行一次。
do-while语句的语法形式如下:
do
语句
while(表达式);
在这一结构中,先执行循环体中的语句部分,然后再求表达式的值。如果表达式的值为真则再次执行语句,否则循环终止。
3.7 break语句与continue语句
不通过循环头部或循环尾部的条件测试而跳出循环,有时是很方便的。break语句可用于从for、while与do-while等循环中提前退出,从switch语句中提前退出一样。break语句可以使程序从switch语句或最内层循环中立即跳出。
continue语句与break语句是相关联的,但它没有break语句常用。continue语句用于使for、while或do-while语句开始下一次循环的执行。在while与do-while语句中,continue语句的执行一位置立即开始执行测试部分;在for循环中,则意味着使控制转移到递增循环变量部分。continue语句只用于循环语句,不用于switch语句。某个循环包含的switch语句中的continue语句,将导致进入下一次循环。
3.8 goto语句与标号
最后,我们介绍下C语言提供的可随意滥用的goto语句以及标记跳转位置的标号。从理论上讲,goto语句是没有必要的,实践中不使用goto语句也可以容易的写出代码。
但是,在某些场合下goto语句还是用得着的。最常见的用法是终止程序在某些深度的嵌套结构中的处理过程,例如一次跳出两层或多层循环。这种情况下使用break语句是不能直接达到目的的,它只能从最内层循环跳出到上一级的循环。
下面是goto语句使用的一个例子:
for( ... )
for(...){
...
if(disaster)
goto error;
}
...
error:
处理错误情况
在该例子中,如果错误处理代码很重要,并且错误可能在多个地方出现,使用goto语句将会比较方便。
标号的命名同变量的命名形式相同,标号的后面要紧跟一个冒号。标号可以位于对应的goto语句所在函数的任何语句的前面。标号的作用域是整个函数。
所有使用了goto语句的程序代码都能改写成不带goto语句的程序,但可能会增加一些额外的重复测试或变量。
大多数情况下,使用goto语句的程序更加难以理解和维护,少数情况除外。尽管该问题并不太严重,但我们还是建议尽量少使用goto语句,避免对goto语句产生依赖。
总结
本章的内容到此就结束了。本章学习了 语句与程序块的概念、if-else与else-if语句、for\while\do-while循环、switch语句、break与continue语句、goto语句与标号 较其他部分来看,本章所学习的控制流语句都较为简单,但是它们都是C语言的核心。一定要打牢基础,为后面的学习提供坚实的保障。