天天看点

初入C语言_3

目录(五道简单的编程题)

                        1. 计算 n的阶乘。

                        2. 计算 1!+2!+3!+……+10!

                        3. 在一个有序数组中查找具体的某个数字n。 编写int binsearch(int x, int v[], int n); 功能:在v[0] <=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x.

                        4. 编写代码,演示多个字符从两端移动,向中间汇聚。

                        5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序。

时隔一个月,我来更新了,由于个人学校考试和学习原因拖了这么长时间,但是进度不会变的,我心里也一直想着呢,所以今天我们继续来c语言的学习。

那么经过上两次的学习,大家已经对C语言最基本的程序和代码有了最基本的认识,循环和判断语句也认识了一点,俗话说光说不练假把式,有了知识的储备也要有配套的练习,这次我就来和大家一起练一些程序员从必练的一些基础编程题,废话少说,我们开始吧。

1. 计算 n的阶乘。

第一题题干给的简明直观,相信中学里大家都学了阶乘是个什么东西,我来简单讲一下,阶乘顾名思义就是一阶一阶往上乘,3的阶乘就是3*2*1,5的阶乘就是5*4*3*2*1,以此类推,n的阶乘就是从1乘到n。那如何用程序实现呢?

想一直乘下去,很明显这是个循环结构,那么前面学过的for和while循环就派上用场了,而所乘的数又是递增到n的,有了个大概的思路,我们就可以上手了

#include <stdio.h>
int main()
{
	int n = 1;
	int tmp = 1;
	while(n)
	{
		tmp *= n;//简便写法,等于tmp = tmp*n
		n++;
	}
	printf("%d", tmp);

	return 0;
}
           

首先因为是n的阶乘,所以我们肯定要定义一个自增的变量,从1开始,然后用到一个循环结构,让n乘n+1;但是要注意,接收的时候必须要再定义一个变量,如果是n*=n的话程序会崩溃,因为两边的n都在变化,所以要用一个额外的变量来控制,tmp也要从1开始,想必大家都能想明白,没人想算乘法的时候来个0。tmp每次都存入n的值,循环几次就存了几的阶乘,至于n的阶乘到底是多少,确切的数字没人知道,只能用n!表达,你想求几的阶乘就让程序循环几次就可以。

2. 计算 1!+2!+3!+……+10!

阶乘学了,那来算一个一到十的阶乘和吧。大家注意,在看博客学习的时候,自己一定要准备好编译器在旁边自己试着写,代码这个东西不练是不会有一点进步的。

这个题肯定也是比较简单了,阶乘如果会求了也就是一个相加的问题,我们直接在上一道题的基础上进行修改就可以,我们先来捋一下思路,上一道题只是让求阶乘,而这道题需要的是把阶乘加起来,所以肯定需要一个变量来存总和,也需要额外的一个循环来把算出来的阶乘加起来,所以我们先定义一个n用来表示想计算的阶乘和,也是控制第一层循环次数的,每算出一次阶乘都要把它存在tmp里,这也是第二层循环需要做的工作,最后再把它们都加到sum里,所以大概需要四个变量两层循环,废话少说,上图:

初入C语言_3

好了,简单的题目就解决了,如果你认为这个结果是正确的话,你可以拿到编译器上运行一下,你并不会得到你想要的数字,甚至算一个很小的阶乘和都算不对,你可以暂停观看自己思考一下, 我们以3的阶乘和为例,得数应该是1+(1*2)+(1*2*3)=9,我现在进行调试

初入C语言_3

 这是调试完的结果,sum=15而并非9,我相信对数字敏感一点的朋友应该能大致才出来,绝对是多乘了或多加了某些数字,没错,问题就出在这里,tmp为什么会等于12?了解阶乘原理的朋友会发现,n=4但是循环只有三次,123三个数得数等于12只有一种可能:1*1*2*2*3,现在已经显而易见了,因为tmp在n++后并没有归1导致了累积乘,所以在每次tmp乘之前都应该把其定义为1,所以正确的代码应该是这样:

#include <stdio.h>
int main()
{
	int n = 0;
	int i = 0;
	int tmp = 1;
	int sum = 0;
	for (n = 1; n <= 3; n++)
	{
		tmp = 1;
		for (i = 1; i <= n; i++)
		{
			tmp = tmp * i;
		}
		sum = sum + tmp;
	}
	printf("%d", sum);
	return 0;
}
           

3. 在一个有序数组中查找具体的某个数字n。 编写int binsearch(int x, int v[], int n); 功能:在v[0] <=v[1]<=v[2]<= ….<=v[n-1]的数组中查找x.

binsearch——二分查找,只要学稍微深入学习C语言就会知道这个查找方法,都是编程小白到大牛不可省略的查找方法,二分查找就是给你一串有序的数,可以是递增也可以是递减,不必有规律,利用三个变量,一次减少一半不符合要求的查找要求的数,效率非常高,本题指定了这些数必须是递增的,而且他给了三个变量,意思就是你需要自己创造这个数列,下面我以画图的形式来讲解给大家提供更直观的理解:

初入C语言_3

 我们假设这个数列就是一到十,用三个类似指针但非指针的变量分别来指向头、尾、中间,而mid就是(head+tail)/2,1的下标是0,10的下标是9,所以9+1除2就是4,所以指向数组下标为4的数,也就是5,这些也可以相当于二分查找的准备工作,当有了这些,就可以开始进行二分查找了。

首先,如果你要查找的数为7,它要比mid指向的5大,所以mid左边的数字肯定不可以,因为数列是由小到大递增的,所以head直接可以移动到mid的下一个,也就是6的位置,mid再次进行(head+tail)/2的运算,这次是5+9除2也就是7,所以mid指向下标为7的数字,也就是8

初入C语言_3

但是8又比7要大,所以mid右边肯定不会有,所以tail又可以改为mid-1,mid再次计算,这次指向下标为6的数字,也就是7,找到了。

初入C语言_3

这道题递增和递减都可以,但是要注意head和tail的改变,mid是由它俩控制的,而mid就是真正用来找数的工具,大家可以自己思考一下,这道题代码并不复杂,思路懂了是最重要的,下面我给大家代码:

#include <stdio.h>
int binsearch(int x,int v[],int n)
{
	int head = 0;
	int tail = x - 1;
	int mid = (head + tail) / 2;
	while (head <= tail)
	{
		if (n > v[mid])
		{
			head = mid + 1;
			mid = (head + tail) / 2;
		}
		else if (n < v[mid])
		{
			tail = mid - 1;
			mid = (head + tail) / 2;
		}
		else
		{
			return v[mid];
		}
	}
	printf("didn't find");
}
int main()
{
	int arr[] = { 0 };
	int n = 0;
	int x = 0;
	printf("How many numbers do you want to enter?");
	scanf("%d", x);
	printf("Please enter a string of increasing numbers:");
	for (int i = 0; i < x; i++)
	{
		scanf("%d", arr[i]);
	}
	binsearch(x, arr, n);
	return 0;
}
           

4. 编写代码,演示多个字符从两端移动,向中间汇聚。

这道题大意就是想让你实现一串字符或者数字打印方式的转变,由两头到中间汇聚,我们先来理一下思路,想好你要打印的字符串,例如:hello world!!!!,首先看到的是相同数量的#,然后从两边开始依次转变为你想打印的字符串,我们来想想会用到什么,两个字符串,肯定要用到两个数组,字符串变换的次数,就需要字符串的长度,第一个数组头尾分别替换到第二个数组,下标肯定也需要,而且这个操作并非一次完成的,所以肯定是个循环结构,所以我还是用画图的形式来给大家更直观地讲解一下:

初入C语言_3

下面我把代码给大家,大家可以拷到自己的编译器上运行一下,由于是个动态过程,所以我这里不便展示

#include <stdio.h>
#include <string.h>
#include <Windows.h>
int main()
{
	char arr1[] = "hello world!!!!";
	char arr2[] = "###############";
	//int sz = sizeof(arr1) / sizeof(arr1[0]) / 2;
	int len = strlen(arr2);
	int left = 0;
	int right = len - 1;
	while(left <= right)
	{
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		Sleep(1000);
		system("cls");
		left++; 
		right--;
	}
	printf("%s", arr2);
	return 0;
}
           

5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序。

大家平时在登陆QQ和微信或者一些个人账户的时候少不了的就是输入密码,可能用了十几年却也不知道其中简单的原理,我们接下来就要来实现输入密码其中简单的原理,匹配就成功,不匹配就失败,我一说匹配与否就知道肯定要用到if else语句,并且你有三次机会,肯定就是循环结构了,知道这些以后,我们就可以上手了。

密码嘛,肯定也是数组存了一组数,所以我们先要定义一个数组,然后把我们设置好的密码放进去,记住我们是写程序的,我们只要面向对象的,所以我们要扮演研发者,也要扮演用户,不断地进行调试,修改,这也是研发软件的必备思维。我依旧来通过画图的形式讲解:

初入C语言_3

在这里我还是要提一嘴,可能出现了大家没见过的东西,strcmp,由于画图板地方有限,所以我来这里给大家展开讲解,大家可能发现了strcmp和strlen比较相似,没错,都是对字符串的操作,strcmp也是库函数,意为string compare,字符串比较,头文件也和strlen一样,可能大家又有疑问了,我直接if(password=="123456")不可以吗?干嘛还需要额外的函数,在这里我提醒大家password和123456一个是数组,一个是数串,直接用==比较的话比较的只是数组的首元素地址和'1'的首地址,所以切记切记,比较两个字符串是否一样的时候,不可以使用==,而strcmp这个函数如果大家想深入研究的话,大家可以打开http://www.cplusplus.com/reference/cstring/strcmp/?kw=strcmp,可以看到

初入C语言_3

 如果返回值是0的话,说明第一个数要比第二个大,如果返回值为0,说明两个数一样,如果大于0,说明第一个数大于第二个数,在这里比较的都为ascii码值,用法下面也有演示strcmp(比较的数组1,比较的数组2),这个函数用来匹配密码正确与否是不是很方便呢?

接下来我给大家代码,还是建议大家把代码拷到编译器上进行测试和运行,毕竟只是看的话对自身的提高肯定没有那么大, 由于博客只能进行文字讲解, 效果肯定要比视频差得多,我也是尽可能讲清楚,但是编程能力如果想要提高的话,没听说过一句代码都不敲能找到好工作的,所以我也在进步,大家也一定要进步。

#include <stdio.h>
int main()
{
	int password[] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("please enter the password:");
		scanf("%d", password);
		if (strcmp(password, "123456") == 0)
		{
			printf("Password is correct");
			break;
		}
		else
		{
			printf("Password is wrong");
		}
	}
	if (i == 3)
	{
		printf("Dangerous user");
	}
	return 0;
}
           

好了,五道编程题大家一定要好好推敲,都是比较经典的题目,我会尽快推出下一篇(最近真是累),拜拜~