C语言笔记第02章:三大基本结构(二)

简介: C语言笔记第02章:三大基本结构

3.循环结构

学习本章之前:循环结构是结构化程序设计的三种基本结构之一,在程序设计中对于那些需要重复执行的操作应该采用循环结构来完成,利用循环结构处理各类重复操作既简单又方便。所以相较于前面两种结构的难度会有所提升,所以在此章节的代码和语法知识更需要花时间消化并且上机操作❤️

  • 使用循环可以多次重复地执行多条语句,这里的“多条语句”称为循环体。在C语言中,可以使用三种循环,分别是:while、do…while、for
  • 在这些语句中,循环体被重复执行的次数由循环条件控制,称为控制表达式(controlling expression)。
  • 这是一个标量类型的表达式,也就是说,它属于一个算术表达式或指针表达式。如果控制表达式的值不等于 0,循环条件为 true,反之,循环条件为 false。
  • 语句 break 和 continue 用于在一次循环还未执行完时,跳转出循环或返回到循环头部。

📍 无论是 while,do…while 还是 for,他们都具有四要素:

  • 循环变量初始化:循环的起始位置
  • 循环变量迭代:所执行的步长,统计变化情况,识别是否继续
  • 循环条件判断:标记循环继续的条件
  • 循环操作(循环体):循环所执行的内容

3.1 for 循环

3.1.1 基本语法

for(循环变量初始化;循环条件判断;循环变量迭代)
{
    语句1;
    语句2;
    …………;
} 

🚩在一个典型的 for 循环中,在循环体顶部,下述三个动作需要执行:

  • 表达式 1:循环变量初始化
    只计算一次。在计算控制表达式之前,先计算一次表达式 1,以进行必要的初始化,后面不再计算它。
  • 表达式 2:循环条件判断
    每轮循环前 都要进行循环条件判断,以判断是否需要继续本轮循环。当控制表达式的结果为 false,结束循环。
  • 表达式 3:循环变量迭代,也叫调节器
    调节器(例如计数器自增)在每轮循环结束后 且表达式 2 计算前 执行。即,在运行了调节器后,再执行表达式 2进行判断。

📍 执行过程如图:

📝 我们来举个例子

#include<stdio.h>
int main()
{
    int i;
    /*在这里面:
     1. 循环变量初始化:i = 0
     2. 循环条件判断:i < 3
     3. 循环变量迭代:i++
     4. 循环体:printf("print the value of i =%d\n", i);
    */
    for(i = 0; i < 3; i++)
    {
        printf("print the value of i =%d\n", i);
    }
    return 0;
}

运行结果:

📍 一次循环的执行过程:

  • 循环变量赋初值: 将 i 的初始值变成 0
  • 循环条件判断: 判断 i 是否小于3,若小于3则为true,其它为false
  • 循环变量值变化: i 的值自动加1

3.1.2 中途终止循环 - return&break

第 3.5 节会再次介绍 break,这里预热一波

1️⃣ 方式一:return

#include<stdio.h>
int main()
{
    int i;
    for(i = 0; i < 3; i++)
    {
        if(i == 1)
        {
            return 0;//直接退出程序,这也是中途终止循环的方式
        }else
        {
            printf("%d", i);   
        }
    }
    printf("My love end");
    return 0;
}

💬 当 i==1 时直接退出程序,因此这道题的输出结果就是 0 。因为 i为1的时候就直接退出程序了,并未printf打印结果,也并未打印My love end。注意与第二种方式 break 进行比较哦。

2️⃣ 方式二:break

break语句用于终止某条语句块的执行,一般使用在 switch或者 循环(for,while,do…while)中,表示退出 switch 或退出循环。

#inlcude<stdio.h>
int main()
{
    int i;
    for(i = 0; i < 3; i++)
    {
        if(i == 1)
        {
            break;//退出for循环,但并未退出程序
        }else
        {
            printf("%d", i);   
        }
    }
    printf("My love end");
    return 0;
} 

💬 当 i==1 时直接退出for循环,但并未退出程序,因此控制台的打印结果为0My love end

3.1.3 跳过本次循环,进入下次循环 - continue

在第 3.5 节会再次介绍continue,这里预热一波

除了break 语句可以结束循环体外,这里再介绍一个continue语句,这个语句跟break语句一样,也可以结束循环体,但不同的是,它只是结束本次循环,循环体会跳过continue后面的语句,直接去再次判断循环条件,进行下一次的循环操作。

📝 举个例子

#include<stdio.h>
int main()
{
    int i;
    for(i = 0; i < 3; i++)
    {
        //即当i等于1的时候,执行 continue语句,结束本次循环
        //即当i等于1的时候不会打印信息,直接执行下一次循环
        if(i == 1) 
        { 
            continue;
        }
        printf(" print the value of i = %d\n", i);
    }
    return 0;
}

运行结果如下:

通过以上例子,我们可以看到,运用 breakcontinue 语句,我们可以更加灵活的使用循环语句来控制程序的流程。

3.1.4 🚩 一个思考

for(表达式1;表达式2;表达式3)
{
  循环操作;    
}

我们已经知道了for循环的基本结构,但我们一定要遵循那个位置标准吗?这么说吧,我们一定要把循环变量初始化放在表达式1吗,一定要把循环条件判断放在表达式2的位置吗,一定要把循环变量迭代放在表达式3的位置吗?

✏️ 不是的,这些只是一些规范,你可以遵循,也可以不遵循。我们来举个例子,把位置改一改。

#include<stdio.h>
int main()
{
  int i = 0; //循环变量初始化
    for(;i < 3;)//表达式1和表达式2的位置空缺,甚至我们把 i < 3 的位置改到循环体中也是没问题的
    {
      printf("%d\n",i);
        i++; //循环变量迭代
    }
}

于是我们发现了,其实表达式1,2,3都可以不放任何东西,可以放到其它位置的。再来看一个更特殊的:

#include<stdio.h>
int main()
{
    for(;;)//三个位置什么都不放,但两个分号无论如何是一定都要写的
    {
        printf("I love you ,软件协会");
    }
}

你可以发现,循环变量初始化循环条件判断循环变量迭代都没有,而且你应该意识到这个for循环居然无法退出循环(可以自己运行一下看看),这叫做**死循环**。这是我们必须避免的,在程序中绝对不能够出现死循环,带给程序的伤害比拒绝你表白的女孩给你的伤害更大!

3.2 while 循环

3.2.1 基本语法

循环变量初始化;
while(循环条件判断)
{
    循环体;
    循环变量迭代;
}
  1. 在while循环前,先进行循环变量初始化。
  2. 再判断while后边括号内的表达式是否为真,若为真即执行大括号内的语句,若为假,则跳过while循环结构执行大括号下方的第一条语句。
  3. 若为真,当执行完大括号内语句后,再次回到2去判断,执行。
  4. 直到while后小括号内表达式的表达式为假,结束循环。

📍 注意:若在while的大括号内执行了 break语句,则立刻结束循环结构,开始执行大括号外下方的第一条语句。

3.2.2 实例演示

📝 例子1:

#include <stdio.h>
int main()
{
    int a = 5, b = 10;
    while(b > a) //即若b > a 为真就执行大括号内的语句,
    {                  
        //若为假则执行大括号下方语句
        printf("while looping a = %d, b = %d\n", a, b);
        a++;
    }
    printf("while loop over\n");
    return 0;
}

运行结果:

即当,a的值等于10时,b>a 不成立,循环结束。

📝 例子2:

#include <stdio.h>
int main()
{
    int a = 5, b = 10;
    while(b > a)            //即若b > a 为真就执行大括号内的语句,
    {                       //若为假则执行大括号下方语句
        printf("while looping a = %d, b = %d\n", a, b);
        if(a == 8)
        {
            break; //如果a等于8跳出while循环,注意哦,如果是return则就是结束整个程序
        }
        a++;
    }
    printf("while loop over\n");
    return 0;
}

运行结果如下:

将例子1和例子2分别执行一下,查看打印输出信息的不同,体会一下while循环的使用,以及 break 的用法。

3.2.3 while死循环

不多说明,上代码演示最简单的while死循环,细品。

#include<stdio.h>
int main()
{
  while(true)
    {
    }
}

3.2.4 注意事项

  • 循环条件判断必须返回一个布尔值的表达式
  • while循环是先循环条件判断再执行大括号中循环操作

3.3 do…while 循环

3.3.1 基本语法

不像 forwhile 循环,它们是在循环头部 检查循环条件。在 C 语言中,do…while 循环是在循环的尾部 检查它的条件。

do…while 循环与 while 循环类似,但是 do…while 循环会确保至少执行一次循环

循环变量初始化;
do
{
  循环操作;
    循环变量迭代;
}while(循环条件判断);
  • 首先执行大括号内语句
  • 判断while后边括号内的表达式是否为真,若为真回到第一步,若为假,则退出while循环结构,执行大括号下方的第一条语句。

3.3.2 实例演示

#include<stdio.h>
//输出结果:012【3】
int main() {
  int i = 0;//循环变量初始化
  do
  {
    printf("%d", i);//循环操作
    i++;//循环变量迭代
  } while (i < 3);//循环条件判断
  printf("【%d】", i);
}

3.3.3 注意事项

  • 循环条件判断必须返回一个布尔值的表达式
  • do…while循环是先执行大括号中的循环操作再进行循环条件判断,因此循环操作会至少执行一次。
  • 注意 while(循环条件判断) 的后面有一个;,千万不要忘记写哦。

3.4 嵌套循环

3.4.1 基本介绍

  • 将一个循环放在另一个循环体内,就形成了嵌套循环,其中 forwhiledo...while均可以作为外层循环和内层循环,建议一般使用两层即可,最多不要超过三层,否则代码的可读性很差。
  • 实际上嵌套循环就是把内层循环当成外层循环的循环体,当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可以结束外层的当次循环,开始下一次循环。

3.4.2 实例演示

📝 示例1

#include<stdio.h>
int main() {
  for (int i = 1; i <= 3; i++)//外循环
  {
    for (int j = 1; j <= 4; j++)//内循环
    {
      printf("i = %d ; j = %d\n", i, j);
    }
  }
}

📝 示例2:输出三三乘法表

#include<stdio.h>
//三三乘法表
int main() {
  for (int i = 1; i <= 3; i++)//外循环
  {
    for (int j = 1; j <= i; j++)//内循环
    {
      printf("%d * %d = %d\t", i, j, i * j);// \t是水平制表符,即向右移动8个单位
    }
    printf("\n");
  }
}

运行结果:

3.5 跳转控制语句

循环控制语句改变你代码的执行顺序。通过它你可以实现代码的跳转。

📍 C 提供了下列的循环控制语句。

控制语句 描述
break 语句 终止循环或 switch 语句,程序流将继续执行紧接着循环或 switch 的下一条语句。
continue 语句 告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代。
goto 语句 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。

3.5.1 break

C 语言中 break 语句有以下两种用法:

  • 当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。
  • 它可用于终止 switch 语句中的一个 case。

📍如果小伙伴使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会退出离自己最近的那层循环,然后开始执行该块之后的下一行代码。

3.5.2 continue

  • C 语言中的 continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。
  • 对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 whiledo…while 循环,continue 语句重新执行条件判断语句。

3.5.3 goto

💬goto语句在此不要求小伙伴们掌握,只需要了解,知道有这么个东西,并且要求大家非必要不使用goto语句。

📍在任何编程语言中,都不建议使用 goto 语句。因为它使得程序的控制流难以跟踪,使程序难以理解和难以修改。任何使用 goto 语句的程序可以改写成不需要使用 goto 语句的写法。原因如下:

  • goto语句是低级语言的表征。它很灵活,灵活到没有任何拘束,在函数体内直来直往。函数体内可能含有一些嵌套的循环,这就意味着goto可以跳进跳出循环而无所顾忌。当程序比较复杂时很容易造成程序流程的混乱。

  • 滥用goto语句,程序无规律,可读性差。在团队开发中影响效率,以后调试和维护程序的过程会令同事和自己都头秃。

任何事物都有两面性,goto语句灵活性如果在适当的地方发挥出来确实非常有用的,毕竟现在有些地方需要无条件的跳转语句。尤其在汇编语言中,如果不使用类似于goto语句的jmp指令,那么其就无法实现循环和条件分支。所以在汇编语言中,goto语句用处还是很大的。使用goto可以使程序变得更加可扩展。当程序需要在错误处理时释放资源时,统一到goto处理最方便。这也是为什么很多大型项目,开源项目,包括Linux,都会大量的出现goto来处理错误!

但现在的编程趋势是要模块化、结构化、所以大多书上已经不建议使用无条件分支的goto语句了,尽管现在大多数语言还在支持它,但还是少用为妙,尤其是像C语言小白玩家,还是瑟瑟发抖的乖乖用break慢慢跳吧。

3.5.4 return

return 使用在方法中,表示跳出/退出所在的方法。如果 return 写在 main 方法中,则会退出程序。

相关文章
|
网络协议 编译器 Linux
【C语言】结构体内存对齐:热门面试话题
【C语言】结构体内存对齐:热门面试话题
444 0
|
11月前
|
存储 安全 C语言
【C语言程序设计——选择结构程序设计】预测你的身高(头歌实践教学平台习题)【合集】
分支的语句,这可能不是预期的行为,这种现象被称为“case穿透”,在某些特定情况下可以利用这一特性来简化代码,但在大多数情况下,需要谨慎使用。编写一个程序,该程序需输入个人数据,进而预测其成年后的身高。根据提示,在右侧编辑器补充代码,计算并输出最终预测的身高。分支下的语句,提示用户输入无效。常量的值必须是唯一的,且在同一个。语句的作用至关重要,如果遗漏。开始你的任务吧,祝你成功!,程序将会继续执行下一个。常量都不匹配,就会执行。来确保程序的正确性。
410 10
|
11月前
|
小程序 C语言
【C语言程序设计——基础】顺序结构程序设计(头歌实践教学平台习题)【合集】
目录 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果: 任务描述 相关知识 编程编写一个程序,从键盘输入3个变量的值,例如a=5,b=6,c=7,然后将3个变量的值进行交换,使得a=6,b=7,c=5。面积=sqrt(s(s−a)(s−b)(s−c)),s=(a+b+c)/2。使用输入函数获取半径,格式指示符与数据类型一致,实验一下,不一致会如何。根据提示,在右侧编辑器补充代码,计算并输出圆的周长和面积。
276 10
|
11月前
|
存储 编译器 C语言
【C语言程序设计——选择结构程序设计】求一元二次方程的根(头歌实践教学平台习题)【合集】
本任务要求根据求根公式计算并输出一元二次方程的两个实根,精确到小数点后两位。若方程无实根,则输出提示信息。主要内容包括: - **任务描述**:使用求根公式计算一元二次方程的实根。 - **相关知识**:掌握 `sqrt()` 函数的基本使用方法,判断方程是否有实根。 - **编程要求**:根据输入的系数,计算并输出方程的根或提示无实根。 - **测试说明**:提供两组测试数据及预期输出,确保代码正确性。 - **通关代码**:包含完整的 C 语言代码示例,实现上述功能。 通过本任务,你将学会如何处理一元二次方程的求解问题,并熟悉 `sqrt()` 函数的使用。
225 5
|
11月前
|
存储 算法 安全
【C语言程序设计——选择结构程序设计】按从小到大排序三个数(头歌实践教学平台习题)【合集】
本任务要求从键盘输入三个数,并按从小到大的顺序排序后输出。主要内容包括: - **任务描述**:实现三个数的排序并输出。 - **编程要求**:根据提示在编辑器中补充代码。 - **相关知识**: - 选择结构(if、if-else、switch) - 主要语句类型(条件语句) - 比较操作与交换操作 - **测试说明**:提供两组测试数据及预期输出。 - **通关代码**:完整代码示例。 - **测试结果**:展示测试通过的结果。 通过本任务,你将掌握基本的选择结构和排序算法的应用。祝你成功!
201 4
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
617 16
|
11月前
|
存储 算法 安全
【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】
本任务要求输入x的值,计算并输出特定阶跃函数的结果。主要内容包括: 1. **选择结构基本概念**:介绍if、if-else、switch语句。 2. **主要语句类型**:详细解释if、if-else、switch语句的使用方法。 3. **跃迁函数中变量的取值范围**:说明如何根据条件判断变量范围。 4. **计算阶跃函数的值**:通过示例展示如何根据给定条件计算函数值。 编程要求:在右侧编辑器Begin-End之间补充代码,实现阶跃函数的计算和输出。测试说明提供了多个输入及其预期输出,确保代码正确性。最后提供通关代码和测试结果,帮助理解整个过程。
245 0
|
11月前
|
存储 算法 安全
【C语言程序设计——选择结构程序设计】判断一个数是不是5和7的倍数(头歌实践教学平台习题)【合集】
本任务要求输入一个正整数,判断其是否同时是5和7的倍数,若是输出&quot;Yes&quot;,否则输出&quot;No&quot;。内容涵盖选择结构的基本概念、主要语句类型(if、if-else、switch)及条件判断逻辑,帮助理解编程中的分支执行与条件表达式。测试用例包括正数、负数及非倍数情况,确保代码逻辑严谨。通关代码示例如下: ```cpp #include &quot;stdio.h&quot; int main(){ int a; scanf(&quot;%d&quot;, &a); if (a &lt;= 0){ printf(&quo
431 0
|
11月前
|
编译器 C语言 C++
【C语言程序设计——选择结构程序设计】求输入的日期是该年的第几天(头歌实践教学平台习题)【合集】
本任务要求编写程序,根据用户输入的年月日(以空格或回车分隔),计算并输出该天是该年的第几天,需注意判断闰年。主要内容包括: 1. **任务描述**:实现从键盘输入年月日,计算该天是当年的第几天。 2. **相关知识**: - `switch` 结构的基本语法及使用注意事项。 - 判断闰年的条件:能被4整除但不能被100整除,或能被400整除的年份为闰年。 3. **编程要求**:根据提示补充代码,确保程序正确处理输入并输出结果。 4. **测试说 示例代码展示了如何使用 `switch` 语句和闰年判断逻辑来完成任务。通过此练习,掌握 `switch` 语句的应用及闰年判断方法。
449 0
|
编译器 C语言 Python
C语言结构
C语言结构
73 0