第6章 循环

英文原版:P99

在第5章里,我们介绍了C语言的选择语句:if语句和switch语句。

本章我们介绍C语言的循环语句。一个循环就是一条语句,该语句的作用就是重复地执行循环体。在C语言中,每个循环都有一个控制表达式。每次执行循环体时,会首先计算控制表达式的值:如果该表达式的值为真(非0值),则循环就继续执行。

C语言提供了3种迭代语句:

  • while语句
    在循环体执行前,测试控制表达式;
  • do语句
    在循环体执行后,测试控制表达式;
  • for语句
    适用于有自增或者自减计数变量值的循环;

本章内容

  • 6.1节介绍了while语句
  • 6.2节介绍了do语句
  • 6.3节介绍了for语句,逗号运算符
  • 6.4节介绍了break语句、continue语句、goto语句,其中break语句的作用是跳出循环体,将控制权交给在循环后的下一条语句;continue语句跳过一次循环迭代;goto的作用是跳转到函数内部的任何一条语句;
  • 6.5节介绍了null语句,用于控制有空循环体的循环。

while语句

在C语言的所有循环语句中,while语句时最简单且最基础的。

形式

while (表达式) 语句

解释:

  • 在括号里的表达式是控制表达式,在括号后的语句是循环体。
  • 括号是必需的,右括号跟循环体之间没有任何符号。

执行过程

  • 先求控制表达式e的值。
  • 如果控制表达式的值为0,则什么都不做,直接执行在while语句后的下一条语句。
  • 如果控制表达式e的值为非0,则执行循环体,且再次检查控制表达式。继续这种模式:先测试控制表达式的值,再执行循环体。直到控制表达式的值为0。

例1 计算大于n的最小的2的幂次方值

i = 1;
while (i < n){
    i = i * 2;
}

例2 递减计数

i= 10;
while (i > 0) {
    printf("T minus and counting\n", i);
    i--;
}

无穷循环

形式

while (1) 语句

程序示例1:打印平方表

源文件sqare.c

#include <stdio.h>

int main(void)
{
    int i, n;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");
    scanf("%d", &n);

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

    return 0;
}

程序示例2:对输入的数求和

源文件:sum.c

#include <stdio.h>

int main(void)
{
    int n, sum = 0;

    printf("This program sums a serial of integers.\n");
    printf("Enter integers (0 to terminate): ");

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


    return 0;
}

6.2节 do循环语句

形式:

do 语句 while (控制表达式);
执行:
当执行一个do语句时,首先执行循环体,然后求控制表达式的值。如果控制表达式的值为非0,则再次执行循环体,然后再次求控制表达式的值。直到某次循环体执行后,控制表达式的值为0,do语句的执行才终止。

例1 do语句示例

int i;

i = 10;
do {
  printf("T minus %d and counting\n", i);
  --i;
} while (i > 0);

程序示例:计算一个整数的数字个数

源文件numdigits.c

/*Calculates the number of digits in an integer */
#include <stdio.h>

int main(void){
  int digits = 0, n;

  printf("Enter a nonnegative integer: ");
  scanf("%d", &n);

  do {
    n /= 10;
    digits++;
  }while(n>0);

  printf("The number has %d digit(s).\n", digits);

  return 0;
}

6.3节 for循环语句

形式

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

例1 for循环

int i;

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

常用for循环语句范例

  • 从0到n-1

    for (i=0; i<n;i++) ...

  • 从1到n

for (i=1; i<=n;i++) ...

  • 从n-1到0

for (i=n-1; i>=0;i--) ...

  • 从n到1

for (i=n; i>0;i--) ...

逗号,运算符

形式

表达式1, 表达式2

求值
首先,对表达式1求值,然后丢弃该值;
然后,对表达式2求值,该值是整个表达式的值;

优先级

逗号运算符的优先级低于所有其他运算符

使用场合

  • 某些宏定义可从逗号表达式中受益;
  • for循环语句:两个或者多个初始化表达式;一次循环递增多个变量;

例1

int i,j;

i = 1;
j = 5;

++i, i+j;//整个表达式的值是7

例2

int i, sum;

sum = 0;
for (i=1; i<=N; i++){
  sum += i;
}

可使用逗号运算符改写为

for (sum=0, i=1; i<=N; i++){
  sum += i;
}

程序示例:打印平方数表

源文件 square2.c

/* Prints a table of squares using a for statement */
#include <stdio.h>

int main(void){
    int i, n;

    printf("This program prints a talbe of squares.\n");
    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;
}

square3.c

#include <stdio.h>
// This program prints a table of squares.
// Enter number of entries in table: 10
//          1         1
//          2         4
//          3         9
//          4        16
//          5        25
//          6        36
//          7        49
//          8        64
//          9        81
//         10       100

int main(void)
{
    int i, n, odd, square;

    printf("This program prints a table of squares.\n");
    printf("Enter number of entries in table: ");
    scanf("%d", &n);

    i = 1;
    odd = 3;

    for (square = 1; i <= n; odd += 2) {
        printf("%10d%10d\n", i, square);
        ++i;
        square += odd;
    }

    return 0;
}

6.4节 循环退出语句

首先,从循环中退出分为两种情况:

  • 正常退出;
  • 从循环体中退出;

正是因为有了从循环体中退出的需求,才会有专门的循环退出语句,比如break;

其次,
break语句实现了两个循环退出需求:

  • 从循环体中退出;
  • 循环语句中不止有一个退出点;

continue语句实现了不跳出循环跳过一次迭代的需求。

break语句

作用:

将程序的控制权转交到循环的结束执行的下一条指令;
跳出循环;

两种用法:

  • 从switch语句中退出
  • 从循环语句中退出,比如while、do、for等

使用场合

  • 循环的退出点是循环体的中间,而非循环开始或者结束;
  • 如果一个语句嵌套有while、do、for、switch语句,则break只能从最内层跳转出来,即一次只能跳转出一层嵌套。

例1 检测一个数是不是素数

for (d=2; d<n; d++){
  if (n%d == 0) {
    break;
  }
}

if (d < n) {
  printf("%d is divisible by %d\n", n, d);
}else {
  printf("%d is a prime\n");
}

例2 循环读取用户输入,直到碰到一个特殊的值

for(;;){
  printf("Enter a number (enter 0 to stop): ");
  scanf("%d", &n);
  if (n == 0) {
    break;
  }
}

例3 跳出一层嵌套语句

while(...){
  switch(...){
    ...
    break;
    ...
  }
}

continue语句

作用:

跳过当前的循环体执行,将程序的控制权转交下次循环体执行开始。
继续驻留在循环中。

使用场合:

  • 只能用于循环语句;

例1 continue用法

n = 0;
sum = 0;
while(n < 10){
  scanf("%d", &i);
  if (i == 0) {
    continue;
  }
  sum += i;
  n++;
}

或者

n = 0;
sum = 0;
while(n < 10){
  scanf("%d", &i);
  if (i != 0) {
    sum += i;
    n++;
  }
}

程序示例:账簿结算

许多交互式的程序都是基于菜单的:给用户展示一个可选择的命令列表。一旦用户选择了某个命令,该程序就执行期望的操作,然后等待着用户选择下一次命令。该程序直到用户选择了一个exit或者quit命令才结束执行。

这样一个程序的核心是一个循环。在循环内是有语句提示用户输入一条指令,读取该指令,执行该指令,比如

for (; ;) {
  语句提示用户输入指令;
  读取指令;
  执行指令;
}

执行指令需要switch语句,比如:

for (; ;) {
  语句提示用户输入指令;
  读取指令;
  switch(指令){
    case 指令1: 执行操作1;break;
    case 指令2: 执行操作2;break;
    .
    .
    .
    case 指令n: 执行操作n;break;
    default: 打印错误消息; break;
  }
}

开发一个账簿结算程序,需求是给用户提供给一个选择菜单:

  • 清空该账户余额,用0表示;
  • 向该账户里存钱,用1表示;
  • 从该账户里取钱,用2表示;
  • 展示余额,用3表示;
  • 退出程序,用4表示;

源文件checking.c

/** Balances a checkbook */

#include <stdio.h>

int main(void)
{
    int cmd;
    float balance = 0.0f, credit, debit;

    printf("*** ACME checkbook-balancing program ***\n");
    printf("Commands: 0=clear, 1=credit, 2=debit, ");
    printf("3=balance, 4=exit\n\n");

    for(; ;) {
        printf("Enter command: ");
        scanf("%d", &cmd);
        switch(cmd){
            case 0:
                balance = 0.0f;
                break;
            case 1:
                printf("Enter amount of credit: ");
                scanf("%f", &credit);
                balance += credit;
                break;
            case 2:
                printf("Enter amount of debit: ");
                scanf("%f", &debit);
                balance -= debit;
                break;
            case 3:
                printf("Current balance: %.2f\n", balance);
                break;
            case 4:
                return 0;
            default:
                printf("Commands: 0=clear, 1=credit, 2=debit, ");
                printf("3=balance, 4=exit\n\n");
                break;                  
        }
    }
}

6.5节 null语句

定义

除了末尾的分号外,什么都没有的语句。

比如

i = 0;
; //null语句
j = 1;

例2 使用null语句来改写循环

for (d=2; d<n; d++){
  if (n%d == 0) {
    break;
  }
}

改写为

for (d = 2; d < n && n%d !=0; d++){
  ;
}

错误的使用null语句

for (d = 2; d < n && n%d !=0; d++);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容