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