【C语言基础2——分支和循环语句(2)】


前言

本文接着上文,继续学习循环。


3.3 do…while()循环

3.3.1 语法

do
	循环语句;
while(表达式);

3.3.2 执行流程

do…while()循环和while循环、for循环不同的是,do…while()是首先执行一次循环语句,然后执行判断语句,若判断条件为真,接着执行循环语句;否则退出循环。

3.3.3 do语句的特点

循环至少执行一次,使用的场景有限,所以不是经常使用。

int main()
{
    
    
int i = 10;
do
{
    
    
	printf("%d\n", i);
}while(i<10);
return 0;
}

3.3.4 do— while循环中的break和continue

3.3.4.1 break的例子

int main()
{
    
    
	int i = 1;
	do
	{
    
    
		if (i == 5)
		{
    
    
			continue; //只输出1 2 3 4,后面就进入死循环了
		}
		printf("%d ", i);
		i++;		
	} while (i<=10);
	return 0;
}

输出结果: 1 2 3 4

程序进入死循环,还没结束
在这里插入图片描述

3.3.4.2 continue的例子

int main()
{
    
    
	int i = 1;

	do
	{
    
    
		if (i == 5)
		{
    
    
			break;
		}
		printf("%d ", i);//只输出1 2 3 4,后面break,循环都不执行了,
		//程序结束了
		i++;

	} while (i <= 10);
	return 0;
}

输出结果: 1 2 3 4
在这里插入图片描述

3.4 练习

3.4.1 计算n的阶乘

int main()
{
    
    
	int ret = 1;	
	for (int i = 1; i <=3; i++)
	{
    
    
		ret = ret * i;//计算3的阶乘,输出是6
	}
	printf("%d", ret);
	return 0;
}

输出结果,3的阶乘 3!= 6
该处使用的url网络请求的数据。
修改程序,随意输入一个整数,求n阶乘。

int main()
{
    
    
	int num = 1;
	int ret = 1;
	scanf("%d", &num);//输入整数
	for (int i = 1; i <= num; i++)
	{
    
    
		ret = ret * i;//求阶乘
	}
	printf("%d", ret);
	return 0;
}

输入3,输出6
在这里插入图片描述

3.4.2 输出n的阶乘求和

将各个数的阶乘求出后,再相加。代入1,2 ,3计算。

int main()
{
    
    
	int n ,j,ret = 1;
	int sum = 0;
	for (n = 1; n <= 3; n++)//一共n个数,外部循环
	{
    
    
		ret = 1;
		for ( j = 1; j <=n; j++)//每个数求阶乘,内部循环
		{
    
    
			ret = ret * j;//求阶乘
		}
		sum += ret;//阶乘求和
	}
	printf("%d", sum);

	return 0;
}

上面的程序求阶乘,是每一个数字都从1开始相乘到自身,求出阶乘后再相加。可以对程序进行优化,每次相乘不要从1开始,可以将前面的结果保存起来,乘上最后一个数。例如:求3的阶乘,不用再用1x2x3,而是用2!乘以3。

int main()
{
    
    
	int n = 1;
	int ret = 1;
	int sum = 0;
	for (n = 1; n <= 3; n++)
	{
    
    
		ret = ret * n;
		sum += ret;
	}
	printf("%d", sum);
	return 0;
}

输出结果为9。
在这里插入图片描述

3.4.3 二分法查找数

二分法查找,又可以称为折半查找算法。每次查找后,下一次的查找范围就能减少一半。

比如我买了一双鞋,你好奇问我多少钱,我说不超过300元。你还是好奇,你想知道到底多少,我就让你猜,你会怎么猜?
答案:你每次猜中间数。

int main()
{
    
    
	int arr[] = {
    
     1,2,3,4,5,6,7,8,9,10 };
	int k = 7;//这是要查找的数,其下标为6
	int length = sizeof(arr) / sizeof(arr[0]);//求取数组长度
	int left = 0;//左下标
	int right = length - 1;//右下标
	int mid = 0;//中间

	while (left<=right)
	{
    
    
		mid = left + (right-left) / 2;//改成这种较好
		//mid = (left + right) / 2;
		//上面的写法有个缺点,当上下标无限大时,两者之和会超出定义类型范围
		if (arr[mid]>k)
		{
    
    //第一次比对,中间值超过K,则k的范围在数组的左半边
		//所以缩写范围,左标为0不动,右边变成中间减1,就是中间值的左边一位
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
    
    //若第一次比对,中间值小于K,则k的范围在数组的右半边
		//所以缩小一半范围,右标为0不动,左边变成中间加1,就是中间值的右边一位
			left = mid + 1;
		}
		else//左右相等时就是找到了那个数
		{
    
    
			printf("找到了,下标是: %d\n", mid);
			break;
		}
	}
	if (left>right)//左标超过右标,找不到
	{
    
    
		printf("找不到了\n");
	}
	return 0;
}

3.4.4 多个字符从两端向中间移动

分别用while循环和for循环写程序:

3.4.4.1 while循环代码

//注意这两个头文件要添加
#include<stdlib.h>//库函数
#include<Windows.h>//和win系统相关

int main()
{
    
    
	char arr1[] = "welcome to bit!!!!!";
	char arr2[] = "###################";
	int left = 0;
	int right = strlen(arr1)-1;//下标减1
	
	printf("%s\n", arr2);
	//while循环
	while (left<=right)
	{
    
    
		Sleep(1000);//延迟函数,延长1秒时间,打印效果明显
		arr2[left] = arr1[left];//字符串对应位置赋值
		arr2[right] = arr1[right];
		left++;//左边向中间移动
		right--;//右边向中间移动
		printf("%s\n", arr2);
	}
	return 0;
}

输出结果如下:
在这里插入图片描述

3.4.4.2 for循环代码

//注意这两个头文件要添加
#include<stdlib.h>//库函数
#include<Windows.h>//和win系统相关

int main()
{
    
    
	char arr1[] = "welcome to bit!!!!!";
	char arr2[] = "###################";
	int left = 0;
	int right = strlen(arr1)-1;

	printf("%s\n", arr2);
	//for循环
	for (left=0,right=strlen(arr1)-1; left <= right; left++,right--)
	{
    
    
		Sleep(1000);
		system("cls");//清屏,动态刷新函数
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
			
		printf("%s\n", arr2);
	}
	return 0;
}

使用了清屏函数,输出结果会动态显示在一行上
在这里插入图片描述

3.4.5 密码登录三次

判断两个字符串是否相同,比较是不能使用==,应该使用strcmp

#include<string.h>

int main()
{
    
    
	char password[20] = {
    
     0 };
	int i, j = 0;
	//假设正确密码为abcd
	for ( i = 0; i < 3; i++)
	{
    
    
		printf("请输入密码: ");
		scanf("%s", password);
		//两个字符串的比较是不能使用==
		//应该使用strcmp
		//将输入密码与正确密码比较,相同则返回值为0
		if (strcmp(password,"abcd")==0)
		{
    
    
			printf("密码正确!\n");
			break;
		}
		else
		{
    
    
			printf("密码错误,请重新输入!\n");
		}
	}
	if (i==3)
	{
    
    
		printf("三次密码都输入错误,退出程序!\n");
	}
	return 0;
}

3.4.6 猜数字游戏

游戏要求

  1. 电脑随机生成一个数字(1~100)
  2. 玩家猜数字
    玩家猜小了,就告知猜小了
    玩家猜大了,就告知猜大了
    直到猜对为止
  3. 游戏可以一直玩
#include<time.h>
#include<stdlib.h>

void menu()
{
    
    
	printf("************************\n");
	printf("********  1.play  ******\n");
	printf("********  0.exit  ******\n");
	printf("************************\n");
}

void play()
{
    
    
	//1、生成随机数
	int random_num = rand() % 100 + 1;//生成1-100的随机数字
	//printf("%d\n",random_num);
	int input = 0;
	while (1)
	{
    
    
		printf("请输入数字: ");
		scanf("%d", &input);
		if (input>random_num)
		{
    
    
			printf("猜大了\n");
		}
		else if (input<random_num)
		{
    
    
			printf("猜小了\n");
		}
		else
		{
    
    
			printf("恭喜你,回答正确!\n");
			break;
		}
	}

}
int main()
{
    
    
	int input = 0;
	srand((unsigned int)time(NULL));//跟系统时间相关的真正的随机数
	do
	{
    
    
		menu();//先输出
		printf("请按菜单选则: ");//先输出
		scanf("%d", &input);//根据输入判断
		switch (input)
		{
    
    
			case 1://玩游戏
				play();
				break;
			case 0://退出游戏
				printf("退出游戏\n");
				break;
			default://
				printf("选择错误,重新选择!\n");
				break;
		}
	} while (input);
	//输入为1,进入循环,玩游戏
	// 为0退出循环
	//输入其他,则依旧循环,重新输入,直到输入的是1或0为止
	return 0;
}

4、goto语句

C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。

但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如:一次跳出两层或多层循环。

多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。

4.1 goto语言真正适合的场景

真正的适用场景如下:

for(...)
	for(...)
	{
    
    
		for(...)
		{
    
    
			if(disaster)
			goto error;//返回,退出到标签出
		}
	}
…
error://标签
	if(disaster)
// 处理错误情况

4.2 goto举例

4.2.1 goto 语句不能跨函数跳转

int main()
{
    
    
	n:
	printf("hehe\n");
	printf("hehe\n");
	printf("hehe\n");
	goto n;//goto 语句不能跨函数跳转

	return 0;
}

4.2.2 一个关机程序

下面是使用goto语句的一个例子,然后使用循环的实现方式替换goto语句

只要程序运行起来,电脑就在1分钟内关机,如果输入:我是猪,就取消关机。(这个关机程序大家看看就行,最好不要运行,真会关机的)

//关机程序,请大家不要尝试运行
#include <stdlib.h>
#include <string.h>

int main()
{
    
    
	char input[20] = {
    
    0};
	system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的
again:
	printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
	scanf("%s", input);
	//判断
	if (strcmp(input, "我是猪") == 0)
	{
    
    
		system("shutdown -a");//取消关机
	}
	else
	{
    
    
		goto again;
	}
	return 0;
}

不用goto语句,用while循环也可以实现。

int main()
{
    
    
	char input[20] = {
    
     0 };
	system("shutdown -s -t 60");//system是一个库函数,是用来执行系统命令的
	while (1)
	{
    
    
		printf("请注意,你的电脑在1分钟内关机,如果输入:我是猪,就取消关机\n");
		scanf("%s", input);
		//判断
		if (strcmp(input, "我是猪") == 0)
		{
    
    
			system("shutdown -a");//取消关机
			break;
		}
	}
	return 0;
}


总结

本文和上篇文章集中写了分支和循环语句的知识,按照B站的学习内容更新,这部分内容也暂时告一段落了。随着后续学习的深入,如果有进一步的体会,前面的博文也会适当做一些修改。

下篇将会更新函数相关的内容。

猜你喜欢

转载自blog.csdn.net/taibudong1991/article/details/123742873