衡庐浅析·C语言程序设计·第三章·三种基本结构之循环结构

       本文适用于大学的期中期末考试、专升本(专接本、专插本)考试、408等考研预科。如有相关题目疑问或建议欢迎在评论区进行互动。

       转载请标明出处。


今天我们来学习本章节的最后一个知识点,循环结构(重复结构)。

循环结构

循环结构是指在程序中需要反复执行某个功能而设置的一种程序结构。它由循环体中的条件,判断继续执行某个功能还是退出循环。根据判断条件,循环结构又可细分为以下两种形式:先判断后执行的循环结构和先执行后判断的循环结构。

循环结构可以看成是一个条件判断语句和一个向回转向语句的组合。另外,循环结构包含三个要素:循环变量循环体循环终止条件

在C语言中,通常有以下四种循环,即 goto 循环、for 循环、while 循环、do…while 循环。但由于 goto 循环 并不能直接用于实现循环结构,故而在初学阶段我们仅需了解后三种即可。

for 循环

for 循环的基本句式如下:

for( 初始化表达式; 条件表达式; 迭代表达式 )
{
  //循环体:当条件表达式为真时执行的代码块
}

其循环要素及执行方法为:

  1. 初始化表达式:在循环开始前执行一次,用于设置循环控制变量的初始值。

  2. 条件表达式:在每次循环迭代前求值。如果结果为真(非零),则执行循环体中的代码块。如果结果为假(零),则退出循环。

  3. 迭代表达式:在每次循环迭代结束时执行,通常用于更新循环控制变量的值。

  4. 循环体:当条件表达式为真时重复执行的代码块。每次迭代结束后,控制流程返回到条件表达式进行下一次求值。

举个例子:

#include<stdio.h>
int main()
{
  int sum = 0;
  for (int i = 1; i <= 10; i++)
  {
    sum += i;  //将 i 的值加到 sum 上
  }
  printf("1 到 10 的和是: %d\n", sum);
  return 0;
}

在这个示例中:

  • 初始化表达式 int i = 1; 设置循环变量 i 的初始值为 1。
  • 条件表达式 i <= 10; 检查 i 是否小于或等于 10。只要这个条件为真,循环就会继续。
  • 迭代表达式 i++ 在每次循环迭代的末尾执行,将 i 的值增加 1。
  • 循环体 sum += i; 将当前的 i 值加到变量 sum 上。 

值得注意的是:

  • 条件表达式如果没有提供,编译器会假设条件始终为真,导致无限循环。
  • 初始化表达式和迭代表达式是可选的,但通常为了清晰起见,即使只涉及一个变量,也会明确写出来。
  • for 循环的三个组成部分都不要省略分号 ;
  • 循环控制变量(如示例中的 i)的作用域仅限于 for 循环体内

for 循环可以用于计数器、条件迭代等多种场景。区别于我们通常 while 循环,我们通常将 for 循环用在知道循环次数的题目中。

在这里,我们举一个经典的 for 循环例题:

题目:

斐波那契数列是一个每一项都是前两项和的序列,通常定义为:F(0) = 0, F(1) = 1, 且对于 n > 1, 有 F(n) = F(n-1) + F(n-2)。

用C语言编写一个for循环来计算斐波那契数列。

解析

在这个程序中:

  • 我们首先读取用户输入的项数 n
  • 使用 if 语句处理特殊情况,即当 n 为0或1时,斐波那契数列的值是预先知道的。
  • 对于 n > 1 的情况,我们使用一个 for 循环来计算第 n 项。在循环中,我们使用三个变量 firstsecond 和 next 来存储序列中的当前项、下一项和下下一项。
  • 在每次迭代中,我们计算 next 作为 first 和 second 的和,然后更新 first 和 second 以移动到序列中的下一项。
  • 最终,变量 next 包含了斐波那契数列的第 n 项,我们将其存储在 fib 中,并打印结果。 

答案:
#include<stdio.h>
int main()
{
  int n, first = 0, second = 1, next, fib;
  printf("请输入要计算的斐波那契数列的项数(非负整数): ");
  scanf("%d", &n);
  //特殊情况处理
  if(n == 0) fib = 0;
  else if(n == 1) fib = 1;
  else
  {
    //初始化前两项
    first = 0;
    second = 1;
    //计算第n项
    for (int i = 2; i <= n; i++)
    {
      next = first + second;  //计算下一项
      first = second;  //将第二项移动到第一项
      second = next;  //更新第二项为下一项
    }
    fib = next;  //fib存储最终计算的第n项
  }
  printf("斐波那契数列第 %d 项是: %d\n", n, fib);
  return 0;
}

请注意,这个程序只能计算相对较小的 n 值,因为当 n 很大时,斐波那契数列的值会迅速增长,超出 int 类型能存储的范围。对于大数的斐波那契数列计算,需要使用特殊的库来处理大数运算。

while 循环

我们刚刚介绍了通常用于知道循环次数题目中的 for 循环,接下来我们将介绍在不知道循环次数的题目中应该如何进行处理,即 while 循环

首先,while 循环的基本句式如下:

while( 条件表达式 )
{
  //循环体:只要条件表达式为真,就重复执行的代码块
}

在C语言中,while 循环是一种前测试循环,这意味着在每次迭代开始之前,循环的条件会被测试。如果条件为真(非零),则执行循环体中的代码块。如果条件为假(零),则退出循环。

其循环要素及执行方法为:

条件表达式(Condition)

  • 这是在每次循环迭代前检查的布尔表达式。
  • 如果条件表达式的结果为真(非零),则执行循环体中的代码块。
  • 如果条件表达式的结果为假(零),则退出循环。 

循环体(Loop Body)

  • 这是当条件表达式为真时重复执行的代码块。
  • 可以包含一个或多个语句,通常用于执行实际的计算或操作。

迭代更新(Iteration Update)

  • 虽然迭代更新不是 while 循环语法的一部分,但它是循环逻辑的一部分。通常在循环体内部,你需要更新一些变量以避免无限循环,并逐步接近循环结束的条件。

举个例子:

#include<stdio.h>
int main()
{
  int count = 1; // 初始化计数器
  while (count <= 5)
  { 
    //只要 count 小于或等于 5,循环就继续执行
    printf("%d ", count); // 执行循环体,打印当前的 count 值
    count++; // 迭代更新,将 count 的值增加 1
  }
  printf("\n");
  return 0;
}

在这个示例中:

  • 条件表达式:count <= 5; 只要 count 的值小于或等于 5,循环就继续执行。
  • 循环体:printf("%d ", count); 打印当前的 count 值。
  • 迭代更新:count++; 在每次迭代结束时将 count 的值增加 1。

注意:

  • 条件表达式必须始终为布尔值,即非零(真)或零(假)。
  • 循环体可以为空,但通常至少包含一个语句。
  • 迭代更新是避免无限循环的关键。如果循环体中没有修改条件表达式中的变量,循环可能会无限进行下去。
  • 循环变量(如示例中的 count)的作用域通常仅限于 while 循环体内,但也可以声明在循环外部,这取决于初始化的位置。

同样是刚刚所提到的斐波那契数列的题目,我们使用 while 循环也可以做出来:

题目:

斐波那契数列是一个每一项都是前两项和的序列,通常定义为:F(0) = 0, F(1) = 1, 且对于 n > 1, 有 F(n) = F(n-1) + F(n-2)。

用C语言编写一个for循环来计算斐波那契数列。

解析

  1. 初始化:首先初始化前两项 first(通常为0)和 second(通常为1)。
  2. 循环:使用 while 循环来计算后续的项。
  3. 迭代:在每次迭代中,计算下一项 next 作为 first 和 second 的和。
  4. 更新:将 first 更新为 second,将 second 更新为 next
  5. 打印:在循环中打印当前计算的斐波那契数列项。

答案:

#include<stdio.h>
int main()
{
  int n, first = 0, second = 1;
  printf("请输入要计算的斐波那契数列的项数(非负整数): ");
  scanf("%d", &n);
  if(n == 0) printf("斐波那契数列第0项是: %d\n", first);
  else
  {
    int i = 1; // 初始化计数器
    while(i <= n)
    {
      if(i == 1 || i == 2) printf("斐波那契数列第%d项是: %d\n", i, first);
      else
      {
        int next = first + second;
        printf("斐波那契数列第%d项是: %d\n", i, next);
        first = second;
        second = next;
      }
      i++;
    }
  }
  return 0;
}

故而在一般的情况下,for 循环的题目往往可以转化为 while 循环来实现,同学们可以依据个人喜好及复杂程度来选择其中某种方法解题。

同样我们在这里也举一个 while 循环的经典例子:

题目:

实现一个简单的倒计时程序,这个程序会从用户指定的数字开始倒计时,并在每次循环迭代中递减数字直到0。

解析

  1. 用户输入:程序首先提示用户输入倒计时的时间,使用 scanf 函数读取用户输入的整数并存储在变量 time 中。

  2. 开始提示:打印一个简单的开始消息,告知用户倒计时即将开始。

  3. while 循环:使用 while 循环进行倒计时。循环的条件是 time 大于或等于0。

  4. 打印倒计时:在循环体内,使用 printf 函数打印当前的倒计时数字。

  5. 递减操作:在打印之后,使用 time-- 语句将 time 的值减少1。

  6. 循环结束条件:当 time 减少到0或以下时,while 循环的条件不再满足,循环结束。

  7. 结束提示:打印一条消息告知用户倒计时已经结束。

答案:

#include<stdio.h>
int main()
{
  int time;
  printf("请输入倒计时的时间(秒): ");
  scanf("%d", &time);  //读取用户输入的倒计时时间
  // 倒计时开始
  printf("倒计时开始...\n");
  while (time >= 0)
  {
    printf("%d...\n", time);  //打印当前的倒计时数字
    time--;  //倒计时递减
  }
  printf("倒计时结束!\n");  //倒计时完成
  return 0;
}

do…while 循环

do…while 循环的基本句式是:

do
{
  //循环体:在每次迭代后检查条件,至少执行一次
} while( 条件表达式 );

在C语言中,do...while 循环是一种后测试循环,这意味着循环体至少会被执行一次,然后才会检查循环的条件。如果条件为真(非零),则循环继续执行;如果条件为假(零),则退出循环。

其循环要素及执行方法为:

循环体(Loop Body)

  • 这是在每次迭代中执行的代码块。
  • 可以包含一个或多个语句,通常用于执行实际的计算或操作。

条件表达式(Condition)

  • 这是在每次循环迭代后检查的布尔表达式。
  • 如果条件表达式的结果为真(非零),则再次执行循环体。
  • 如果条件表达式的结果为假(零),则退出循环。

迭代更新(Iteration Update)

  • 虽然迭代更新不是 do...while 循环语法的一部分,但它是循环逻辑的一部分。通常在循环体内部,你需要更新一些变量以逐步接近循环结束的条件。

举个例子:

#include<stdio.h>
int main()
{
  int count = 1; // 初始化计数器
  do
  {
    printf("%d ", count);  //执行循环体,打印当前的 count 值
    count++;  //迭代更新,将 count 的值增加 1
  } while(count <= 5);  //条件表达式,只要 count 小于或等于 5,循环就继续执行
  printf("\n");
  return 0;
}

在这个示例中:

  • 循环体:首先执行,打印当前的 count 值。
  • 迭代更新:在循环体内部,将 count 的值增加 1。
  • 条件表达式:count <= 5; 在每次迭代后检查 count 的值是否小于或等于 5。如果是,循环继续;否则,退出循环。

注意:

  • 循环体至少执行一次,因为条件检查是在迭代之后进行的。
  • 条件表达式必须始终为布尔值,即非零(真)或零(假)。
  • 迭代更新是避免无限循环的关键。如果循环体中没有修改条件表达式中的变量,循环可能会无限进行下去。
  • 循环变量(如示例中的 count)的作用域通常仅限于 do...while 循环体内,但也可以声明在循环外部,这取决于初始化的位置。

举一个 do...while 循环的经典例子:

题目:

实现一个循环,直到用户输入一个特定的值(比如0)为止。这种类型的循环常用于需要至少执行一次循环体,然后根据条件决定是否继续循环的场景。

解析

  1. 初始化用户输入提示:程序首先提示用户输入一个整数,并告知输入0将退出循环。

  2. do...while 循环:使用 do...while 循环开始读取用户输入。

  3. 读取输入:在循环体内,使用 scanf 函数读取用户输入的整数,并存储在变量 input 中。

  4. 显示输入值:然后使用 printf 函数显示用户输入的值。

  5. 循环条件检查:在循环体执行完毕后,while 部分的 条件表达式 被检查。如果 input 不等于0,循环将继续,再次提示用户输入。如果 input 等于0,则循环结束。

  6. 退出消息:当用户输入0,循环结束,打印退出消息。

答案:

#include<stdio.h>
int main()
{
  int input;
  printf("请输入一个整数(输入0退出): ");
  do
  {
    scanf("%d", &input); // 读取用户输入
    printf("You entered: %d\n", input); // 显示用户输入的值
    printf("请输入另一个整数(输入0退出): ");
  } while(input != 0); // 如果输入的值不是0,循环继续
  printf("您已退出循环。\n");
  return 0;
}

最后需要注意:

在这三种循环结构中,

for 循环的初始化表达式执行了 1 次,条件表达式执行了 n+1 次,迭代表达式和循环体执行了 n 次。 

while 循环的条件表达式执行次数 == 循环体的执行次数 + 1

do...while 循环的表达式执行次数 == 循环体的执行次数


《衡庐浅析·C语言程序设计·第三章·三种基本结构之循环结构》部分到这里就结束了,我会在后续章节编写一些题目或分享一些典型的例子以巩固所学的知识点。三种基本结构的内容到这里也就告一段落了,下一个知识点章节我们将会学习C语言中数组的相关知识,敬请期待,也欢迎大家在评论区进行互动!

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 21:04:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 21:04:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 21:04:01       45 阅读
  4. Python语言-面向对象

    2024-07-21 21:04:01       55 阅读

热门阅读

  1. 揭秘Odoo OWL的魔法:reactive vs useState

    2024-07-21 21:04:01       15 阅读
  2. PS像素图层简介

    2024-07-21 21:04:01       16 阅读
  3. ArduPilot开源代码之AP_DAL研读系列

    2024-07-21 21:04:01       11 阅读
  4. Dockerfile相关命令

    2024-07-21 21:04:01       12 阅读
  5. Lucene 索引文件详解:结构与工作原理

    2024-07-21 21:04:01       15 阅读
  6. go语言的命名规则

    2024-07-21 21:04:01       18 阅读
  7. 基于python的时空地理加权回归(GTWR)模型

    2024-07-21 21:04:01       19 阅读
  8. c++端的类,作为组件在qml端使用

    2024-07-21 21:04:01       14 阅读