循环控制语句

循环语句

一、goto循环

goto原本是用于实现代码的跳转的,注意:只能在同一个函数中跳转。

goto对代码的逻辑性和易读性是有一定的影响的,所以要慎用goto

1.1 goto的基本使用格式

代码块1;
    goto NEXT;
代码块2;
NEXT:    //标签
代码块3;

1.2 执行逻辑

先执行代码块1,然后遇到goto语句,直接跳转到对应的标签继续向下执行代码块3

代码块2 就被跳过了 不执行。

上面代码中的 NEXT叫做标签,名字可以随便起 符合命名规范即可,一般都是大写。

代码中可以定义多个标签,goto到哪个标签,就到哪个标签后面开始执行。

例:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("11111111\n");
	goto NEXT; //直接跳转到 NEXT 继续向下执行
	printf("22222222\n");//被跳过
	printf("33333333\n");//被跳过
	printf("44444444\n");//被跳过
NEXT:
	printf("55555555\n");

	return 0;
}

1.3 使用goto实现循环

我们平时使用的循环一般都是有结束条件的

否则就是死循环了

例:使用goto输出 5行 hello world

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("----start----\n");
	int count = 0; //用来计数的
LOOP:
	printf("hello world\n");
	count++;   //count = count + 1;
	if(count<5){   //这个条件不满足时 就不再goto了
		goto LOOP;//如果无条件的goto 就是死循环了
	}
	printf("----end----\n");

	return 0;
}

练习:

使用goto实现计算 1+2+3+…+100 求和。

实现思路:
#if 0
int sum = 0;
sum += 1;
sum += 2;
...
sum += 100;
#endif

#if 0
int sum = 0;
int i = 1; //用于控制循环次数的变量 称之为循环变量 i j k 
sum += i;
i++;
sum += i;
i++;
....
sum += i;
i++;
#endif

int sum = 0;
int i = 1;
LOOP:
sum+=i;
i++;
if(i<=0){
    goto LOOP;
}

答案:

#include <stdio.h>
int main(){
    int sum = 0;//用来保存求和的结果 此处初始化成0 是必须的
    int i = 0;//用来控制循环的次数 以及每次加的值
LOOP:
    sum += i;
    i++;
    if(i<=100){
        goto LOOP;
    }
    printf("sum = %d\n", sum);
    return 0;
}

二、 while循环

2.1 格式

while(表达式){
    代码块;
}

2.2 执行逻辑

先执行表达式,如果表达式为真,则执行代码块

然后继续执行表达式,如果还为真,就再执行代码块

直到表达式为假 循环立即结束 继续执行循环后面的代码

while中表达式的用法和 if…else 的表达式用法一样。

注意:代码块中一般都有用于表达式结果的语句 来控制循环的次数

例:使用while循环实现 打印 5行 hello world

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("----start----\n");

	int i = 0; //循环变量命名 一般都是  i j k
	while(i < 5){
		printf("hello world\n");
		i++;
	}

	printf("----end----\n");

	return 0;
}

练习:

1.使用while循环,计算 1~100 求和。

#include <stdio.h>
int main(){
    int sum = 0;
    int i = 1;
    while(i <= 100){
        sum += i;
        i++;
    }
    printf("sum = %d\n", sum);
    return 0;
}

2.猴子吃桃问题

猴子第一天摘了若干个桃,当即就吃掉了一半数量的桃

没吃过瘾,又多吃了一个;

第二天,在剩下的桃中,又吃了一般数量

没吃过瘾,又多吃了一个;

。。。

依次类推,以后的每天都吃一半数量再多一个

到10天再想吃桃的时候,发现,只剩下一个了。

问:猴子第一天摘了多少个桃。

要求使用while循环实现。

/*
9
第10天 1个
第9天  4个      (1+1)*2
第8天  10个     (4+1)*2
..
*/

#include <stdio.h>
int main(){
    int count = 1;
    int i = 0;
    while(i < 9){
        count = (count+1)*2;
        i++;
    }
    //当循环结束的时候 count记录的就是 第一天的桃子的数量
    
    printf("第一天有 %d 个桃\n", count);
    
    return 0;
}

思考:

如何实现:把每天剩余的桃子数量都输出出来?

#include <stdio.h>
int main(){
    int count = 1;
    int i = 0;
    while(i < 9){
    	printf("第 %d 天有 %d 个桃\n", 10-i, count);
        count = (count+1)*2;
        i++;
    }
    printf("第 %d 天有 %d 个桃\n", 10-i, count);
    
    return 0;
}

3.思考 下面的代码会输出什么?

//没有代码块的while循环可以将{}用分号 ; 替换
//while(表达式);

int x = 100;
while(x--){}
//while(x--);  //这种写法和上面那行是一样的
printf("%d\n", x); // -1

int x = 100;
while(--x);
printf("%d\n", x); // 0

三、 do…while循环

3.1 格式

do{
    代码块;
}while(表达式);    //别忘了此处有个分号

3.2 执行逻辑

先执行代码块,然后执行表达式,如果表达式为真,

则继续执行代码块,直到表达式为假,循环立即结束。

do…while 和 while 的区别:

while 先判断 后执行

do…while 先执行 后判断

do…while的代码块,不管表达式是否为真,都至少执行一次。

例:使用 do…while 实现 1~100 求和

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int sum = 0;
	int i = 1;
	do{
		sum+=i;
		i++;
	}while(i<=100);

	printf("sum = %d\n", sum);

	return 0;
}

编码:输入一个日期,输出这个日期是这一年的第几天(考虑平年闰年问题)。

如:2022年3月1日 则输出 2022年3月1日是2022年的第60天

2020年3月1日 则输出 2022年3月1日是2022年的第61天

#include <stdio.h>

//输入一个日期,输出当前日期是这一年的第几天

#define MONTH_1 31
#define MONTH_2 28
#define MONTH_3 31
#define MONTH_4 30
#define MONTH_5 31
#define MONTH_6 30
#define MONTH_7 31
#define MONTH_8 31
#define MONTH_9 30
#define MONTH_10 31
#define MONTH_11 30
#define MONTH_12 31

int main()
{
    int year, month, day;
    printf("请输入要查询的日期(年/月/日):");
    scanf("%d/%d/%d", &year, &month, &day);

	//闰年的增量  也是闰年的标志位  0  平年  1 闰年
    int leap = 0;

    //printf("%d/%d/%d\n", year, month, day);

    //判断输入的日期是否有误
    //判断年是闰年还是平年
    if(((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)){
        leap = 1;
    }

    //判断月份输入的是否有误
    if(month < 1 || month > 12){
        printf("您输入的月份有误,请重新输入\n");
        //在main函数里面使用return,结束整个程序
        return -1;
    }

    //判断日是否有误
    //月份:1 3 5 7 8 10 12 最多31天
    if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12){
        if(day < 1 || day > 31){
            printf("您输入的日期有误,请重新输入\n");
            return -1;
        }
    }

    //月份:4 6 9 11 最多30天
    if(month==4 || month==6 || month==9 || month==11){
        if(day < 1 || day > 30){
            printf("您输入的日期有误,请重新输入\n");
            return -1;
        }
    }
    
    //月份:2 闰年最多29天 平年最多28天
    if(month == 2){
        if(leap == 1){ //闰年
            if(day < 1 || day > 29){
                printf("您输入的日期有误,请重新输入\n");
                return -1;
            } 
        }else if(leap == 0){ //平年
            if(day < 1 || day > 28){
                printf("您输入的日期有误,请重新输入\n");
                return -1;
            }
        }
    }
    
    int days = 0;
    switch(month){
		case 12:
			days += MONTH_11;
		case 11:
			days += MONTH_10;
		case 10:
			days += MONTH_9;
		case 9:
			days += MONTH_8;
		case 8:
			days += MONTH_7;
		case 7:
			days += MONTH_6;
		case 6:
			days += MONTH_5;
		case 5:
			days += MONTH_4;
		case 4:
			days += MONTH_3;
		case 3:
			days += MONTH_2 + leap;
		case 2:
			days += MONTH_1;
		case 1:
			days += day;
			break;
    }

    printf("%d年%d月%d日%d年的第%d天\n", year, month, day, year, days);

    return 0;
}

四、 for循环

4.1 格式

for(表达式1;表达式2;表达式3){
    代码块;
}

4.2 执行逻辑

先执行表达式1,然后执行表达式2,如果表达式2为真,则执行代码块,然后执行表达式3

然后再执行表达式2,如果还为真,则继续执行代码块和表达式3,

直到表达式2为假,循环立即结束。

4.3关于for循环的三个表达式

表达式1:只执行一次,一般是用来给循环变量赋初值的

----C99的编译器允许for循环的第一个表达式中定义变量,

但是注意,这种方式定义的变量只能在循环内部使用

表达式2:和if或者while的表达式一样,

一般是有关系运算符和逻辑运算符组成用来判断真假的

表达式3:一般是用来改变循环变量的值从而控制循环结束的

注意:

1.这三个表达式如果不需要其中某几个,可以不写,但是两个分号 ;; 必须写

2.表达式1和表达式3,每个都可以不只是一句,如果是多句,用逗号分隔

例:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	printf("----start----\n");

#if 0
	for(int i = 0; i < 5; i++){//在表达式1中定义的 i 只能在循环内部使用
		printf("hello world\n");
	}
	//printf("i = %d\n", i);//i不能再使用了
#endif

#if 1
	int i = 0;
	for(i = 0; i < 5; i++){
		printf("hello world\n");
	}
	printf("i = %d\n", i); // 5  i可以使用
#endif

	printf("----end----\n");
	return 0;
}

练习:

1.使用for循环实现 1~100 求和。

#include <stdio.h>

int main(){
	int sum = 0;
	int i = 0;
	for(i = 1; i <= 100; i++){
		sum += i;
	}
	printf("sum = %d\n", sum);

	return 0;
}

把 goto 、while 、do…while 、for 实现的1~100求和的代码 拿出来 自己对比一下。

int sum = 0;
int i = 0;
LOOP:
sum += i;
i++;
if(i <= 100){
	goto LOOP;
}

int sum = 0;
int i = 0;
while(i <= 100){
	sum += i;
	i++;
}

int sum = 0;
int i = 0;
do{
	sum += i;
	i++;
}while(i <= 100);

int sum = 0;
int i = 0;
for(i = 0; i <= 100; i++){
	sum += i;
}

2.在终端输入一个数 [100,999]范围内的,判断这个是是不是水仙花数

水仙花数:个位个位个位 + 十位十位十位 + 百位百位百位 == 自身

如:153 <==> 333 + 555 + 111 == 27 +125 + 1 == 153

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	scanf("%d", &num);

	int g = num % 10;
	int s = num % 100 / 10;
	int b = num / 100;

	if(g*g*g + s*s*s + b*b*b == num){
		printf("%d 是水仙花数\n", num);
	}

	return 0;
}

3.输出[100,999]范围内所有的水仙花数

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	int g = 0;
	int s = 0;
	int b = 0;
	for(num = 100; num < 1000; num++){
		//循环里面尽量不要定义变量
		//因为频繁的分配和回收内存空间会产生额外的时间开销
		//int g = num % 10;
		//int s = num % 100 / 10;
		//int b = num / 100;
		
		g = num % 10;
		s = num % 100 / 10;
		b = num / 100;
	
		if(g*g*g + s*s*s + b*b*b == num){
			printf("%d 是水仙花数\n", num);
		}
	}

	return 0;
}

C语言中计算幂的函数和开平方的函数–了解即可

使用时需要加头文件 #include

编译时需要链接数学库 需要加编译选项 -lm

double pow(double x, double y); //pow 计算x的y次方

double sqrt(double x); //sqrt 计算x的非负平方根

#include <stdio.h>
#include <math.h>

int main(int argc, const char *argv[])
{
	int a = 2;
	int b = 3;
	double ret1 = pow(a, b);
	printf("ret1 = %lf\n", ret1); //8.000000
	printf("%lf\n", pow(3, 4));	//81.000000

	int x = 16;
	printf("%lf\n", sqrt(x)); //4.000000

	return 0;
}

4.使用循环配合着 putchar 函数,打印下面的图案。

在这里插入图片描述

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	char value = 'F';
	//外面循环控制行数
	for(i = 0; i < 6; i++){
		//循环体 就是一行要输出的内容

		//打印没一行的下划线的
		for(j = 0; j < i; j++){
			putchar('_');
		}
		//打印字母的
		value = 'F'; //此处重置 value 的值为 'F' 是必要的
		for(j = 0; j < 6-i; j++){
			putchar(value--);
		}
		putchar(10);//换行
	}

	return 0;
}

五、 死循环

所谓的死循环就是程序一直在循环里面执行,无限循环。

while(1){  //常用的写法
    //循环体
}

for(;;){   //注意所有表达式都可以不写 但是 两个 ;; 必须要写
    //循环体
}

//如果自己写代码 不小心死循环了 按 ctrl +  c 退出

例:

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
	printf("----start----\n");

#if 0
	while(1){
		printf("hello world\n");
		sleep(1);  //休眠1秒
	}
#endif

	for(;;){ //表达式可以不写 两个分号必须写
		printf("hello world\n");
		sleep(1);  //休眠1秒
	}

	printf("----end----\n");//永远执行不到

	return 0;
}

六、辅助控制关键字

6.1 break

break可以用在switch…case语句中,表示执行完某一个分支就立即结束整个switch…case语句

break也可以用在循环中,表示立即结束本层的循环。

6.2 cuntinue

continue 只能用于循环中,表示立即结束本层的本次循环。

6.3 return

return 如果用在函数中,使用来返回函数运行的结果的;

return 如果用在main函数中,表示理解结束整个程序。

例:

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int i = 0;
	int j = 0;
	for(i = 1; i <=5; i++){
		for(j = 1; j <= 5; j++){
			if(3 == j){
				//break;
				//continue;
				return 0;
			}
			printf("%d--%d\n", i, j);
		}
	}
	
	return 0;
}

七、控制语句综合练习

1.输出 [1,100] 范围内所有的偶数

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	for(num = 1; num <= 100; num++){
		if(0 == num%2){
			printf("%d 是偶数\n", num);
		}
	}
	return 0;
}

2.输入一个数,输出这个数的所有因子。

例如:输入 12 则输出 1 2 3 4 6 12

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	//遍历 1~num
	for(i = 1; i <= num; i++){
		if(num%i == 0){
			printf("%d\n", i);
		}
	}
	return 0;
}

3.输入一个数,判断这个数是不是完数。

完数:除了自身之外的所有因子和还等于自身。

如: 6 == 1 + 2 + 3 说明 6就是完数

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int n = 0;
	scanf("%d", &n);
	int sum = 0;

	int i = 1;
	//计算因子和
	for(i = 1; i < n; i++){
		if(n%i == 0){
			sum += i;
		}
	}
	//当上面的循环结束的时候
	//sum中保存的就是 n的所有因子和(不包括n)
	if(sum == n){
		printf("%d 是完数\n", n);
	}
	
	return 0;
}

4.输出 [1,999] 范围内所有的完数

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int n = 0;
	int sum = 0;
	int i = 0;
	for(n = 1; n < 1000; n++){
		sum = 0; //注意:此处的 sum重新置0是必要的
				//因为sum中还保存着上一个数的因子和呢
		//计算n的因子和
		for(i = 1; i < n; i++){
			if(n%i == 0){
				sum += i;
			}
		}
		//当上面的循环结束的时候
		//sum中保存的就是 n的所有因子和(不包括n)
		if(sum == n){
			printf("%d 是完数\n", n);
		}
	}

	return 0;
}

5.输出 [2, 99] 范围内所有的质数

质数:因子只有自身和1的数

解决方式1:通过标志位处理

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	int flag = 0;	//质数的标识位 0 是质数  1 不是质数
	int i = 0;
	for(num = 2; num < 100; num++){
		flag = 0;  //如果使用的是标识位来判断 记得每次 重新置0
		for(i = 2; i < num; i++){
			if(num%i == 0){
				flag = 1;
				break;
			}
		}

		if(flag == 0){
			printf("%d 是质数\n", num);	
		}
	}
	return 0;
}

解决方式2:通过判断循环结束的条件来处理

#include <stdio.h>

int main(int argc, const char *argv[])
{
	int num = 0;
	int i = 0;
	for(num = 2; num < 100; num++){
		for(i = 2; i < num; i++){
			if(num%i == 0){
				break;
			}
		}
		//上面的循化有两种结束情况
		//第一种:由于表达式2为加导致的正常结束
		//第二中:由于break导致的提前结束
		if(i == num){
			printf("%d 是质数\n", num);	
		}
	}
	return 0;
}

n的所有因子和(不包括n)
if(sum == n){
printf(“%d 是完数\n”, n);
}
}

return 0;

}


5.输出 [2, 99] 范围内所有的质数

质数:因子只有自身和1的数

解决方式1:通过标志位处理

#include <stdio.h>

int main(int argc, const char *argv[])
{
int num = 0;
int flag = 0; //质数的标识位 0 是质数 1 不是质数
int i = 0;
for(num = 2; num < 100; num++){
flag = 0; //如果使用的是标识位来判断 记得每次 重新置0
for(i = 2; i < num; i++){
if(num%i == 0){
flag = 1;
break;
}
}

	if(flag == 0){
		printf("%d 是质数\n", num);	
	}
}
return 0;

}


解决方式2:通过判断循环结束的条件来处理

​            

#include <stdio.h>

int main(int argc, const char *argv[])
{
int num = 0;
int i = 0;
for(num = 2; num < 100; num++){
for(i = 2; i < num; i++){
if(num%i == 0){
break;
}
}
//上面的循化有两种结束情况
//第一种:由于表达式2为加导致的正常结束
//第二中:由于break导致的提前结束
if(i == num){
printf(“%d 是质数\n”, num);
}
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值