初阶C语言已经完结,下面就再给大家分享几道练习题
一、
💓写一个函数,判断一个数是不是素数,并用这个函数打印100~200之间的素数
要判断素数,首先得知道素数是什么,素数也叫质数,简单的来说就是一个大于1的数,除1和它本身外没有别的因数 使用函数来判断一个数是否为素数,如果它返回1则为素数,返回0则不为素数,可以采用试除法,因为素数是除1和它本身外没有其他的因数,所以可以使用2~根号num之间的数来试除,如果在这个区间内有别的因数,就证明它不是素数,如果没有别的因数,就证明它是素数
代码演示:
//代码1:判断一个数是不是素数//为素数返回1,不为素数返回0intprime_num(intnum) { inti=0; //试除for (i=2; i<=sqrt(num); i++) { if (num%i==0) return0; } return1; } intmain() { intnum=0; scanf("%d", &num); intret=prime_num(num); if (0==ret) printf("%d不是素数\n", num); elseprintf("%d是素数\n", num); return0; }
//代码2:打印100~200之间的素数intprime_num(intnum) { inti=0; //试除for (i=2; i<=sqrt(num); i++) { if (num%i==0) return0; } return1; } intmain() { intj=0; for (j=100; j<=200; j++) { if (prime_num(j) ==1) printf("%d ", j); } return0; }
二、
💓编写一个函数,实现将数组A中的内容和数组B中的内容进行交换。(数组一样大)
要通过函数来实现交换,就得用形参来操作实参,因此就需要指针,确定好两个数组第一个元素的地址,然后交换一次地址就+1指向下一个元素,直至交换完,所以还得求出元素个数
代码演示:
voidex_change_arr(int*arr1, int*arr2, intsz) { inti=0; int*str1=arr1; //确定第一个元素的位置int*str2=arr2; inttmp=0; for (i=0; i<sz; i++) { //实现交换tmp=*str1; *str1=*str2; *str2=tmp; str1++; str2++; } } intmain() { intarr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; intarr2[10] = { 10,9,8,7,6,5,4,3,2,1 }; intsz=sizeof(arr1) /sizeof(arr1[0]); //交换ex_change_arr(arr1, arr2, sz); inti=0; //打印for (i=0; i<sz; i++) { printf("%d ", arr1[i]); } putchar('\n'); for (i=0; i<sz; i++) { printf("%d ", arr2[i]); } return0; }
三、
💓实现函数init() 初始化数组为全0
💓实现print() 打印数组的每个元素
💓实现reverse() 函数完成数组元素的逆置。
💓要求:自己设计以上函数的参数,返回值。
代码演示:
//打印函数voidprint(intarr[], intsz) { inti=0; for (i=0; i<sz; i++) { printf("%d ", arr[i]); } } //初始化函数voidinit1(intarr[], intsz) { inti=0; for (i=0; i<sz; i++) { arr[i] =0; //全部初始化为0 } } voidinit2(intarr[], intsz) { inti=0; for (i=0; i<sz; i++) { arr[i] =i; //初始化为i } } //逆序函数voidreversr_arr(int*arr, intsz) { inti=0; int*left=arr; int*right=arr+sz-1; inttmp=0; while(left<right) { tmp=*left; *left=*right; *right=tmp; left++; right--; } } intmain() { intarr[10] = { 0 }; intsz=sizeof(arr) /sizeof(arr[0]); //初始化数组init1(arr, sz); //打印数组print(arr, sz); putchar('\n'); //初始化数组init2(arr, sz); //打印print(arr, sz); putchar('\n'); //逆序数组reversr_arr(arr, sz); print(arr, sz); return0; }
四、
💓写一个函数,实现统计一个数的二进制位中1的个数
统计二进制位中1的个数有好几种方法 1.可以%2、/2(有缺陷) 2.可以使用&操作符 3.相邻两个数进行&
//代码1intbin_num(intnum) { intcount=0; while (num) { if (num%2==1) count++; num/=2; } returncount; } intmain() { intnum=0; scanf("%d", &num); intcount=bin_num(num); printf("%d的二进制位中1有%d个\n", num, count); return0; } //但是这种方法有缺陷,它不能计算负数的二进制位
//代码2intbin_num(intnum) { inti=0; intcount=0; for (i=0; i<32; i++)//32位平台下一个数的二进制位最多只有32位,所以遍历32次 { if (((num>>i) &1) ==1) //&操作符的用法得熟悉 { //>>右移操作符用法熟悉count++; } } returncount; } intmain() { intnum=0; scanf("%d", &num); intcount=bin_num(num); printf("%d的二进制位中1有%d个\n", num, count); return0; } //这种方法修复了代码1的缺陷,但是这种方法比较麻烦,无论一个啥数都要循环32次//所以效率有点慢,因此还得改进
//代码3intbin_num(intnum) { intcount=0; while (num) { num=num& (num-1); //这样写表示的意思一个数的二进制位有几个1就循环几次count++; } returncount; } intmain() { intnum=0; scanf("%d", &num); intcount=bin_num(num); printf("%d的二进制位中1有%d个\n", num, count); return0; }
五、
💓获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列
获取一个数的二进制位其实和我们前面计算一个数的二进制位有多少个1是一样的方法,只不过在本题需要进行区分偶数位和奇数位
voidPrintbit(intnum) { inti=0; //先找偶数位for (i=31; i>=1; i-=2) { printf("%d ", (num>>i) &1); } putchar('\n'); //找奇数位for (i=30; i>=0; i-=2) { printf("%d ", (num>>i) &1); } putchar('\n'); } intmain() { intnum=0; scanf("%d", &num); Printbit(num); return0; }
六、
💓两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
在这里有两种方法: 1.将m和n右移i位然后&1,判断这两个结果相不相等,以此来判断有多少个位不同 2.将m^n的结果存起来,然后判断这个结果中有多少个1
//代码1intmain() { intm=0; intn=0; scanf("%d %d", &m, &n); inti=0; intcount=0; for (i=0; i<32; i++) { if (((m>>i) &1) != ((n>>i) &1)) { count++; } } printf("%d和%d的二进制位有%d个位不同\n", m, n, count); return0; }
//代码2//按位异或操作符:^//相同为0,相异为1intmain() { intm, n; scanf("%d %d", &m, &n); intcount=0; intret=m^n; while (ret) { ret=ret& (ret-1); count++; } printf("%d和%d的二进制位有%d个位不同\n", m, n, count); return0; }
七、
💓用C语言在屏幕上输出以下图案:
菱形是由上下两部分组成的,要打印菱形可以分为先打印上面的三角形,然后再打印下面的三角形,假设要打印的菱形有13行,我们可以用第7行进行分割,上半部分打印的空格递减的,而打印的*是递增的,打印空格的规律是从上往下每一行都减少一个,打印*的规律是2*i+1,下半部分空格从上往下依次增加一个,*从上往下是2*(line-1-i)-1个
代码演示:
intmain() { intline=0; scanf("%d", &line); inti=0; intj=0; //打印上半部分for (i=0; i<line; i++) { //打印空格for (j=0; j<line-1-i; j++) { printf(" "); } //打印*for (j=0; j<2*i+1; j++) { printf("*"); } printf("\n"); } //打印下半部分for (i=0; i<line-1; i++) { //打印空格for (j=0; j<=i; j++) { printf(" "); } //打印*for (j=0; j<2* (line-1-i) -1; j++) { printf("*"); } printf("\n"); } return0; }
八、
💓给定一个乱序数组,调整数组使奇数全部都位于偶数前面。
关于排序数组这种类型的题需要使用下标进行交换,可以设置两个下标,从数组的两边往中间进行遍历,类似于二分查找算法,但在本题中只需要加上判断这个数是奇数还是偶数
代码演示:
voidswap_arr(intarr[], intsz) { intleft=0; intright=sz-1; inttmp=0; while (left<right) { //从前向后面找,找到第一个偶数,就停止while ((left<right) && (arr[left] %2==1)) { left++; } //从后面向前找,找到第一个奇数就停止while ((left<right) && (arr[right] %2==0)) { right--; } //进行奇偶数的位置交换if (left<right) { tmp=arr[left]; arr[left] =arr[right]; arr[right] =tmp; } } } //打印voidprint(intarr[], intsz) { inti=0; for (i=0; i<sz; i++) { printf("%d ", arr[i]); } } intmain() { intarr[10] = {1,5,6,8,9,7,2,3,4,10}; intsz=sizeof(arr) /sizeof(arr[0]); printf("排序前:"); print(arr, sz); putchar('\n'); swap_arr(arr, sz); printf("排序后:"); print(arr, sz); return0; }
九、
💓猜凶手
💓A说:不是我。
💓B说:是C。
💓C说:是D。
💓D说:C在胡说
💓已知3个人说了真话,1个人说的是假话。
使用代码实现凶手是谁?
代码演示:
intmain() { //假设嫌疑人是a,b,c,dcharkiller=0; for (killer='a'; killer<='d'; killer++) { //三个人说的是真话,表明四个语句只有一个语句是假(0),因此四个语句加起来就是3if ((killer!='a') + (killer=='c') + (killer=='d') + (killer!='d') ==3) { printf("凶手是%c\n", toupper(killer)); //转化为大写字母 } } return0; }
所以经过判断凶手就是C
十、
💓实现一个函数,可以左旋字符串中的k个字符
💓例如:
💓ABCD左旋一个字符得到BCDA
在这里提供一种思路:首先将逆序前段,再逆序后端,然后再将整个字符串逆序
代码演示:
//逆序函数voidreverse_part(char*str, intstar, intend) { inti, j; chartmp=0; for (i=star, j=end; i<j; i++, j--) { tmp=str[i]; str[i] =str[j]; str[j] =tmp; } } voidleft_round_arr(char*str, intk) { intlen=strlen(str); intpos=k%len; //逆序前段reverse_part(str, 0, pos-1); //逆序后段reverse_part(str, pos, len-1); //逆序整个字符串reverse_part(str, 0, len-1); } intmain() { intk=0; scanf("%d", &k); chararr[10] = { "ABCDEF" }; printf("左旋前:%s\n", arr); left_round_arr(arr, k); printf("左旋%d个字符后:%s\n", k, arr); return0; }
关于初阶C的训练题就到此结束,后面会分享关于进阶C语言的一些博客,感谢大家支持!