6 循环

6.1 while语句

语法:while(表达式)语句

  • 圆括号强制要求,循环体外面的大括号不强制要求使用(多个语句除外)
1
2
3
4
i = 10;
while(i > 0){
printf("T minus %d and counting\n", i);
}

6.1.1 无限循环

说明:如果控制表达式的值始终是非零值的话,while语句将无法终止。
技巧:c语言程序员有时故意用非零常量作为控制表达式来构造无限循环。

1
while(1) ...

6.1.2 程序:显示平方值的表格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Prints a table of squares using a while statement
*/

#include <stdio.h>
int main(){
int i, n;
printf("This program prints a table of ssquares.\n");
printf("Enter number of entries in table :");
scanf("%d", &n);
i = 1;
while(i <= n){
printf("%10d%10d\n", i, i*i);
i++;
}
return 0;
}
1
2
3
4
5
6
7
8
$ ./square                          
This program prints a table of ssquares.
Enter number of entries in table :5
1 1
2 4
3 9
4 16
5 25

6.1.3 程序:数列求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Sums a series of numbers
*/

#include <stdio.h>
int main(){
int n, sum = 0;
printf("This program sums a series of intergers.\n");
printf("Enter intergers (0 to terminate:)");

scanf("%d", &n);
while(n != 0){
sum += n;
scanf("%d", &n);
}
printf("The sun is:%d\n", sum);
return 0;

}
1
2
3
4
$ ./sum 
This program sums a series of intergers.
Enter intergers (0 to terminate:)1 2 3 4 0
The sun is:10

6.2 do语句

语法:do 语句 while(表达式);
语句说明:do语句的本质就是while语句,只不过do语句是在每次执行循环体之后对控制表达式进行判定的。
适用场景:至少要执行一次的循环体
注意:最好所有的do语句都适用大括号,因为没有大括号的do语句很容易被误认为while语句。

程序:计算整数中数字的位数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Calculates the number od digits in an interger
*/

#include <stdio.h>
int main(){
int digits = 0, n;
printf("Enter a nonnegative interger:");
scanf("%d",&n);
//如果使用while循环,输入0将导致判断错误(认为0为0位数字)
do{
n /= 10;
digits++;
}while(n > 0);
printf("The number has %d digit(s).\n", digits);
return 0;
}
1
2
3
$ ./numdigit 
Enter a nonnegative interger:20150621
The number has 8 digit(s).

6.3 for语句

语法:for (表达式1;表达式2;表达式3) 语句

1
2
3
for(i = 10;  i > 0; i--){
printf("T minus %d and counting\n", i);
}

while模拟for:

1
2
3
4
5
表达式1
while(表达式2){
语句
表达式3;
}

6.3.1 for语句的惯用法

1
2
3
4
5
6
7
8
//从0向上加到n-1
for(i = 0; i < n; i++)
//从1向上加到n
for(i = 1; i <= n ; n++)
//从n-1减到0
for(i = n-1; i >= 0; i--)
//从n减到1
for(i = n; i > 0; i--)

6.3.2 在 for语句中省略表达式

省略 语法 说明
表达式1 for(; 表达式2; 表达式3) 执行循环前没有初始化的操作
表达式2 for(表达式1; ; 表达式3) 表达式2默认为真值,无限循环
表达式3 for(表达式1; 表达式2;) 循环体有责任确认第二个表达式的值最终回变为假
表达式1、3 for(;表达式2;) while
表达式1、2、3 for(;;) 简单的无限循环

6.3.3 逗号运算符

语法:表达式1,表达式2
用途:为了在c语言要求单独一个表达式的情况下使用两个或多个表达式。
使用场景:宏、for循环
优先级:低于所有其它运算符。
计算过程:

  1. 计算表达式1并且仍低哦计算出的值
  2. 计算表达式2,把这个值作为整个表达式的值

注意:计算表达式1始终会有副作用;如果没有,那么表达式1就没有了存在的意义。

6.2.4 程序:显示平方值的表格(改进版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Prints a table of squares using a for statement
*/

#include <stdio.h>
int main(){
int i, n;
printf("This program prints a table of squares.");
printf("Enter number of entries in table:");
scanf("%d", &n);

for(i = 1; i <= n; i++){
printf("%10d%10d\n", i, i * i);
}
return 0;
}

6.4 退出循环

6.4.1 break语句

作用:把程序从switch语句中转移出来;跳出whiledofor循环。
注意:break只能跳出一层循环

1
2
3
4
5
6
for(;;){
printf("Enter a number (enter 0 to stop):");
scanf("%d", &n);
if(n == 0) break;
printf("%d cubed is %d\n", n, n*n*n);
}

6.4.2 continue 语句

作用:把程序控制正号转移到循环结束之前的一点;只能用于循环。

1
2
3
4
5
6
7
8
n = 0;
while(n < 10){
scanf("%d", &i);
if(i == 0)continue;
sun += i;
n ++;
/*continue jumps to here*/
}

6.4.3 goto语句

语法:

  • 标号语句:标识符 : 语句
  • goto语句:goto 标识符

注意:break continue return本质上都是受限制的goto语句,它们和exit函数配合可以应对大多数需要goto语句的情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
for(d = 2; d < n; d++){
if(n % d == 0){
//goto语句
goto done;
}
}
//标号语句
done:
if(d < n){
printf("%d is divisible by %d\n", n, d);
}else{
printf("%d is prime\n", n);
}

6.4.4 程序:账目簿结算

6.5 空语句

语法:;
用途:

  • 编写空循环体(在某些情况下帮助省略循环体)
  • goto语句的标号不能独立存在,后面必须有语句,可以使用空语句
1
2
for(d =2; d < n && n % d != 0; d++)
;/*empty body*/

注意:建议将空语句单独放在一行,便于代码阅读。