C chapter3 语句


空语句

C 最简单的语句就是空语句,它本身只包含一个分号。空语句本身并不执行任何任务,但有时还是有用的。它所适用的场合就是语法要求出现一条完整的语句,但并不需要它执行任何任务。

表达式语句

C 并不存在专门的 “赋值语句”,它通过表达式进行赋值。
只需要在表达式后面加上一个分号,就可以把表达式转变为语句。

1
2
x=y+3;
ch=getchar();

实际上是表达式语句,而不是赋值语句。

警告:理解这点很重要,因为像下面这样的语句也是完全合法的:

1
2
y+3;
getchar()

所谓语句 ”没有效果“ 只是表达式的值被忽略。printf函数所执行的是有用的工作,这类作用称为 ”副作用(side effect)“。

代码块

代码块就是位于一对花括号之内的可选的声明和语句列表。

1
2
3
4
{
declarations
statemente
}

if语句

1
2
3
4
if(expression){
statement
}else
statement

括号是if语句的一部分,而不是表达式的一部分,因此它是必须出现的,即使是那些极为简单的表达式也是如此。

while语句

1
2
3
while(expression){
statement
}

循环的测试在循环体开始执行之前开始,所以如果测试的结构一开始就是假,循环体就根本不会执行。同样,当循环体需要多条语句来完成任务时,可以使用代码块来实现。

break和continue语句

while循环中可以使用break语句,用于永久终止循环。在执行完break语句之后,执行流下一条执行的语句就是循环正常结束后应该执行的那条语句。

while循环中也可以使用continue语句,它用于永久终止当前的那次循环。在执行完continue语句之后,执行流接下来就是重新测试表达式的值,决定是否继续执行循环。

这两条语句的任何一条如果出现于嵌套的循环内部,它只对最外层的循环起作用,你无法使用breakcontinue语句影响外层循环的执行。

while语句的执行过程

提示:偶尔,while语句在表达式中就可以完成整个语句的任务,于是循环体就无事可做。在这种情况下,循环体就用空语句来表示。单独用一行来表示一条空语句是比较好的做法,如下面的循环所示,它丢弃当前输入行的剩余字符。

1
2
while((ch=getchar())!=EOF && ch!='\n')
;

for语句

C的for语句比其它语言的for语句更为常用,事实上,C的for语句是while循环的一种极为常用的语句组合形成的简写法。for语句的语法如下所示:

1
2
for(expressionl;expression2;expression3)
statement

for语句中也可以使用break语句和continue语句。break语句立即退出循环,而continue语句把控制流直接转移到调整部分。

for语句的执行过程

for语句和while语句执行过程的区别在于出现continue语句时。在for语句中,continue语句跳过循环体的剩余部分,直接回到调整部分。在while语句中,调整部分是循环体的一部分,所以continue将会把它也跳过。

do语句

C语言的do语句非常像其他语言的repeat语句。它很像while语句,只是它的测试在循环体执行之后才进行,而不是先于循环体执行。所以,这种循环的循环体至少执行一次。下面是它的语法。

1
2
3
do 
statement
while(expression)

当你需要循环体至少执行一次时,选择do

switch语句

C的switch语句颇不寻常。它类似于其他语言的case语句,但在有一个方法存在重要的区别。首先让我们来看看它的语法,其中expression的结果必须是整型值。

1
2
switch(expression)
statement

尽管在switch语句体内只使用一条单一的语句也是合法的,但这样做毫无意义。

实际使用中的switch语句一般如下所示:

1
2
3
switch(expression){
statement-list
}

贯穿于语句列表之间的是一个或多个case标签,形式如下:

1
case constant-expression:

每个case标签必须有一个唯一的值。常量表达式(constant-expression)是指在编译期间进行求值的表达式,它不能是任何变量。这里不同寻常之处是case标签并不把语句列表划分为几个部分,它们只是确定语句列表的进入点。

首先计算expression的值,然后执行流跳转到匹配的语句。之后执行到底部。

switch中的break语句

如果在switch语句的执行中遇到了break语句,执行流就会立即跳到语句列表的末尾。

1
2
3
4
5
6
7
8
9
switch(command){

case 'A':
add_entry();
break;
case 'B':
delete_enery();
break;
}

break语句的实际效果是把语句列表划分为不同的部分。这样,switch语句就能够按照更为传统的方式工作。

switch语句中,continue语句没有任何效果。只有当switch语句位于某个循环内部时,你才可以把continue语句放在switch语句内。在这种情况下,与其说,continue语句作用于switch语句,还不如它作用于循环。

default子句

我们在case标签后面加上一个default。当switch表达式的值并不匹配所有case标签的值时,这个default子句后面的语句就会执行。

每个default语句中只能出现一条default子句。

1
default:

提示:在每个switch语句中都放上一条default子句是个好习惯。

switch语句的执行过程

在处理四个以上分支时,switch语句就是查找表。

goto语句

语法:

1
goto 语句标签;

要使用goto语句,你必须在你希望调跳转的语句前面加上语句标签。语句标签就是标识符后面加个冒号。包含这些标签的goto语句可以出现在同一个函数中的任何位置。

注意:goto需要谨慎使用。