9 循环语句

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加

例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、循环结构

循环结构 :在程序中需要反复执行 某个功能而设置的一种程序结构,可以看成是一个条件判断语句 和一个向回转向语句 的组合。

循环结构由三个要素 组成:循环变量循环终止条件循环体

  • 循环变量:用来控制循环是否继续进行的变量
  • 循环终止条件:决定了循序执行多少次,何时结束循环
  • 循环体:被反复执行的程序段

二、for语句

2.1 语法结构

c 复制代码
for (初始化表达式; 测试条件表达式; 更新表达式) {
		//循环体
}

条件表达式是一个布尔表达式(结果只有真假)。当是逻辑表达式时,逻辑为真(1),执行循环体;逻辑为假(0),跳过循环。当是数值表达式时,非0为真,执行;0为假,跳过。

C99针对真/假 值专门设计了_Bool类型,该类型的变量只能存储1(true)0(flase)。如果把其他非0数值赋值给_Boo变量,该变量会被设置为1

  • 第一个表达式只在for循环开始时执行一次,用于初始化循环变量
  • 第二个表达式在执行循环之前求值,如果为真,执行循环体;为假,循环结束
  • 第三个表达式在每次循环结束时求值,使循环趋于结束的操作
  • 三个表达式都可以使用任意合法的表达式

执行逻辑

2.2 特殊形式

省略表达式

三个表达式都可以省略 但是 不能省

c 复制代码
for ( ; ; ) { //死循环,在单片机程序中可以看到
}

• 表达式1可省略,但循环之前应给循环变量赋值

• 表达式2可省略,将陷入死循环

• 表达式3可省略,但在循环体中增加使循环变量值改变的语句

c 复制代码
										i = 1;
for(i = 1; i <= 100; i++){				for( ; i <= 100; ){
	sum += i;					===》		sum += i;
}											i++;
										}

省略花括号

c 复制代码
for(int i = 0; i < 10; i++)
	printf("i = %d\n",i);
	printf("ABC\n");		//打印i=0~9,ABC只打印一次

循环体只有一条语句时可以不用花括号。

不使用符合语句(花括号)时,for语句到第一个";"视为语句结束。

2.3 嵌套for循环

c 复制代码
for (初始动作1; 条件1; 每轮动作1) {
	... 
	for (初始动作2; 条件2; 每轮动作2) {
		//循环语句块
	}
}
//后续语句

执行逻辑

2.4 for循环用法

递减计数器

c 复制代码
for(num = 10; num > 0; num--){}

递增计数器

c 复制代码
for(num = 2; num < 100; num += 10){}

字符递增递减
倍数式递增递减

2.5 内外条件变量的区别

c 复制代码
int i = 0;
for(i = 0; i < 10; i++){
}
printf("%d\n",i);		//i=10
c 复制代码
for(int i = 0; i < 10; i++){
}
printf("%d\n",i);		//i未定义,此时i的作用域是for内

2.6 示例

例2-1:输入整数n, 打印n行下面形状的星型(*)

c 复制代码
*
**
***
****
*****
c 复制代码
#include <stdio.h>

int main(void){
    int n;
    int i,j;

    printf("Please enter a integer: ");
    scanf("%d",&n);

    for(i = 0; i < n; i++){
        for(j = 0; j <= i ; j++){
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

例2-2:输入大写字母,假如输入F,利用for循环打印下面的图案

c 复制代码
F
_FE
__FED
___FEDC
____FEDCB
_____FEDCBA
c 复制代码
#include <stdio.h>

int main(void){
        char ch;
        int i,j;

        printf("Please enter a A-Z: ");
        scanf("%c",&ch);
        if(ch >= 'A' && ch <= 'Z'){
                for(i = 0; i <= (ch - 'A'); i++){
                        for(j = 0; j < i ; j++){
                                putchar('_');
                        }
                        for(j = 0; j <= i; j++){
                                printf("%c",ch-j);
                        }
                        printf("\n");
                }
        }else{
                printf("enter erorr!");
        }
        return 0;
}

例2-3:九九乘法表

c 复制代码
#include <stdio.h>

int main(void){
    int i,j;
    int num = 0;

    for(i = 1; i <= 9; i++){
        for(j = 1; j <= i; j++){
            num = i * j;
            printf("%d x %d = %-4d",j,i,num);
        }
        printf("\n");
    }

    return 0;
}

例2-4:打印出所有的"水仙花"数。"水仙花"数是指一个3位数,其各个位数字立方和等于该数本身。

c 复制代码
#include <stdio.h>

int main(){
    //100-999
/*  int num = 0;

    for(int i = 100; i <= 999; i++){
        num = (i % 10) * (i % 10) * (i % 10) + 
              (i / 10 % 10) *  (i / 10 % 10) * (i / 10 % 10) +
              (i / 100 % 10) * (i / 100 % 10) * (i / 100 % 10);
        if(num == i){
            printf("%d  ",i);
        }
    }
    putchar('\n');
*/

    int i, j, k;
    for(i = 1; i <= 9; i++){
        for(j = 0; j <= 9; j++){
            for(k = 0; k <= 9; k++){
                if(i*i*i + j*j*j + k*k*k == i*100 + j*10 + k){
                    printf("%d  ",i*100 + j*10 + k);
                }
            }

        }
    }
    putchar('\n');
    return 0;
}

三、while循环

3.1 语法结构

c 复制代码
while (条件表达式) {  
	/*循环语句块*/	
}

执行流程

与for差不多,只不过是把初始化条件写到外面了,把更新表达式写到里面了。

3.2 特殊形式

while的条件表达式不能省略。

省略花括号

c 复制代码
while (条件表达式) 
	//一条语句

循环体只有一条语句时可以不用花括号。

不使用符合语句(花括号)时,while语句到第一个";"视为语句结束。

c 复制代码
int n = 0;
while (n < 3)
	printf("n = %d\n",n);		//死循环打印n=0
	n++;

while后跟 空语句 (C中单独的分号表示空语句),有时故意用带空语句的while语句,因为所有的任务都在测试条件中完成了,不需要在循环体中做什么。

例:跳过输入的第1个非空白字符或数字

c 复制代码
while(scanf("%d",&num) == 1)
	;	

这种情况更好的方式是使用continue语句。

3.3 终止循环

方式1:在循环体内改变表达式的终止条件

c 复制代码
int n = 5;
while(n < 7){
	//...
	n++;
}

方法2:在函数体内利用break语句

c 复制代码
int n = 5;
while(n < 7){
	if(表达式){
		break;		//if的表达式为真,终止并跳出循环
	}
}

方式3 :在条件表达式内改变("不要用")

c 复制代码
int n = 5;
while(n++ < 7){
	//...
}
c 复制代码
int n = 5;
while(n-- < 7){	//可能会跳出,一般n减到该类型最小,再减1跳到最大值
	//...
}

3.4 for和while比较

  • for 循环可以实现while循环的功能,while循环也可以实现for循环的功能
  • for 循环通常用在事先知道总循环次数的场景------计数循环
  • while 循环可以用在事先不知道循环次数的场景,而是以达到某个目标为目的------不确定循环

3.5 C风格读取循环

c 复制代码
int n,num;
n = scanf("%d",&num);
while(n ==1){
	/*循环行为*/
	n = scanf("%d",&num);
}
可替换为:
while(scanf("%d",&num) == 1){
	/*循环行为*/
}

3.6 示例

例3-1:从键盘输入整数,把整数进行累计求和,并统计偶数的个数,用户输入字母q结束输入

c 复制代码
#include <stdio.h>

int main(){
    int num,ret;
    int add = 0,count = 0;
/*
    printf("Please enter a integer(q to quit): ");
    ret = scanf("%d",&num);	//scanf()返回成功输入的个数,输入对象不匹配指定格式时,返回0
    while(ret == 1){		//假设这里写成ret = 1会导致什么情况?1.死循环 2.当输入一个字母后,就一直输入不进去了。原因是输入字母scanf()读不到,返回0,并且不对缓冲区内的字母做处理,去判断循环条件ret又被赋值1,进入循环读取还是会遇到刚才哪个字母,如此反复,导致输入不进去。可用putchar()解决。
        printf("Please enter a integer(q to quit): ");
        add += num;
        if(num % 2 == 0){
						count++;
				}
        ret = scanf("%d",&num);
    }
    printf("%d,%d\n",add,count);
*/
    printf("Please enter a integer(q to quit): ");
    while(scanf("%d",&num) == 1){
        printf("Please enter a integer(q to quit): ");
        add += num;
        if(num % 2 == 0){
						count++;
				}
    }
    printf("%d,%d\n",add,count);
    return 0;
}

例3-2 : 辗转相除法求最大公约数

最大公约数思路:

假设两个数字a和b,求两个数字相除的余数c=a%b,如果余数为0,则b为最大公约数。如果b不为零,a=b,b=c,继续循环计算。

最小公倍数思路:

两个数的最小公倍数数等于两个数的乘积除以两个数的最大公约数。即:x,y的最小公倍数 min(公倍数)=x*y÷max(公约数)

c 复制代码
#include <stdio.h>

int main(){
    unsigned int a,b,c,t;

    printf("Please enter tow integer: ");
    scanf("%d%d",&a,&b);

    if(a < b){
        t = a;
        a = b;
        b = a;
    }

    t = a * b;
    while((c = a % b) != 0){
        a = b;
        b = c;
    }

    printf("MAX = %d\n",b);
    printf("MIN = %d\n",t / b);


    return 0;
}

例3-3 :打印100以内所有的素数,并统计素数的个数

素数是指只能被1和它本身整除的正整数,1不是素数。

c 复制代码
#include <stdio.h>

int main(){
    int num = 2,i = 2,n = 0;
    int flag;

    while(num < 100){
        flag = 1;
        i = 2;
        while(i < num){
            if(num % i == 0){
                flag = 0;
                //break;
            }
            i++;
        }
        if(flag){
            printf("%d ",num);
            n++;
        }
        num++;
    }
    printf("\n n = %d\n",n);

    return 0;
}

四、do-while循环

4.1 语法结构

c 复制代码
do{
	/*循环体*/
}while(条件表达式);

执行逻辑

五、循环辅助控制语句

5.1 break语句

  • break就是大哥,在switch语句中用于终止跳出本层switch语句
  • 在循环中用于终止跳出本层循环体,常和if语句一起使用
  • 必须在switch或循环语句内,不能单独出现

例5-1:打印100以内所有的素数

c 复制代码
#include <stdio.h>

int main(){
    int i, j;
    int count = 0;

    for(i = 2; i < 100; i++){
        for(j = 2; j < i; j++){
            if(i % j == 0){
                break;
            }
        }
        if(j >= i){
            printf("%d ",i);
            count++;
        }
    }
    printf("\ncount = %d\n",count);

    return 0;
}

5.2 continue语句

continue语句结束本次循环后续语句,直接去判定下一次循环条件,看是否执行循环。常和if一起使用

例5-2:打印1到100的所有数,其中能被3整除的数值不打印

c 复制代码
#include <stdio.h>

int main(){
    int i, j;
    int count = 0;

    for(i = 1; i <= 100; i++){
        if(i % 3 == 0){
            continue;
        }
        printf("%d ",i);
    }
    putchar('\n');
    return 0;
}

例5-3:输入一个整数n, 判断它是不是一个素数,若用户输入的不是整数,重新输入。

c 复制代码
#include <stdio.h>

int main(){
    int num,i;

    while(1){
        printf("Please enter a integer: ");
        if(scanf("%d",&num) == 0){
            getchar();		
            //如果用户输入的是非数字字符(例如字母 'a'),scanf 会匹配失败,返回 0,并且不会从输入缓冲区中移除这些字符。
            //此时如果不处理,下一次循环中 scanf 又会读到同样的无效字符,再次失败,导致无限循环输出 "Please enter a integer: "。
            //getchar() 每次读取并丢弃一个字符(例如 'a'),从而让缓冲区前进一步。这样下次循环时 scanf 就能尝试读取后续的输入(可能是数字,或者继续清除下一个无效字符)。
            //如果用户输入了多个无效字符(如 "abc"),需要循环多次才能清空。更健壮的做法是:while(getchar() != '\n');  // 清空整行输入
            continue;
        }

        for(i = 2; i < num; i++){
            if(num % i == 0){
                printf("%d NO!\n",num);
                break;
            }
        }
        if(i >= num && num != 1){
            printf("%d IS!\n",num);
        }
    }
    putchar('\n');
    return 0;
}

六、goto-无条件跳转语句

  • goto是C语言的任意跳转语句关键词,后接跳转的标签。

  • 语法结构如下:

    c 复制代码
    label:语句
    	//其它代码
    	goto label
  • label为定义的一个标签,定义的规则与变量的命名相同,可以写在goto语句的后面,也可以在前面

  • goto语句只能在一个函数内部跳转,它并不允许跳转出一个函数外部。

goto构造循环

c 复制代码
#include <stdio.h>

int main(void){
    int i = 1,sum = 0;
loop:
    if(i<=100){
        sum += i;
        i++;
        goto loop;
    }

    printf("%d\n",sum);
    return 0;
}

goto跳过本次循环

c 复制代码
#include <stdio.h>

int main(void){
    int a = 10;
loop:
    do{
        if(a == 15){		//满足一定条件时跳过本次循环的后续语句
            a += 1;
            goto loop;
        }
        printf("%d\n",a);
        a++;
    }while(a<20);
    return 0;
}
相关推荐
stevenzqzq2 小时前
Kotlin 协程:withContext 与 async 核心区别与使用场景
android·开发语言·kotlin
CDN3602 小时前
弱网下游戏盾掉线重连失败?链路保活与超时参数优化
开发语言·游戏·php
im_AMBER2 小时前
Leetcode 153 课程表 | 腐烂的橘子
开发语言·算法·leetcode·深度优先·图搜索
烈风2 小时前
01_Tauri环境搭建
开发语言·前端·后端
cch89182 小时前
PHP爬虫框架大比拼
开发语言·爬虫·php
l1t2 小时前
DeepSeek辅助编写的dmp转schema和csv文件c语言程序
c语言·开发语言·windows
DREW_Smile2 小时前
自定义类型:联合体和枚举
c语言·开发语言
算法鑫探2 小时前
显示器插座最短连线算法(蓝桥杯十六届C组编程题第二题)
c语言·数据结构·算法·排序算法·新人首发
女王大人万岁2 小时前
Golang实战gRPC与Protobuf:从入门到进阶
服务器·开发语言·后端·qt·golang