当前位置: C语言 -- 基础 -- 语句和块

语句和块(四)

七、迭代语句

C语言中迭代语句包括while语句、do语句和switch语句。


1、while语句

while语句具有以下语法格式:

while( controlling-expression ) secondary-block

其中controlling-expression是控制表达式,while语句中控制表达式应具有标量类型(scalar type);secondary-block是次块,也称为循环体(loop body);whileC语言关键词。


while语句流程图如下所示:

while语句流程图


每次执行循环体前,while语句中的控制表达式都会被评估;如果控制表达式的值等于0while语句结束;如果控制表达式的值不等于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是次块,也称为循环体;dowhileC语言关键词。


do语句流程图如下所示:

do语句流程图


每次执行循环体后,do语句中的控制表达式都会被评估;如果控制表达式的值等于0do语句结束;如果控制表达式的值不等于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是次块,也称为循环体;forC语言关键词。

clause-1expression-3都可以省略;如果省略expression-2expression-2视为使用非0常量替代,该非0常量是常量表达式。

for( ; ; ) //等价于for( ; 1; )。

for语句流程图如下所示:

for语句流程图


如果子句-1是声明,声明标识符的作用域为声明的剩余部分、表达式-2、表达式-3以及循环体。如果子句-1是表达式,表达式将在控制表达式评估前作为void类型表达式评估。

每次执行循环体前,for语句中的控制表达式都会被评估;如果控制表达式的值等于0for语句结束;如果控制表达式的值不等于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语句进行优化,例如:即使无法证明终止条件成立,仍可移去空循环,因为编译器可假设循环最终会终止。