别划走!真的不看看全是干货的初级C语言练习题吗?一滴水都没有哦还有解析

今天,小江同学为大家带来5个亲测的干货初级C语言练习题。看完,练完,保证你的C语言跟上一层楼!

1. 排序问题

1.1 题目

请将 arr[10]={9,5,8,2,10,3,1,4,7,6}这一乱序的数组,编写一个函数 void bubble_sort(int arr[ ],int sz) ,该函数接收一个数组和字符个数为参数,并排成升序数组,并打印出来。

1.2 分析

这里,我们会使用冒泡排序

1.2.1 冒泡排序

冒泡排序大致流程:

从数组下标0开始,依次比较相邻的2个下标所对应的数字,正序则不交换,倒序则交换,如此循环往复,直到数组有序(升序or倒序)为止。

例如,以下列数据为例,想得到升序数组:

 先将下标0和1对应的数字3和2比较:3 > 2 ——> 交换

 再将下标1和2对应的数字3和7比较:3 < 7 ——> 不交换

不断重复循环,直到第一次将7排到最后:

切记!7已经是最大的了,下一次排序不考虑和7排序了

............

以此类推,直到排序成功:(总共排序4次)

5个数字;排序4趟;第1趟排4次;第2趟排3次;第3趟排2次;第4趟排1次;

结论:设有n个数字,需要排序(n-1)趟,每一趟需要排(n-对应趟数);

1.3 代码实现

1.3.1 方法1:冒泡排序

#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	//确定排序趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		//每一趟排序次数
		int j = 0;//表示下标
		for (j = 0; j < sz - 1 - i; j++)//eg.i=0,排第一趟,排10-1-0=9趟;i=1,排第二趟,排10-1-1=8趟
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[10] = { 9,5,8,2,10,3,1,4,7,6 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);//10
	//对arr进行排序,排成升序
	//arr是数组,对数组arr传参,实际上只传数组arr首元素的地址 &arr[0]
	bubble_sort(arr, sz);//冒泡排序函数
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

                                                                          输出界面

如果只传参arr[ ],会造成以下结果:

#include<stdio.h>
void bubble_sort(int arr[])
{
	int sz = sizeof(arr) / sizeof(arr[0]);//10
	printf("%d\n",sz);

}
int main()
{
	int arr[10] = { 9,5,8,2,10,3,1,4,7,6 };
	int i = 0;

	//对arr进行排序,排成升序
	//arr是数组,对数组arr传参,实际上只传数组arr首元素的地址 &arr[0]
	bubble_sort(arr);//冒泡排序函数
	
	return 0;
}

                                                                  输出界面

1.3.2 方法2:冒泡排序进阶

由于冒泡排序效率低,计算量大,我们可以进一步优化:

#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	//确定排序趟数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//假设这一趟排序的数据已经有序
		//每一趟排序次数
		int j = 0;//表示下标
		for (j = 0; j < sz - 1 - i; j++)//eg.i=0,排第一趟,排10-1-0=9趟;i=1,排第二趟,排10-1-1=8趟
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;//本趟排序的数据其实不完全有序
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}
int main()
{
	int arr[10] = { 9,5,8,2,10,3,1,4,7,6 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);//10
	//对arr进行排序,排成升序
	//arr是数组,对数组arr传参,实际上只传数组arr首元素的地址 &arr[0]
	bubble_sort(arr, sz);//冒泡排序函数
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

                                                                  输出界面

2. 生兔子问题

2.1 题目

假定一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?

2.2 分析

首先,分2种情况:

1.一开始一对大兔子

2.一开始一对小兔子

大:i

小:j

这里涉及到斐波那契数列:

斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89...

这个数列从第3项开始,每一项都等于前两项之和。

结论:i = i + j ; 现 i = 原 i + 原 j

           j = i - j ;现 j = 现 i - 原 j

ps:这只是小江的思路哦,其他的也可以

2.3 代码实现

1.一开始一对大兔子

#include<stdio.h>
#include<string.h>
//开始是一对大兔子
int main()
{
	int big = 1;
	int small = 0;
	for (int i = 1; i <= 12; i++)
	{
		big = big + small;
		small = big - small;
	}
	printf("1年后总共%d对兔子\n",small+big);//377对
	return 0;
}

                                                                        输出界面

2.一开始一对小兔子

#include<stdio.h>
#include<string.h>
//开始是一对小兔子
int main()
{
	int big = 0;
	int small = 1;
	for (int i = 1; i <= 12; i++)
	{
		big = big + small;
		small = big - small;
	}
	printf("1年后总共%d对兔子\n", small + big);//233对
	return 0;
}

                                                                    输出界面

3.二分法查找问题

3.1 题目

请用二分法查找数组arr[10]={1,2,3,4,5,6,7,8,9,10}中的任意一个数字(数字不在数组中也可以),找到输出数字对应的下标,没找到输出没找到。

3.2 分析

3.2.1 二分法查找

 以此类推,直到找到数字,或者循环结束

3.3 代码实现

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int right = sz - 1;
	while (left <= right)//限制条件,如果left>right,出现错误
	{
		int mid = (left + right) / 2;//mid要在循环中定义,mid需要多次计算
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了,%d的下标是%d\n", k, mid);
			break;
		}
	}
	if (left > right)
	{
		printf("找不到");
	}
	return 0;
}

                                                                    输出界面

4.计算阶乘之和问题

4.1 题目

请计算1!+2!+3!+4!的和,并输出结果。

4.2 分析

1!+2!+3!+4!=1 * 1 + 2 * 1 + 3 * 2 * 1 + 4 * 3 * 2 * 2 * 1

4.3 代码实现

4.3.1 方法一

#include<stdio.h>
int main()
{
	//求n的阶乘
	int n = 0;
	//1*2*3*4*5=120
	int i = 0;
	int ret = 1;//求n的阶乘,要*,所以ret不能=0
	int sum = 0;//求n的阶乘的和,要+,所以sum=0
	for (n = 1; n <= 4; n++)
	{
		ret = 1;//每次循环都需要从ret=1开始,否则ret的值会累积前面的阶乘值
		for (i = 1; i <= n; i++)
		{
			ret = ret * i;
		}
		sum = sum + ret;
	}
	printf("%d \n", sum);

	return 0;
}

                                                                        输出界面

4.3.2 方法2(方法1的改进)

4!= 4 * 3 * 2 * 1

5!= 5 * 4 * 3 * 2 * 1 = 4!* 5

#include<stdio.h>
int main()
{
	//求n的阶乘
	int n = 0;
	//1*2*3*4*5=120
	int i = 0;
	int ret = 1;//求n的阶乘,要*,所以ret不能=0
	int sum = 0;//求n的阶乘的和,要+,所以sum=0
	for (n = 1; n <= 4; n++)
	{
		ret = ret * n;
	}
		sum = sum + ret;
	printf("%d \n", sum);
	return 0;
}

                                                                      输出界面

5. 2个数的最大公约数问题

5.1 题目

给定2个数,求2个数的最大公约数。

5.2 分析

最大公约数:即两个数据中公共约数的最大者。
求解的方式比较多,暴力穷举、辗转相除法、更相减损法、Stein算法算法
此处主要介绍:辗转相除法
思路:
例子:18和24的最大公约数
第一次:a = 18  b = 24  c = a%b = 18%24 = 18
      循环中:a = 24   b=18
第二次:a = 24   b = 18  c = a%b = 24%18 = 6
      循环中:a = 18   b = 6
第三次:a = 18   b = 6   c=a%b = 18%6 = 0
  循环结束
  
此时b中的内容即为两个数中的最大公约数。

5.3 代码实现

#include<stdio.h>
int main()
{
    int a = 32;
	int b = 48;
	int c = 0;
	while (b % a)
	{
		c = b % a;
		a = c;
		b = a;
	}
	printf("%d", a);
	return 0;
}

                                                                         输出界面

PS:小江目前是个新手小白,目前,自己就总结了这些自己觉得有意义的题目。欢迎大家在评论区讨论哦!有问题也可以讨论的!

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值