我的C语言学习日记05——分支和循环练习题

求n的阶乘

int main()
{
	int i = 0;
	int ret = 1;
	int n = 0;
	scanf("%d", &n);
	for (i = 1; i<=n; i++)
	{
		ret = ret*i;
	}
	printf("ret=%d", ret);
}

求1!+2!+3!+4!

重点是要初始化ret

int main()
{
	int i = 0;
	int ret = 1;//若等于0则乘多少都为0
	int n = 0;
	int sum = 0;
	//1+2+6+24=33
	for (n = 1; n <= 4; n++)//n的阶乘相加4次
	{
		ret = 1;//初始化,防止重复运算导致错误
		        //初始化运行过程n=1时:循环1次,ret初始值为1结束值为1;ret=1*1=1(为1!)
							  //n=2时:循环2次,ret初始值为1结束值为1;ret=1*1*2=2(为2!)
							  //n=3时:循环3次,ret初始值为1结束值为1;ret=1*1*2*3=6(为3!)
							  //n=4时:循环4次,ret初始值为1结束值为1;ret=1*1*2*3*4=24(为4!)
		        //若不初始化n=1时:循环1次,ret初始值为1结束值为1;ret=1*1=1
						  //n=2时:循环2次,ret初始值为1结束值为2;ret=1*1*2=2
						  //n=3时:循环3次,ret初始值为2结束值为12;ret=2*1*2*3=12
						  //n=4时:循环4次,ret初始值为12结束值为288;ret=12*1*2*3*4=288
		for (i = 1; i <= n; i++)//n的阶乘
		{
			ret = ret*i;
		}
		sum = sum + ret;//把每个数字的阶乘相加
	}
	printf("sum=%d\n", sum);//sum=33
	return 0;
}

                //初始化运行过程n=1时:循环1次,ret初始值为1结束值为1;ret=1*1=1(为1!)
                              //n=2时:循环2次,ret初始值为1结束值为1;ret=1*1*2=2(为2!)
                              //n=3时:循环3次,ret初始值为1结束值为1;ret=1*1*2*3=6(为3!)
                              //n=4时:循环4次,ret初始值为1结束值为1;ret=1*1*2*3*4=24(为4!)
                //若不初始化n=1时:循环1次,ret初始值为1结束值为1;ret=1*1=1
                          //n=2时:循环2次,ret初始值为1结束值为2;ret=1*1*2=2
                          //n=3时:循环3次,ret初始值为2结束值为12;ret=2*1*2*3=12
                          //n=4时:循环4次,ret初始值为12结束值为288;ret=12*1*2*3*4=288

进一步优化

int main()
{
	int ret = 1;
	int n = 0;
	int sum = 0;
	for (n = 1; n <= 4; n++)
	{
		ret = ret*n;//循环到几就是几的阶乘
		sum = sum + ret;//依次相加
	}
	printf("sum=%d\n", sum);
}

 二分查找/折半查找

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12 };//有序数组
	int k = 7;
	int left = 0;//左下标
	//  计算数组arr所占的字节
	//     (此处为44个字节)        单个元素所占的字节数,此处为下标是0的元素所占的字节(4个字节)
	//          ↓                  ↓
	int sz = sizeof(arr) / sizeof(arr[0]);//计算出sz数组的总长度,为11
	int right = sz - 1;//右下标
	while (left <= right)
	{
		int mid = (left + right) / 2;//中间值
		if (arr[mid] > k)//说明要找的k在mid的左边
		{
			right = mid - 1;//右下标移到中间值左移一个
		}
		else if (arr[mid] < k)//说明要找的k在mid的右边
		{
			left = mid + 1;//左下标移到中间值右移一个
		}
		else
		{
			printf("找到了,下标是%d\n", mid);
			break;
		}
	}
	if (left>right)
		printf("找不到\n");



	return 0;
}

 打印一串字符,从两端到中间依次显示

和二分查找有异曲同工之妙 
注意在求长度时,下标比元素个数少一,所以减一,字符串结尾有\n所以再减去一个一,求出右下标总共需要减去二

int main()
{
	char arr1[] = "welcome to bit!!!!!!!";
	char arr2[] = "#####################";
	int left = 0;
	//int right = sizeof(arr) / sizeof(arr[0]) - 2;  //减去2是因为字符串结尾有\n,
	int right = strlen(arr1) - 1;
	while (left <= right)
	{
		arr2[left] = arr1[left];//替换左下标
		arr2[right] = arr1[right];//替换右下标
		left++;//左下标右移一个
		right--;//右下标左移一个
		system("cls");//执行系统命令的一个函数-cls,效果为清空屏幕
		printf("%s\n", arr2);
		Sleep(1000);//休息1秒
	}
	
	return 0;
}

模拟用户登录,用户只能登陆三次

strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。

int main()
{
	int i = 0;
	int a = 3;
	char passward[20] = { 0 };
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf("%s", passward);
		if (strcmp(passward, "123456") == 0)
		{
			printf("登陆成功\n");
			break;
		}
		else
		{
			a--;
			printf("密码错误请重试,还剩余%d次机会\n",a);
		}
	}
	if (i==3)
	printf("三次机会已用光,退出程序\n");

	return 0;
}

判断输出结果

static关键字使得局部变量变得静态,离开了作用范围不被重置初始化
就相当于int b出了sum函数就失忆了,每次回来都是3;但static int b不在失忆,能记得上一次的数值所以能累加起来数值

int sum(int a)//a每次循环都是2
{
	int c = 0;
	static int b = 3;//静态局部变量,延长生命周期到整个main函数
	c += 1;//c每次循环都是0,所以这里的c一直就是1
	b += 2;//b每次循环都加2
	return (a + b + c);
}
int main()
{
	int i;
	int a = 2;
	for (i = 0; i < 5; i++)
	{
		printf("%d,", sum(a));
	}
	return 0;//结果8,10,12,14,16
}

三个数字从大到小输出

int main()
{
	int a = 0;//a放最大值
	int b = 0;//b次之
	int c = 0;//c放最小值
	int nmb= 0;//中间值
	scanf("%d %d %d", &a, &b, &c);//输入时的间隔符号要注意格式与函数内保持一致,否则间隔符就参与排序
	if (a < b)//若b比a大,就交换一下把较大的值放到a里
	{
		nmb = a;
		a = b;
		b = nmb;
	}
	if (a < c)//若c比a大,就交换一下把较大的值放到a里
	{
		nmb = a;
		a = c;
		c = nmb;
	}   //此时,三个数中最大的值放到了a里,在比较b和c的值就可以了
	if (b < c)//若c比b大,就交换一下把较大的值放到b里
	{
		nmb = b;
		b = c;
		c = nmb;
	}
	
	printf("%d %d %d", a, b, c);


	return 0;
}

打印1-100之间的所有的3的倍数

int main()
{
	int i = 0;
	int a = 1;
	for (i = 0; i < 100; i++)
	{
		if (a % 3 == 0)//3的倍数本质来说对3取模等于0
		{
			printf("%d ", a);
			
		}
		a++;
	}

	return 0;
}

求最大公约数-辗转相除法

求两个数最大公约数就是两个数取模为0的数,若不为0用较小的数和余数再次取模,一直循环到取模为0的数

int main()
{
	int m = 0;
	int n = 0;
	int r = 0;
	scanf("%d%d", &m, &n);
		while (m%n)//取余结果不为零的进入循环体调整各参数位置,即开始辗转
		{
		r = m%n;//把余数储存
		m = n;//较小的数存到m
		n = r;//余数存到n,为进入下一个循环做好准备,在下一次循环中即为较小的数对余数取模
		}
	
	printf("%d\n", n);

	return 0;
}

打印1000年到2000年之间的闰年

判断是否为闰年的依据
1.能被4整除并且不能被100整除
2.能被400整除

int main()
{
	int year = 0;
	int a = 0;//定义计数器
	for (year = 1000; year <= 2000; year++)
	{
		if (year % 4 == 0 && year % 100 != 0)//&&逻辑与:需两边都满足
		{
			printf("%d ", year);
			a++;
		}
		else if (year % 400 == 0)
		{
			printf("%d ", year);
			a++;
		}
	}
}
	printf("\n闰年数为:%d\n", a);
//	//------进化版----
	int main()
	{	
		int year = 0;
		int a = 0;//定义计数器
		for (year = 1000; year <= 2000; year++)
		{
			if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))//||逻辑或:两边满足一个即可
			{
				printf("%d ", year);
				a++;
			}
		}
		printf("\n闰年数为:%d\n", a);

		return 0;
	}

打印100-200之间的素数

判断素数规则:1.试除法,产生2到i-1个数字
素数:只能被1和本身整除的数

int main()
{
	int i = 0;
	int j = 0;
	int a = 0;//计数器
	for (i = 100; i <= 200; i++)
	{
		for (j = 2; j < i; j++)
		{
			if (i%j == 0)//判断2到i本身之间的数有无可整除的数
			{
				break;
			}
		}
		if (i == j)
		{
			a++;
			printf("%d ", i);
		}
	}printf("\n素数个数为:%d \n", a);
	return 0;
}

优化

如果i=a*b,那么a或者b中至少有一个数字小于等于开平方i

	int  main()
{
	int i = 0;
	int j = 0;
	int a = 0;//计数器
	for (i = 100; i <= 200; i++) //for(i=101;i<=200;i+=2)  因为偶数不可能是素数,直接跳过偶数
	{    //在开平方i之前找就可以了
		for (j = 2; j <=sqrt(i); j++)//sqrt()  为非负实数平方根函数//是数学库函数
		{
			if (i%j == 0)
			{
				break;
			}
		}
		if (j>sqrt(i))
		{
			a++;
			printf("%d ", i);
		}
	}printf("\n素数个数为:%d \n", a);

	return 0;
}

找出1-100所有含有9的数字

int main()
{
	int i = 0;
	int a = 0;//计数器
	for (i = 1; i <= 100; i++)
	{
		if (i % 10 == 9 )//说明个位为9
		{
			a++;
			printf("%d ", i);
		}
		else if (i / 10 == 9)//说明十位为9
		{
			a++;
			printf("%d ", i);
		}
	}
	printf("\n个数为:%d\n", a);

	return 0;
}

分数求和;计算1/1-1/2+1/3-1/4+1/5.....+1/99-1/100的值

int main()
{
	int i = 0;
	double sum = 0.0;//求和结果采用浮点型存储
	int flag = 1;
	for (i = 1; i <= 100; i++)
	{
		sum += flag*1.0 / i;//要得到小数,要保证除号两端必须至少有一个浮点数
		flag = -flag;//改变正负符号
	}
	printf("%lf\n", sum);//打印浮点数要用%lf

	return 0;
}

求最大值:求10个整数中最大值

int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int i = 0;
	int max = arr[0];//假设数组中第一个为最大值
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 1; i < sz; i++)
	{
		if (arr[i]>max)
			max = arr[i];
	}
	printf("max= %d\n", max);

	return 0;
}

乘法口诀,打印9*9乘法口诀

int main()
{
	int i = 0;//行数
	for (i = 1; i <= 9; i++)//行数  打印9行
	{
		int j = 0;//列数
		for (j = 1; j <= i; j++)//有几行就打印几列
		{
			printf("%d*%d=%-2d ", i, j, i*j);//%2d 打印两位靠右对齐,%-2d 打印两位靠左对齐
		}
		printf("\n");//每行末尾回车
	}

	return 0;
}

猜数字游戏

1.电脑会生成一个随机数2.猜数字
          rand()需要调用#include <stdlib.h>头文件
          使用time()函数需要引用头文件#include <time.h>

用时间戳生成随机数——猜数字游戏

用rand()函数生成随机数:
在调用rand()函数生成随机数之前,需要使用srand()函数来为rand()函数设置随机数的起点,用时间戳作为srand函数的参数来设置随机数的生成起始点 

时间戳:
当前计算机的时间减去计算机的起始时间(1970年1月1日0时0分0秒)=(xxxxx)秒,即为时间戳;
time()函数返回时间戳(time()函数的参数类型为time_t*的指针)
time()函数返回的值是time_t类型,time_t的本质是long长整型


srand()函数的参数需为unsigned int即无符号整型, 而time_t的本质是long长整型,就可以用(unsigned int)强制转换为无符号整型
注:随机数起点不要频繁设置,频繁设置随机效果不好,所以要放在循环外面

void menu()
{
	printf("****************************\n");
	printf("***** 1.play  0.exit   *****\n");
	printf("****************************\n");
}
void game()
{
	//游戏本体
	
	int ret = 0;
	int guess = 0;//接收猜的数字
	//1.生成一个随机数,
	ret = rand() % 100 + 1;//把随机数限定到1-100之间
	                       //rand()生成随机数函数,需要sranf()函数设置随机起点
	//2.猜数字
	while (1)
	{
		printf("请猜数字:");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了\n");
		}
		else if (guess < ret)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你,猜对了!\n");
			break;
		}
	}

}
							        

int main()   //时间戳:当前计算机的时间减去计算机的起始时间(1970年1月1日0时0分0秒)=(xxxxx)秒即为时间戳

{
	int input = 0;
//     强制转换为无符号整型																																	
//	          ↓                                                                                                                                                          
	srand((unsigned int)time(NULL));//在调用rand()函数生成随机数之前,需要使用srand()函数来为rand()函数设置随机数的起点,用时间戳作为srand函数的参数来设置随机数的生成起始点;注:随机数起点不要频繁设置,频繁设置随机效果不好,所以要放在循环外面
//	   ↑                 ↑
//     ↑                time()函数返回时间戳 ————> time(time_t*timer)函数 ; time()函数返回的值是time_t类型。
//  srand()函数的参数需为unsigned int即无符号整型                  ↑                                    ↑
	do  //                                           time()函数的参数类型为time_t*的指针                time_t的本质是long长整型
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
				game();//进入到游戏
				break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} 
	while (input);
	
	return 0;
}

goto语句

适合的场景是多层循环内跳出

int main()
{
	again://要用冒号结尾!!!!!!
	printf("hello\n");
	goto again;//again相当于标记,执行进程跳转到标签处
	//----或者----
	printf("hello\n");
	goto a;
	printf("你好\n");//这里的作用是跳过本语句
a:
	printf("hehe\n");

	return 0;
}

自动关机程序

用goto语句实现 

sysem()是执行系统命令的函数,shutdown -s -t 60 是60秒关机的指令
sysem()函数需要头文件#include <stdlib.h>
strcmp()比较两个字符串的函数,在本程序中用于比较用户输入的字符

int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");//sysem()是执行系统命令的函数//shutdown -s -t 60 是60秒关机的指令
again:
	printf("你的电脑将在一分钟内关机,请输入:我是猪,以取消关机\n请输入:");
	scanf("%s", input);
	if (strcmp(input, "我是猪") == 0)//strcmp()比较两个字符串的函数
	{
		system("shutdown -a");
	}
	else
	{
		goto again;//用while(1)循环也可以实现
	}


	return 0;
}

用while语句实现

int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");//sysem()是执行系统命令的函数//shutdown -s -t 60 是60秒关机的指令
	while (1)
	{
		printf("你的电脑将在一分钟内关机,请输入:我是猪,以取消关机\n请输入:");
		scanf("%s", input);
		if (strcmp(input, "我是猪") == 0)//strcmp()比较两个字符串的函数
		{
			system("shutdown -a");
			break;
		}
	}

	return 0;
}

谨慎运行此程序,注意提前保存数据

更有甚者可以把此可运行文件添加到电脑的本地服务中去,开机自启动“自动关机程序”,非常狠

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值