C_语句

C_语句
BarbecueC_语句
在C语言中,语句可以分为以下几种类型:
- 标签语句:可以通过标签来标记一个语句。C语言中有三种类型的标签:简单标识符后跟冒号(用于goto语句的目标)、
case
和default
标签(用于switch
语句中)。 - 复合语句:也称为块语句,是将多个语句和声明用大括号
{
}
括起来,形成一个单独的语句块。函数体也是一种复合语句。 - 表达式语句:由一个可选的表达式后跟分号
;
构成。如果存在表达式,则该语句可能有值。没有表达式的情况下,语句通常被称为空语句。 - 选择语句:包括
if
语句和switch
语句,用于根据表达式的值选择执行不同的语句块。 - 迭代语句:包括
while
、do-while
和for
语句,用于重复执行某段代码直到满足特定条件。 - 跳转语句:包括
goto
、break
、continue
和return
语句,用于无条件地改变程序的控制流。
选择语句
布尔值
最初的c语言缺少布尔类型。在 C99 中,定义了 _Bool
类型, _Bool
类型的变量只能赋值为 0
或 1
。往 _Bool
类型中存储非零值,会导致该变量赋值为 1
。
1 | _Bool flag = 5; /* flag is assigned 1 */ |
C99 中还提供了一个新的头文件 stdbool.h
,该头文件定义了 bool
宏,用它来表示_Bool
;该头文件还定义了 true
和 false
两个宏,它们分别代表 1
和 0
。
1 |
|
if
语句
if
语句:
1 | if (expr) {statement;} |
if
语句 else
子句:
1 | if (expr) |
级联式 if
语句:
1 | if (expr) |
悬空 else
问题:
else
子句应该属于离它最近的,且还没有和其它 else
匹配的 if
语句。为了使 else
子句属于外层的 if
语句,需用花括号将内层的 if
语句括起:
1 | if (y != 0) |
条件表达式
C 语言的一种特殊的运算符——条件运算符,条件运算符由 ?
和 :
组成,其格式如下:
1 | expr1 ? expr2 : expr3 |
条件运算符是 C 语言中唯一一个三目运算符。
条件表达式的求值步骤是:首先计算 expr1
的值,如果该值不为 0
,则计算 expr2
的值,并且把 expr2
的值当作整个表达式的值;如果 expr1
的值为 0
,那么计算 expr3
的值,并把 expr3
的值当作整个表达式的值。
1 | int i, j, k; |
最后一条语句的圆括号是必须的,三目运算符的优先级只比赋值运算符的优先级高一点。
switch
语句
switch
语句的执行速度比 if
语句快。 switch
语句比级联式 if
语句更容易阅读。
switch
语句:
1 | switch (expr) { |
switch
语句的组成成分:
控制表达式: switch
后边表达式的值必须是整数类型。字符类型也当作整数来处理, switch
语句也可以对字符类型进行判定。但不能判定浮点数和字符串(浮点数存在精度问题,字符串会增加编译器的实现复杂性)。
分支标号:case
后边必须跟常量表达式(在编译期间求值的表达式),并且常量表达式的值必须是整数、字符类型。
语句:每个case
标签后可以跟任意数量的语句(不需要用大括号括起来),通常每组语句的最后会有一个break
语句,用于跳出switch
语句的执行。
Tips:
- C 语言不允许有重复的分支标号,但对分支的顺序没有要求,特别是
default
分支不一定要放到最后。switch
语句不要求一定要有default
分支。- 当
default
不存在,而且控制表达式的值和任何一个分支标号都不匹配,控制会直接传递给switch
后面的语句。
case
穿透:一个分支的最后没有 break
语句,控制会从一个分支继续到下一个分支。
1 | switch (grade) { |
如果grade
的值为 3
,会显示:Good Average Poor Illegal grade
。
循环语句
每个循环语句都有一个控制表达式。每次执行循环体时,都要对控制表达式求值。如果表达式为真,那么继续执行循环语句;否则执行循环语句的下一条语句。
while
语句
while
语句:控制表达式是在每次执行循环体之前进行判定。
1 | while (expr) |
无限循环:控制表达式 expr
的值始终非零, while
语句将永远执行下去。
do...while
语句
do...while
语句:控制表达式是在每次执行完循环体之后进行判定。
1 | do |
do...while
语句和 while
语句的唯一区别:do...while
语句的循环体至少会执行一次,而 while
语句在控制表达式的值初始为 0
时,一次都不会执行。
for
语句
for
语句:非常适合递增或递减计数变量的循环
1 | for (expr1; expr2; expr3) |
expr1
是循环开始执行前的初始化步骤,只执行一次expr2
是控制循环的控制表达式expr3
是每次循环中最后被执行的一个操作。
省略 for
语句中的的表达式:
- 省略
expr1
,在执行循环前没有初始化的操作。 - 省略
expr2
,expr2
的值默认为真,无限循环。 - 省略
expr3
,循环体需要确保expr2
的值最终会变成0
。 - 同时省略
expr1
和expr3
时,for
语句和while
语句一样。
for
语句的第一个表达式可以替换为声明一个或多个用于循环的变量:
1 | for (int i = 0, j = 0; i < n; i++) |
变量 i
不需要在该语句前进行声明。如果变量 i
在之前已经进行了声明,这个语句将创建一个新的 i
,且该变量只能在循环内使用。( for
语句声明的变量在循环外是不可见。)
逗号表达式
逗号表达式允许在一个语句中同时执行多个表达式,并以逗号分隔。逗号表达式的值是最后一个表达式的值。逗号表达式的格式如下:
1 | expr1, expr2, ..., exprn |
逗号表达式的求值:逗号表达式是左结合的,逗号表达式从左到右依次执行,每个表达式都会被依次计算并丢弃其值,最终的结果是最后一个表达式的值。
作用:
- 在
for
循环中初始化和更新多个变量。 - 在一个语句中执行多个操作,例如执行一系列函数调用或变量赋值,并只保留最后一个表达式的值。
跳转语句
C语言提供了四种跳转语句:break
、continue
、goto
和return
。
break
语句
break
可以跳出 switch
, while
, do...while
和 for
语句。当语句嵌套时,break
只能跳出包含 break
语句的最内层嵌套。
1 | while (...) { |
continue
语句
continue
语句与break
语句对比:
break
语句会把控制转移到整个循环的后面,而continue
会将控制转移到循环体的末尾。break
语句会跳出循环,而continue
语句仍然留在循环体内。break
语句可以用于switch
语句和循环,而continue
只能用于循环。在
for
循环中,执行continue
后会跳到循环的更新表达式;在while
和do-while
循环中,执行continue
后会跳到循环的条件判断。1
2
3
4
5for (int i = 0; i < 5; i++) {
if (i == 2) continue;
printf("i=%d\n", i);
}
// 输出:i=0 i=1 i=3 i=4
goto
语句
goto
语句可以跳转到函数中任何有标号的语句处。唯一限制只能在函数内进行跳转。
标号是放置在语句开始处的标识符:
1 | identifier: |
goto语句的格式如下:
1 | goto identifier; |
使用goto
可以实现从深层嵌套结构中跳出,但过多使用会使程序结构混乱,不易理解和维护。
1 | if (error) goto error_handler; |
return
语句
return
语句用于结束函数的执行,并将控制权返回给函数的调用者。如果函数声明了返回类型,return
语句还可以返回一个值。
return
可以在函数的任何位置使用,一旦执行,函数的剩余部分将不会被执行。
1 | int add(int a, int b) { |