语句和块(四)
七、迭代语句
C语言中迭代语句包括while语句、do语句和switch语句。
1、while语句
while语句具有以下语法格式:
while( controlling-expression ) secondary-block
其中controlling-expression是控制表达式,while语句中控制表达式应具有标量类型(scalar type);secondary-block是次块,也称为循环体(loop body);while是C语言关键词。
while语句流程图如下所示:
每次执行循环体前,while语句中的控制表达式都会被评估;如果控制表达式的值等于0,while语句结束;如果控制表达式的值不等于0,将执行循环体。循环体会被反复执行,直至控制表达式的值等于0。
int i = 3; //循环体会被执行三次。 while(i>0) { printf("i = %d\n", i--); }
while语句的循环体可以通过while迭代语句进入,也可以跳转进入。通过跳转方式进入循环体,跳过的代码不会被执行。
int i = 3; goto here; while(i>0) { i--; here : printf("i = %d\n", i); }
上述代码中循环体会被执行四次,第一次执行从标签here :处开始(第一次执行控制表达式i>0不会被评估,语句i--;不会被执行。);上述代码将输出:
i = 3 i = 2 i = 1 i = 0
如果while语句的控制表达式不是常量表达式,并且其循环体和控制表达式未执行以下操作,实现(编译器)可以假定该while语句会终止:
-- 输入/输出操作。
-- 访问volatile对象。
-- 同步或者原子操作。
该规则允许编译器对控制表达式是非常量表达式的while语句进行优化,例如:即使无法证明终止条件成立,仍可移去空循环,因为编译器可假设循环最终会终止。
2、do语句
do语句具有以下语法格式:
do secondary-block while( controlling-expression );
其中controlling-expression是控制表达式,do语句中控制表达式应具有标量类型;secondary-block是次块,也称为循环体;do和while是C语言关键词。
do语句流程图如下所示:
每次执行循环体后,do语句中的控制表达式都会被评估;如果控制表达式的值等于0,do语句结束;如果控制表达式的值不等于0,将执行循环体。循环体会被反复执行,直至控制表达式的值等于0。
int i = 3; //循环体会被执行三次。 do { printf("i = %d\n", i--); }while(i>0);
do语句的循环体可以通过do迭代语句进入,也可以跳转进入。通过跳转方式进入循环体,跳过的代码不会被执行。
int i = 3; goto here; do { i--; here : printf("i = %d\n", i); }while(i>0);
上述代码中循环体会被执行四次,第一次执行从标签here :处开始(第一次执行语句i--;不会被执行。);上述代码将输出:
i = 3 i = 2 i = 1 i = 0
如果do语句的控制表达式不是常量表达式,并且其循环体和控制表达式未执行以下操作,实现(编译器)可以假定该do语句会终止:
-- 输入/输出操作。
-- 访问volatile对象。
-- 同步或者原子操作。
该规则允许编译器对控制表达式是非常量表达式的do语句进行优化,例如:即使无法证明终止条件成立,仍可移去空循环,因为编译器可假设循环最终会终止。
3、for语句
for语句具有以下语法格式:
for( clause-1opt; expression-2opt; expression-3opt ) secondary-block
其中clause-1;是子句,子句可以是声明,也可以是表达式语句,clause-1指定循环的初始化操作;expression-2是控制表达式,for语句中控制表达式应具有标量类型;expression-3是表达式,指定每次迭代后执行的操作(例如:递增操作、递减操作等。);secondary-block是次块,也称为循环体;for是C语言关键词。
clause-1和expression-3都可以省略;如果省略expression-2,expression-2视为使用非0常量替代,该非0常量是常量表达式。
for( ; ; ) //等价于for( ; 1; )。
for语句流程图如下所示:
如果子句-1是声明,声明标识符的作用域为声明的剩余部分、表达式-2、表达式-3以及循环体。如果子句-1是表达式,表达式将在控制表达式评估前作为void类型表达式评估。
每次执行循环体前,for语句中的控制表达式都会被评估;如果控制表达式的值等于0,for语句结束;如果控制表达式的值不等于0,将执行循环体。每次执行循环体后,表达式-3作为void类型表达式评估。循环体会被反复执行,直至控制表达式的值等于0。
//循环体会被执行三次。 for(int i=0; i<3; i++) { printf("i = %d\n", i); }
for语句的循环体可以通过for迭代语句进入,也可以跳转进入。通过跳转方式进入循环体,跳过的代码不会被执行。
int i = -1; goto here; for(i=0; i<3; i++) { here : printf("i = %d\n", i); }
上述代码中循环体会被执行四次,第一次执行从标签here :处开始(第一次执行语句i=0;不会被执行,控制表达式i<3不会被评估。);上述代码将输出:
i = -1 i = 0 i = 1 i = 2
如果for语句的控制表达式不是常量表达式,并且其循环体、控制表达式以及表达式-3未执行以下操作,实现(编译器)可以假定该for语句会终止:
-- 输入/输出操作。
-- 访问volatile对象。
-- 同步或者原子操作。
该规则允许编译器对控制表达式是非常量表达式的for语句进行优化,例如:即使无法证明终止条件成立,仍可移去空循环,因为编译器可假设循环最终会终止。