1. 写一个宏实现offsetof
1.1 offsetof是什么
offsetof是一个宏,用来检索成员相对于其父结构开头的偏移量。
1.2 模拟实现offsetof
(1)思路
1.先把将数字0转化成一个结构体类型的指针,这样等于某个结构体的首地址是0,此时这个指针指向的成员就是相对于0的偏移量
2.取出地址,因为偏移量不可能为负数,所以用size_t将偏移量进行强制转化,求得偏移量
(2)代码
#include<stdio.h>
struct S
{
char a;
int b;
double c;
};
#define OFFSETOF(type,name) (size_t)&(((type*)0)->name)
int main()
{
printf("%d\n", OFFSETOF(struct S,c));
printf("%d\n", OFFSETOF(struct S,b));
printf("%d\n", OFFSETOF(struct S,c));
return 0;
}
2. 写一个宏实现整数二进制奇偶位交换
思路
一看到二进制数,我们要对其进行操作,一定要想到用位操作符进行解决,虽然不能一下子解题,但是至少我们的大方向是正确的,顺着往下思考就会简单很多。
- 要交换奇偶位,那说明我们要先把奇偶位取出来,再交换
- 如何交换?下面就很巧妙了,先看看这两个十六进制数
0xaaaaaaaa = 10101010101010101010101010101010(偶数位为1,奇数位为0)
0x55555555 = 01010101010101010101010101010101(偶数位为0,奇数位为1)
这两个十六进制数的二进制数十分有规律,奇偶数位交替为0,1
所以我们可以这样做:
((num)&0x55555555)<<1:让num先与0x55555555按位与,得到其所有的奇数位,偶数位被置为0,然后左移一位,右边补一个0,奇数位到偶数位上。
((num)&0xaaaaaaaa)>>1:让num先与0xaaaaaaaa按位与,得到其所有的偶数位,奇数位被置为0,然后右移一位,左边补一个0,偶数位到奇数位上。
然后把分离出的奇数位和偶数位相加就OK了。
例如: 一个整数10000他的二进制数为 00000000000000000010011100010000
((num)&0x55555555)<<1分离出奇数位变为00000000000000000000101000100000
((num)&0xaaaaaaaa)>>1分离出偶数位变为00000000000000000001000100000000
相加后为00000000000000000001101100100000 得到十进制数为6944,正确
代码
#include<stdio.h>
#define SWAP_BIT(x) (x = (((x & 0x55555555)<<1) + ((x&0xaaaaaaaa)>>1)))
int main()
{
int a = 0;
scanf("%d",&a);
SWAP_BIT(a);
printf("%d\n", a);
return 0;
}
总结
不知道0xaaaaaaaa和0x55555555这两个十六进制数,我根本不会写!!!还是要多练