35道C语言练习题

目录

1.打印100-200之间的素数

2.输出9*9乘法口诀表

3.判断1000到2000年的闰年

4.计算1!+2!+...+10!

5.二分查找

6.猜数字小游戏 

7.输入一个数字,使其从高位到低位依次输出,例如输入2563,输出2 5 6 3

8.不使用中间变量交换两个数字

(1)加减法(缺点:如果两个整形过于大,会溢出)

(2)异或法

9.求一个整数存储在内存中的二进制中1的个数

10.运算符的运算

11.任意输入三个数将其按照从大到小输出

12.打印一个菱形

13.打印0到100000的自幂数

14.求n+nn+nnn+...nn.n(n个n) (不考虑溢出)  

15.求第n个斐波那契数字(递归方法和循环方法)

(1)递归

(2)循环

16.求k^n

17.给一个数组,封装两个函数一个进行初始化全0,一个进行打印

18.倒置数组

19.求一个二进制数中1的个数

20.打印一个二进制数列的奇数位和偶数位

21.给两个int(32位)整数m和n的二进制表达,求其中有多少个位(bit)不同?

22.跳水选手问题

23.写一个函数,可以实现右旋字符串中的第K个字符串

24.写一个函数,可以实现左旋字符串中的第K个字符串

25.写一个函数判断一个字符串是否是另一个字符串旋转后的字符串

26.在杨氏矩阵中找一个数

27.strlen函数的实现

28.strcpy函数的实现

29.strcat函数的实现

30.strcmp函数的实现

31.strstr函数的实现

32.memcpy函数的实现

33.memmove函数的实现

34.通讯录

        test.c

        contact.h

        contact.c

35.顺序表的实现

        test.c

        Seqlist.h

       Seqlist.c


1.打印100-200之间的素数

试除法

思路:素数的定义是这个数字除了1和本身不能被整除,而且整数都可以写成c=a*b的形式,且有a或者b<=sqrt(c) (sqrt是开平方的意思),那么也就说判断sqrt(c)之前的数字如果能被整除,则说明不是素数,若是不能被整除,那么sqrt(c)后边的数字一定不能被整除,那么这个数字就是素数。

#include<stdio.h>
#include<math.h>//后边用到sqrt库函数
int main ()
{
	int i=0;
	int count =0;//用做后边用来计数
	for (i=100;i<=200;i++) //要找到100到200之间的素数 首先要先生成100到200之间的数字
	{
		int j=0;
		for (j=2;j<=sqrt(i);j++)//产生小于开平方i的数字 
		{
			if (i%j==0)//在这里判断i除以j的余数  如果等于0 这说明整除了 那么不是素数 跳出循环
			{
				break;
			}
		}
		if (j>sqrt(i))// 如果大于开平方i 则表明开平方i之前都没有数字能被整除 那么之后肯定也不会被整除 那么这个就是素数
		{
			count++;//  找到一个 计数一次
			printf("%d ",i);
		}
	}
	printf("\n");
	printf("count=%d\n",count);//最后将计数次数也打印出来
	return 0;
}

2.输出9*9乘法口诀表

思路:9*9口诀即

1*1=1

2*1=2  2*2=4

3*1 =3 3*2 =6  3*3 =9

...  ...

9*1=9  9*2 =18 ...

可以看出列是从1到9,行也是从1到9,则可以分别用for循环来生成。

#include<stdio.h>
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;
}

3.判断1000到2000年的闰年

思路:闰年法则为四年一闰,百年不闰,四百年在闰,故可遍历1000到2000的数字,是4的倍数同时不是100的倍数是闰年,或者是400的倍数也是闰年,这两个条件是或的关系。代码如下

#include<stdio.h>
int main ()
{
	int year=0;
	int count =0;
	for (year=1000;year<=2000;year++)
	{
		if(year%4==0 && year%100!=0) //判断是4的倍数 并且不是100的倍数
		{
			printf("%d ",year);
			count++;
		}
		else if (year%400==0)// 第二个判断规则 判断400的倍数
		{
			printf("%d ",year);
			count++;
		}
	}
	printf("\ncount=%d ",count);//计数看看共有多少闰年
	return 0;
}

4.计算1!+2!+...+10!

思路:首先n!=n*(n-1)*(n-2)*..*2*1,因为每个因子都是连续的,且是1到10的阶乘,故可以用两层循环进行描述,代码如下:

过程为:第一次n=1,进入循环i=1,ret=1,ret=1*1,相当于计算1!;sum=0+1=1;

              第二次n=2,进入循环i=1,ret=1,ret=1*1,1<2,再进入小循环i=2,ret=1*2,相当于计算2!;sum=1+2;  

               第三次n=3,进入循环i=1,ret=1,ret=1*1,1<2,再进入小循环i=2,ret=1*2,2<3继续进入小循环i=3,ret=2*3;sum=3+6; 

                .........

#include <stdio.h>
int main ()
{
	int i=0;
	int n=0;
	int sum=0;
	for (n=1;n<=10;n++)// 首先生成1到10的数字 给求n!传入参数
	{
		int ret=1; 
		for (i=1;i<=n;i++) 
			{
				ret =ret*i;//这里可以计算n!但是n不能是太大的数字 否则会溢出 对于此题是可以的
			}
		sum =sum+ret;
	}
	printf("sum=%d\n",sum);
	return 0;
}

5.二分查找

思路:比如从1 2 3 4 5 6 7 8 9 10中找到7,各个元素下标依次是0-9,能查到的情况在注释中说明的很清楚,主要说下查不到的条件:

如果是从1 2 4 5 6 7 8 9 10 11中查找3  情况如下

查找次数 左边元素下标(对应的数字) 中间元素下标(对应的数字) 右边元素下标(对应的数字) 中间元素与3的大小关系
第1次 0(1) 4(6) 9(11) >  在左边
第2次 0(1) 1(2) mid-1=3(5) < 在右边
第3次 mid+1=1(2) 2(4)

3(5)

>  在左边
第4次 1(2) 1(2) mid-1=2(4) < 在右边
第5次 mid+1=2(4) 1(2) 2(4) < 在右边
第6次 mid+1=3(5) 2(4) 2(4) >在左边

可以看出 从左边元素下标大于右边元素下标开始   就再也找不到了。

#include<stdio.h>
int main ()
{
	int arr[]={1,2,3,4,5,6,7,8,9,10};
	int sz =sizeof(arr)/sizeof(arr[0]);//计算元素个数
	int left=0;//最左边的元素下标为0
	int k=7;  //假如是找7 
	int right =sz-1; //最右边的数下标为sz-1
	while (left<=right)  //这个等号不能少 
	{
		int mid=(left+right)/2;//中间元素的下标
		if(arr[mid]>k)  //中间元素下标大于要查找的数字 说明数字在中间的左边 左侧数字下标不动 右侧下标比中间值减1
			//这样就去掉右边一半
		{
			right=mid-1;
		}
		else if (arr[mid]<k)//中间元素下标小于要查找的数字 说明数字在中间的右边 右侧数字下标不动 左侧下标比中间值加1
			//这样就去掉左边一半
		{
			left=mid +1;
		}
		else //上边两者都不满足 则说明就是这个中间元素 
		{
			printf("找到了,下标是%d\n",mid);
			break;
		}
	}
	if(left>right) //当找到这种情况 则说明不可能找到了
	{
		printf("找不到\n");
	}
	return 0;
}

6.猜数字小游戏 

思路:

1.猜数字游戏无非就是计算机随机出一个数字,你来猜,但是主要的问题是计算机如何出数字呢?

其实可以运用c语言自带的rand函数,但是这个函数虽然能生成随机数,但是你退出游戏后再次玩的时候其实随机数还是那几个,那样游戏你就只能玩一次,后边在玩就相当于知道答案了,故需要用srand函数来调用rand函数,srand函数主要的参数是一个无符号整形,这里也有个问题就是你把数字定了之后,rand产生的数字也就那一个,故需要你自己给srand函数传入一个随机值,所有我们可以使用时间戳来实现传入随机值来使得srand函数产生随机值,这个时间戳是由time函数实现的。代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<time.h>  //下面用到时间函数
#include<stdlib.h>//用到srand库函数
void menu()
{
	printf("*********************\n");
	printf("******1.进行游戏*****\n");
	printf("******0.退出游戏*****\n");
	printf("*********************\n");
}
void game()
{
	int ret =0;
	int guess=0;
	ret =rand()%100+1;//由于随机数很大,故为了游戏体验 将其变成100以内的数字 求余数再+1 就可得到0-100的数字
	while(1)
	{
		printf("请猜数字 数字在0到100之间\n");
		scanf("%d",&guess); //%d后边不能加换行符和空格 
		if(ret >guess)
		{
			printf("猜小了\n");
		}
		else if (ret <guess)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜猜对了 真牛逼\n");
			break;
		}
	}
}
int main() 
{
	int input=0;
	//void srand(unsined int seed)  这个seed如果写成一个无符号整形的话srand生成的值
	//就一直不会变 故需将seed一直变化 所以可以用时间戳来实现seed一直变化
	//用时间戳来设置  时间戳是当前计算机的时间减去计算机起始时间(1970年1月1日0点0分0秒)
	srand((unsigned int)time(NULL));//使用rand之前先用srand进行调用 
	do 
	{
		menu();//菜单函数
		printf("请选择输入内容===>\n");
		scanf("%d",&input);//%d 后边不能加空格 否则要输入两次才行
		switch(input)  //分支语句 case 1 玩游戏 case 0 退出游戏
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新在1和0之间选择一个数字");
			break;
		}
	}
	while (input);//当输入为假即0时结束游戏
	return 0;
}

最后玩游戏的过程如下:

 

 

 可以看到玩了两把都是不同的数字,按0也可以退出游戏。

7.输入一个数字,使其从高位到低位依次输出,例如输入2563,输出2 5 6 3

思路:假如说要你只输出3的话其实是很简单的,就是拿数字直接模上1000就行了,下一位数字直接模100,依次类推,但是要求从第一个数字是2,所以这种方法显然不行,故可以考虑函数递归的方式,即可以将2563拆分成256 和 3, 再将256分成25 和6,最后将25分成2和5,代码如下:

#include <stdio.h>
void print(int x)
{
	if(x>9)   //如果输入的数字大于9 则说明这个数字最少有两位数 则进入循环进行函数调用
	{
		print(x/10);  
	}
	printf ("%d ",x%10);
}
#include <stdio.h>
int main ()
{
	int num=0;
	scanf("%d",&num);
	print(num);
	return 0;
}

 

 从图中可以看到,假如传入123这个数字,首先调用print函数,将123送进去,判断条件成立,进入循环再次调用函数,此时进行过了运算传进去的是12,再次进行判断,条件成立再次进去,如图3,这次不满足判断条件,直接进行打印,打印出来的就是1,然后再依次打印2,3,这样就可实现上述效果,其中判断条件的意思是若是小于9则说明就是一位数就直接进行打印即可,满足条件才进行函数递归。

8.不使用中间变量交换两个数字

(1)加减法(缺点:如果两个整形过于大,会溢出)

思路:假设输入为3和4

x=3 y=4
x=x+y=7 y=4
x=7 y=x-y=3
x=x-y=4 y=3
#include <stdio.h>
void swap(int* x,int* y)  //形参是实参的一份临时拷贝 不能直接传值 要把地址传进来
{
	*x=*x+*y;
	*y=*x-*y;
	*x=*x-*y;
}
int main ()
{
	int a=0;
	int b=0;
	scanf("%d %d",&a,&b);//输入的按照格式输入 中间有空格
	printf("before:%d-----%d\n",a,b);
	swap(&a,&b);
	printf("after:%d-----%d\n",a,b);
	return 0;
}

(2)异或法

思路:假如还是3和4

a=3     101B b=4  100B
a=a^b=001B b=4   100B
a=001B b=a^b=101B
a=a^b=100B b=101B
#include <stdio.h>
int main ()
{
	int a=0;
	int b=0;
	scanf("%d %d",&a,&b);//输入的按照格式输入 中间有空格
	printf("before:%d-----%d\n",a,b);
	a=a^b;
	b=a^b;
	a=a^b;
	printf("after:%d-----%d\n",a,b);
	return 0;
}

 

9.求一个整数存储在内存中的二进制中1的个数

思路:由于&有0出0,全1为1,故可以使得这个二进制数往右边移位依次与1进行按位与,为1则说明有1,结果是0则说明无1,代码如下:

#include <stdio.h>
int main ()
{
	int num =0;
	int count=0;
	int i=0;
	scanf("%d",&num);
	for (i=0;i<32;i++)
	{
		if(1==((num>>i)&1)) //使得num右移i位  按位与得1说明有一
		{
			count++;//有一计数一次
		}
	}
	printf("count=%d ",count);
	return 0;
}

 

10.运算符的运算

 首先a先使用后自增,a=0,经过逻辑与运算,最左边为0,整个为0,逻辑与右边不进行运算,a要自增,a=1,bcd不变,结果为a=1,b=2,c=3,d=4.

然后在进行逻辑或运算,此时a=1,逻辑或左边为1整个为1,右边不参加运算,则a自增,a=2,b=2,c=3,d=4.

11.任意输入三个数将其按照从大到小输出

思路:两两相比,将大数和小数进行交换,这里采用简单的方式,创建一个中间变量来实现,代码如下:

#include <stdio.h>
int main ()
{
	int a =0;
	int b =0;
	int c =0;
	scanf("%d%d%d",&a,&b,&c);
	if (a<b)
	{
		int tmp=a;    //交换ab
		a=b;
		b=tmp;
	}
	if (a<c)
	{
		int tmp =a;   //交换ac
		a=c;
		c=tmp;
	}
	if (b<c)
	{
		int tmp =b; //交换bc
		b=c;
		c=tmp;
	}
	printf("%d %d %d",a,b,c);
	return 0;
}

思路:想实现将welcome to henan 从两边往中间打印在*********上,可以将对应的位置字符直接替换过去就行了,两边打印完了之后,让左边元素往右边移动一下,让右边元素往左边移动一下即可,实现代码如下:

#include <stdio.h>
#include <string.h>
#include<windows.h>
#include<stdlib.h>
int main ()
{
	char arr1[]="Welcom to  henan";
	char arr2[]="****************";
	int le
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值