C语言基础六:循环结构及面试上机题

Day06:循环结构

定义

代码的重复执行,就叫做循环

循环的分类

  • 无限循环:其实就是死循环,程序设计中尽量避免无限循环。程序中的无限循环必须可控。
  • 有限循环:循环限定循环次数或者循环的条件。

循环的构成

  • 循环条件
  • 循环体

当型循环的实现

特点:先判断后执行,如果条件不满足,一次都不执行

代表:while和for

while

语法:

c 复制代码
while(循环条件) // a>b&&b>c
{
    循环许局;//如果是单语句,可以省略{}、如果是复合语句,不可以省略{}
}

说明:

​ 1.循环条件的返回值必须是布尔类型(条件表达式只能是关系表达式或逻辑表达式)。在C语言中,布尔类型为真使用 非0,布尔类型为假使用 0.如果引入 #include <stdbool.h>,也可以用true和false来表示。

​ 2.{}包起来的内容整体称之为 循环体

​ 3.我们要在循环体中控制循环条件 的变化,否则会产生死循环。

执行过程:

特点:先判断,后执行,循环体语句有可能一次不执行

案例

c 复制代码
#include <stdio.h>
/*
	如何编程来计算1+2+3...+100(累加求和)
*/

int main()
{
    //定义一个变量,保存累加的和
    int sum = 0;
    //定义一个循环变量
    int i = 1;
    
    while(i<=100)//循环条件,这里可以有关系表达式、逻辑表达式、整型常量
    {
     	//累加运算
        //sum =sum +i;
        sum += i;
        i++;
        //给循环变量赋值,用来影响循环条件
    }
    
    printf("1-100的累加和是:%d\n",sum);
	return 0;
}
死循环
c 复制代码
while(1)//我们会在死循环进行必要的限制
for

原则上,for循环能实现的while循环一定可以实现,for循环可以看做是while循环的一种特殊写法。

语法:

c 复制代码
for(①表达式1;②表达式2;③表达式3)
{
	①循环体语句; --如果是单语句,可以省略{};如果复合语句,必须保留{}
}

说明:

1.()中可以只保留两个 ;;,举例for(;;)

2.①(表达式1)是循环变量,我们需要赋初值,循环变量可以是列表,多个循环变量使用逗号分隔,举例:int i=0,j=0

3.②(表达式2)是循环条件,用来限制循环的次数,循环条件支持关系表达式,如果加入逻辑表达式,会变成复合表达式,举例:i<10 &&j<=i

4.③(表达式3)改变循环条件,支持列表,这里可以使用赋值表达式,举例: i++,j++

5.执行顺序:①②④③→②④③→②④③→...→②

执行过程:

特点:

​ 先判断,后执行,循环语句可能一次不执行

c 复制代码
#include <stdio.h>
int main()
{
	for(int i=2;i<100;i+=2)
	{
		sum+=i;
	}
	printf("偶数和的结果是:%d",sum);
	return 0;
}
总结
  • for语句使用语法规则上,降低/避免因为忘记循环条件更新操作;而引起的产生无限循环的几率。
  • 应用场合:for语句往往应用于次数事先可以确定的场景。
死循环
c 复制代码
for(;;);
for(表达式1;;表达式2);

循环实现三要素

  • 循环变量的初始值
  • 循环条件
  • 循环变量的更新

案例

c 复制代码
 #include <stdio.h>
 #include <math.h>
 /**
 *  需求:for循环案例-求斐波拉契数列前20个数
 *  分析:1,1,2,3,5,8...
 */
 int for_test2()
 {
	int f1 = 1;// 前一个数,默认是1,因为第一个是1
	int f2 = 1;// 后一个数,默认是1,因为第二个是1
 	int i = 1;// 循环变量
for(; i <= 10; i++)
 	{
 	printf("%12d%12d\n",f1,f2);
 	// 一行显示两个数,每两个换行  1 1 2 3 5 8
 	//if(i % 2 == 0)
 	//{
 	//  printf("\n");
	 //}
 	f1 += f2; // f1 = 2 = 1 + 1
 	f2 += f1; // f2 = 3 = 1 + 2
 	}
 }
 int main(int argc,char *argv[])
 {
 	for_test2();
 }
 return 0
直到型循环的实现

特点:先执行,后判断

代表:do...while

do...while

语法:

c 复制代码
do
{
	循环体;
}while(循环条件);

说明:

1.循环条件的返回值必须是布尔类型,在C语言中,布尔类型为真使用 非0来表示。

2、{}包起来的内容整体称之为 循环体

3、我们要在 循环体中控制循环条件的变化,否则会产生死循环。

执行过程:

特点;先执行,后判断,不管满不满足条件,都要先执行一次

goto

语法:

c 复制代码
goto 标签(label);

标签:标明

注意事项

1.可读性: goto 语句会破坏代码的结构和可读性,使得代码难以理解和维护。因此,应尽量避免使用。

2.替代方案:大多数情况下,可以使用循环、条件语句、函数等结构来替代 goto 语句,使代码更加清晰和易于管理。3.嵌套限制:虽然 goto 语句可以跨函数跳转(即跳转到另一个函数中的标签),但这种用法是不合法的,并且会导致编译错误。goto 语句只能在同一函数内部跳转。

4.错误处理:在某些情况下, goto 语句可以用于错误处理,例如从嵌套的多层循环中跳出。但即使在这种情况下,也应谨慎使用,并考虑是否有更好的替代方案。

循环的嵌套

3种循环(while、do...while、for)可以相互嵌套,在前一个循环结构的内部又存在一个完整的循环结构。如:

案例:

c 复制代码
#include<stdio.h>
/*
需求:嵌套for循环案例-求100~200之间的所有素数
分析:只能被1和自身整除的数叫做素数
*/
int main()
{
	 // 创建一个变量,存放100~200之间的自然数
	int num = 100;
 	// 循环变量,默认从2开始,因为自然数除以1没有意义 
	int i;
 	// 定义标志位:用来记录1~自身之间的能整除的次数,用来校验该自然数是否为素数
	// 第1层for循环:生成100~200之间的自然数
	for(;num <= 200;num++)
 	{
 		// 每个自然数在判别之前,需要重置标志位
		is_flag = 1;
 		// 第2层for循环:验证该自然数能否被除了1~自身之间的数整除,能整除,就改变is_flag的值
		// for(i = 2;i < num -1;i++
         for(i = 2;i < num / 2;i++)
 		{
 			// 校验是否能整除
			if(num % i == 0)
 			{
 				is_flag = 0;
 				break;// 只校验第一个能整除的数
			}
 		}
 	// 根据标志位,判断该自然数是否是素数
		if (is_flag) // 条件判断:is_flag == 1 缩写 is_flag(推荐) is_flag == 0 缩写 !is_flag
 		{
 			printf("%-4d",num);
 		}
 	}
 	printf("\n")
	return 0;
}

循环结构的典型应用场景

  • 求累和:举例 1+2+3+...+100的和

  • 求累乘:举例123*...*100的积

  • 求均值:举例(1+2+3+...+100)/100的值

  • 求极值:举例、12,34,56,67中的最大值或者最小值

  • 元素遍历:常用于数组元素的遍历

基础算法模型
  1. 累加和

    • 定义一个变量(sum),并赋初值为0;

    • 该变量累加(+=)每一个数据项(i);

    • 当访问完每一个数据项,此时该变量的取值就是累加和的结果。

  2. 累乘

    • 定义一个变量,并赋初值为1;
    • 用该变量累乘(*=)每一个数据项;
    • 当访问完每一个数据项,此时该变量的取值就是累乘的结果
  3. 极值(多用于数组)

    • 定义一个变量,并赋初值为第一个数据项;
    • 从第二个数据项开始,依次于该变量进行比较,如果大于/小于该变量,则将当前数据项的数据赋值给该变量。
    • 当访问完每一个数据项,此时该变量的取值就是求极值的结果。
  4. break和continue

    • break

      功能:

      ​ ①用在switch中,用来跳出switch的case语句:如果case没有break,可能会产生case穿透。

      ​ ②用在循环中(while、do...while、for),提前结束循环,也就是跳出整个循环。

      说明:

      ​ ①break不能用于循环语句和switch语句之外的任何其他语句之中。

      ​ ②break只能终止并跳出最近一层的循环结构。

      流程图:

      案例1:

      c 复制代码
       #include <stdio.h>
       /**
       * 需求:break案例-输出1~100以内的偶数,只能输出前10个
       */ 
      int break_test()
       {
          for(int i = 1,count = 1; i <= 100; i++)
          {
              if(i % 2 == 0)
              {
                  if(count > 10)
                  {
                      break;
                  }
                  count ++;// 用来计数
                  printf("%d\t",i);
              }
          }
          
          printf("\n");
       }
       int main(int argc,char *argv[])
       {
          break_test();
          return 0;
       }
      • continue

        功能:continue语句不会结束整个循环,而是跳过本次循环尚未执行的语句,进入下一次循环。

        说明:

        ​ ①仅用于循环语句中。

        ​ ② 在嵌套循环的情况下,continue语句只对包含它的最近的一层循环起作用。

        图示:

        案例:

        c 复制代码
        #include <stdio.h>
        /*
        求1-100以内的偶数和
        */
        int continue_test1()
        {
            int sum = 0;
            for(int i = 1; i<=100;i++)
            {
                if(i%2 !==0)
                {
                    comtinue;
                }
                sum+=i;
            }
            printf("1-100以内的偶数和是%d\n",sum);
        }
        int main()
            {
                continue_test1();
            }
            
        • 跳出多层循环

          跳出多层循环是不能直接使用break和continue实现的,因为它们只能跳出单层循环,跳出多层循环,需要我们自定一定标志位进行跳出(标志位也可以配合break使用)。

        案例:

        c 复制代码
         #include <stdio.h>
         int fun0()
         {
        	 // 定义一个标志位
        	int is_flag = 1;// 默认循环成立
        	// 定义一个变量,用来接收控制台输入
        	char fu;
         	// 循
                 while(is_flag)
            {
                printf("外层循环执行的内容..\n");
                while(is_flag)
                {
                    printf("内存循环执行的内容..\n");
                    scanf("%c",&fu);
                    if(fu == 'Y' || fu == 'y')
                    {
                        is_flag = 0;
                    }
                }
            }
         }
         int fun1()
         {
            // 定义一个标志位
            int is_flag = 1;// 默认循环成立
            // 定义一个变量,用来接收控制台输入
            char fu;
            // 循环
            while(is_flag)
            {
                printf("外层循环执行的内容..\n");
                while(1)
                {
                    printf("内存循环执行的内容..\n");
                    scanf("%c",&fu);
                    if(fu == 'Y' || fu == 'y')
                    {
                        is_flag = 0;
                        break;
                    }
                }
            }
         }
         int main()
         {
            fun0();
            fun1();
         }

        注意:

        层循环执行的内容...\n");

        while(1)

        {

        printf("内存循环执行的内容...\n");

        scanf("%c",&fu);

        if(fu == 'Y' || fu == 'y')

        {

        is_flag = 0;

        break;

        }

        }

        }

        }

        int main()

        {

        fun0();

        fun1();

        }

        注意:
        如果是多层循环(嵌套循环),进的时候是从外到内,跳出的时候是从内到外。
        

上机题

  1. 计算n以内所有正奇数的和 ? n值通过键盘输入
  2. 计算 1 + 1/(2 * 3) + 1/(3 * 4) + .+ 1/(n * (n + 1)) = ?直到最后一相值小于0.00001为至。
  3. 计算1+1/2 - 1/3 + 1/4 - 1/5 .+1/n= ? n通过键盘输入(int k = -1)
  4. 计算n的阶乘 ? n值通过键盘输入
  5. 输出半径为1~10的圆面积,面积大于100时停止
  6. 求输入的十个整数中正数的个数及其平均值
  7. 打印出100以内能整除7之外的的自然数
  8. 打印乘法表
  9. 我国古代数学家张丘建在《算经》一书中提出的数学问题:鸡翁一值钱五,鸡母一值钱三,鸡 雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
  10. 从键盘上输入多个无符号整型数据,直到 0 结束 ,输出所输入数据中的最大值。
相关推荐
走在考研路上1 小时前
Python错误处理
开发语言·python
数据小爬虫@1 小时前
Python爬虫:如何优雅地“偷窥”商品详情
开发语言·爬虫·python
CV大法好1 小时前
刘铁猛p3 C# 控制台程序引用System.Windows.Forms报错,无法引用程序集 解决方法
开发语言·c#
工业甲酰苯胺1 小时前
C语言之输入输出
c语言·c++·算法
Days20501 小时前
uniapp小程序增加加载功能
开发语言·前端·javascript
朱小勇本勇2 小时前
Qt实现控件拖曳
开发语言·数据库·qt
片片叶2 小时前
C++(十四)
开发语言·c++
dengjiayue2 小时前
golang实现简单的reids服务2
开发语言·golang
疯狂的沙粒3 小时前
JavaScript 单例模式的创建与应用
开发语言·前端·javascript·vue.js