欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第四章 循环结构程序设计

程序员文章站 2022-05-07 17:24:52
...

第一节 while循环语句

  • C语言包含3大基本结构:顺序结构、选择结构、循环结构(重复结构)。大多数的应用程序都会包含循环结构。循环结构顺序结构选择结构是结构化程序设计的3种基本结构,它们是各种复杂程序的基本构成单元。

  • while语句的一般形式:while (表达式) 语句

  • 只要当循环条件表达式为真(即给定的条件成立),就立即执行循环体语句。

    • 练习:实现将公元0年~10000年的所有闰年都打印出来。

    • 第四章 循环结构程序设计

    • #include <stdio.h>
      int main() {
          int year = 0;
          while (year <= 10000) {
              if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
                  printf("%d年是闰年\n", year);
              ++year;
          }
          return 0;
      }

第二节 do···while循环语句

  • 除了while语句以外,C语言还提供了do···while语句来实现循环结构。

  • do ··· while 语句的一般形式为:

    • 第四章 循环结构程序设计
  • do ··· while 语句的执行过程是:先执行循环体,然后再检查条件是否成立,若成立,再执行循环体。

  • do ··· while 语句的特点:先无条件的执行循环体,然后再判断循环条件是否成立,如果成立,返回到语句继续执行。如果不成立,则结束do···while,继续向下执行剩余代码。

  • 练习:求1+2+3+···+n的和,n由用户输入

    • #include <stdio.h>
      int main() {
      	int i = 1, n, sum = 0;
      	printf("请输入要求多少的累加和\n");
      	scanf("%d", &n);
      	do {
      		sum += i;
      		i++;
      	} while (i <= n);
      	printf("1~%d的累加和为:%d\n", n, sum);
      	return 0;
      }

第三节 用for语句实现循环

  • 除了while语句和do···while语句实现循环体外,C语言还提供了for语句实现循环,而且for语句更为灵活,不仅可以用于循环次数已经确定的情况,还可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替while语句。

    • 第四章 循环结构程序设计
  • for语句的一般形式:

    • 第四章 循环结构程序设计
    • 表达式1:设置初始条件,只执行1次。可以为零个、一个或多个变量设置初值(如i = 1)。
    • 表达式2:循环条件表达式,用来判定是否继续循环,在每次执行循环体前先执行此表达式,决定是否继续执行循环。
    • 表达式3:作为循环的调整,例如使循环变量增值,它是在执行完循环体后才进行的。
  • 最常用的for语句形式是:

    • 第四章 循环结构程序设计
  • 代码示例

    • #include <stdio.h>
      int main() {
          int year = 0;
          for (; year <= 10000;  ++year) {
              if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
                  printf("%d年是闰年\n", year);
          }
          return 0;
      }
  • 说明:

      1. for语句的一般形式如下:for (表达式1;表达式2;表达式3) 语句,可以改写为while循环的形式如下,二者无条件等价。
      • 第四章 循环结构程序设计
      1. 表达式1可以省略,即不设置初值,但表达式1后面的分号不能省略,代表空语句,例如for (; i <= 100; i++)

      2. 表达式2也可以省略,即不用表达式2来作为循环条件表达式,不设置和检查循环的条件,如for (i = 1;;i++),此时循环无终止地进行下去,也就是认为表达式2始终为真,即死循环。

      3. 表达式3也可以省略,但此时程序设计者应另外设法保证循环能正常结束,例如:

        for (i = 1; i<= 100;) {//没有表达式3
            sum += i;
            i++;//在循环体中使循环变量增值
        }
      4. 如果表达式1和表达式3都没有,只有表达式2,即只给循环条件,但是应当在for语句前给循环变量赋初值,否则无法正常执行,如:

        int i = 1;
        for (; i <= 100;) {
            sum += i;
            i++;
        }
      5. 甚至可以将3个表达式都省略,即不设初值,不判断条件(认为表达式2为真值),循环变量也不增值,无终止地执行循环体语句,没有实用价值,如:

        for (; ;) printf("%d\n", i);

        相当于:

        while (1) printf("%d\n", i);
      6. 表达式1可以是设置循环变量初值的赋值表达式,也可以是与循环变量无关的其他表达式,如:

        for (sum = 0; i <= 100; i++) sum += i;

        表达式3也可以是与循环控制无关的任意表达式。但不论怎样写for语句,都必须使循环能正常运行。

      1. 表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式,即包含一个以上的简单表达式,中间用逗号间隔,如:
      for (sum = 0,i = 0; i <= 100; i++) sum += i;

      for (i = 0, j = 100; i <= j; i++, j--) k = i + j;

      表达式1和表达式3都是逗号表达式,各包含两个赋值表达式,即同时设两个初值(i = 0, j = 100),使两个变量增值(i++, j–),在逗号表达式内按自左至右顺序求解,整个逗号表达式的值为最右边表达式的值。

      1. 表达式2一般是关系表达式(如i <= 100)或逻辑表达式(如a<b && x<y),但也可以是数值表达式或字符表达式,只要其值非零,就执行循环体。如:
      for (i = 0; (c = getchar()) != '\n'; i += c);

      在表达式2中先从终端接收一个字符赋给c,然后判断此赋值表达式的值是否不等于’\n’(换行符),如果不等于’\n’,就执行循环体。改行代码的作用是不断输入字符,将它们的ASCII码相加,直到输入一个换行符为止。此for语句的循环体为空语句,把本来要在循环体内处理的内容放在表达式3中,作用是一样的。

      for (; (c = getchar()) != '\n';) printf("%c\n", c);

      for语句中只有表达式2,没有表达式1和表达式3。其作用是每读入一个字符后立即输出该字符,直到输入一个“换行”为止。

      1. C99允许在for语句的“表达式1”中定义变量并赋初值,如:
      for (int i = 1; i <= 100; i++) sum += i;

      显然,这可以使程序简练,灵活方便。但应注意:所定义的变量的有限范围只限于for循环中,在循环外不能使用此变量。

第四节 循环的嵌套

  • 一个循环体内又包含另一个完整的循环结构,称为循环的嵌套。内嵌的循环中还可以嵌套循环,这就是多层嵌套。

  • 第四章 循环结构程序设计

  • 注意:嵌套循环,将内层循环执行完之后执行一次外层循环。

  • 几种循环的比较:

      1. 3种循环都可以用来处理同一问题,一般情况下可以互相替换。
      2. for语句中包含了3个表达式,而while语句只有一个表达式。
      3. for语句可以对值进行初始化,for语句更加强大。
  • 练习:打印九九乘法表

    • #include <stdio.h>
      int main() {
      	int i, j;
      	for (i = 1; i <= 9; i++) {
      		for (j = 1; j <= i; j++)
      			printf("%d*%d=%2d\t", i, j, i * j);
      		printf("\n");
      	}
      	return 0;
      }
  • 嵌套循环实现时钟

    • #include <stdio.h>
      #include <Windows.h>
      int main() {
      	int h, m, s;
      	for (h = 0; h <= 24; ++h) {
      		for (m = 0; m <= 60; ++m) {
      			for (s = 0; s <= 60; ++s) {
      				Sleep(100);
      				printf("\r%dh-%dm-%ds", h, m, s);//  \r让打印的内容在当前行进行显示
      			}
      		}
      	}
      	return 0;
      }

第五节 改变循环执行的状态

  • 用break语句提前终止循环

    • break语句可以使流程跳出switch结构,继续执行switch语句下面的一个语句。实际上,break语句还可以用来从循环体内跳出当前循环体,即提前结束循环,接着执行循环下面的语句。

    • 练习:计算1+2+3+···+n,一直累加,当值大于n(n由用户输入)时,打印一共累加了几个数,并结束程序?

    • #include <stdio.h>
      int main() {
      	int i, sum, n;
      	scanf("%d", &n);
      	for (i = 1, sum = 0;; i++) {
      		sum += i;
      		if (sum > n) {
      			printf("一共累加了%d个数\n", i);
      			break;
      		}
      	}
      	return 0;
      }
  • 用continue语句提前终止循环

    • continue语句用来跳出本次循环的剩余部分,继续进行下一轮循环。

    • 练习1:求斐波那契数列前40个数,特点:第1,2个数为1,从第3个数开始,该数是前面两个数之和

    • #include <stdio.h>
      int main() {
          int f1 = 1, f2 = 1, f3, i;
          printf("%d\n%d\n", f1, f2);
          for (i = 1; i <= 38; i++) {
              f3 = f1 + f2;
              printf("%d\n", f3);
              f1 = f2;
              f2 = f3;
          }
          return 0;
      }
    • 练习2:输入一个大于3的整数n,判断它是否为素数

    • #include <stdio.h>
      int main() {
      	int i, n;
      	printf("请输入一个数字:\n");
      	scanf("%d", &n);
      	for (i = 2; i < n; i++)
      		if (n % i == 0) break;
      	if (i < n)
      		printf("%d不是素数\n", n);
      	else
      		printf("%d是素数\n", n);
      	return 0;
      }
    • 练习3:判断100以内的所有素数

    • #include <stdio.h>
      int main() {
      	int i, n = 2;
      	while (n <= 100) {
      		for (i = 2; i <= n; i++)
      			if (n % i == 0) break;
      		if (i < n)
      			printf("%d不是素数\n", n);
      		else
      			printf("%d是素数\n", n);
      		++n;
      	}
      	return 0;
      }