题目一:序列中删除指定数字
#include <stdio.h>
int main()
{
int a=0;
int arr[50]={0};
int c=0;
scanf("%d",&a);
for(int i=0;i<a;i++)
{
scanf("%d",&arr[i]);//输入a个值
}
scanf("%d",&c);//输入要删除的数据
int i=0;
int j=0;
for(i=0;i<a;i++)
{
if(c!=arr[i])//如果条件不成立,if语句里面的j不再加一,此时的i比j大一
{
arr[j]=arr[i];//如果条件成立,就把i下标的值给j下标了
j++;
}
}
for(int k=0;k<j;k++)
{
printf("%d ",arr[k]);//此时数组里的元素的个数是j个,最后一位与前一位相同,不要输出它
}
return 0;
}
题目二:变种水仙花数
这个题就比较简单了:
#include <stdio.h>
int main()
{
for (int i = 10000; i <= 99999; i++)//逐个排查从10000到99999所有符合条件的数
{
int sum = 0;
for (int j = 10; j <= 10000; j *= 10)
{
int a = (i % j) * (i / j);//比如12345第一步是5*1234,第二次循环是45*123,然后是345*12,最后是2345*1。
sum = a + sum;//把所有结果加起来
}
if (sum == i)
{
printf("%d ", i);
}
}
return 0;
}
题目三:数组串联
这个也不难,就是拼接一下就行了
#include <stdio.h>
#include <stdlib.h>
int* getConcatenation(int* nums, int numsSize, int* returnSize)
//注意,nums是原先就有的数组,需要我们自己赋值,numsSize是原先数组的长度,returnSize是后来的ans数组的长度
{
int* ans = (int*)malloc(sizeof(int) * numsSize * 2);//malloc开辟两倍的numsSize的空间
for (int i = 0; i < numsSize; i++)
{
ans[i] = nums[i];
ans[i + numsSize] = nums[i];//这就是普通的赋值了
}
*returnSize = numsSize * 2;
return ans;
}
int main()
{
int arr[] = { 1,2,3 };
int returnSize = 0;
int* p = getConcatenation(arr, 3, &returnSize);
for (int i = 0; i < returnSize; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
题目四:交换奇偶位
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。
这个就需要思考一下了。先看一下代码
#define SWAPBIT(n) ((( (n) & 0x55555555 ) << 1 )|(( (n) & 0xaaaaaaaa )>>1))
#include<stdio.h>
int main()
{
printf("%d", SWAPBIT(13));
return 0;
}
最后打印出来的结果是14.
如果想要把奇数位和偶数位互换,我们就必须要知道奇数位和偶数位分别都是什么数字。
比如13。0000 0000 0000 0000 0000 0000 0000 1101我们就需要把奇数位给提取出来,这里我们需要用到&操作符。
13&0x55555555就是0000 0000 0000 0000 0000 0000 0000 1101&
0101 0101 0101 0101 0101 0101 0101 0101
得出来的结果就是 : 0000 0000 0000 0000 0000 0000 0000 0101
标记为1的就是奇数位 因为偶数位是0所以此时不会保留偶数位。
再让它左移1.得到 000 0000 0000 0000 0000 0000 0000 01010
此时的1就都到了偶数位处。
而13&0xaaaaaaaa就是0000 0000 0000 0000 0000 0000 0000 1101&
1010 1010 1010 1010 1010 1010 1010 1010
得出来的结果就是 : 0000 0000 0000 0000 0000 0000 0000 1000
标记为1的就是偶数位 因为奇数位是0所以此时不会保留奇数位。
我们将它右移1.得到 00000 0000 0000 0000 0000 0000 0000 100
此时的1就都到了奇数位处。
然后再将它们按位或一下。
000 0000 0000 0000 0000 0000 0000 01010
00000 0000 0000 0000 0000 0000 0000 100
就是交换之后的结果了:
0000 0000 0000 0000 0000 0000 0000 1110
换成十进制就是14.
题目五:offsetof宏的实现
写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明。
想实现这个函数宏的实现,就要先知道这个函数是干什么的。
这个函数包含在头文件stddef.h里面,type应为结构或联合类型,而member是里面的成员。而它计算的就是这个成员的在整个自定义类型里的偏移量。
#include<stddef.h>
#include<stdio.h>
struct A
{
int i;
char c;
};
int main()
{
int ret =offsetof(struct A, c);
printf("%d", ret);
return 0;
}
打印出的是4。
知道了它是怎么样的一个函数,我们就可以用宏来实现一下这个函数。
#include<stdio.h>
#define My_offsetof(s,m) ((size_t)&(((s*)0)->m))
struct A
{
int i;
char c;
};
int main()
{
int ret =My_offsetof(struct A, c);
printf("%d", ret);
return 0;
}
这个就是我们自己实现的offsetof函数。
(s*)0的意思就是把0强制转换成结构体类型,相当于就是当前结构体的首地址,就是0号地址。
而(s*)0)->m的意思就是相较于0号地址的位置,m在哪里。
&(((s*)0)->m)),我们知道&的作用是拿地址,拿到的是相较于0号地址->m的地址(m的地址号其实就是偏移量,所以我们下面就需要一个强转的东西)。
(size_t)的意思就是把地址强制转换成size_t类型。