交换奇偶数宏与offsetof宏实现
交换奇偶位
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。
具体思路
💥 宏的实现思路和函数不大一样,如果我们用函数写可能会遍历数据的每一个位来拿到奇数位和偶数位,但是用宏来写遍历不大靠谱,那么怎么才能拿到数据的奇数位和偶数位并使奇偶数位互换呢?
这给人的第一感觉是很难下手,不知道该怎么办,但是这个问题如果我们了解了位操作符其实并不是很难。
💪💪让我们来以一个例子看看具体的做法:
💦假设我们交换10的奇数位和偶数位,10写成2进制为00000000 00000000 00000000 00001010
我们只需要将10分别与0xaaaaaaaa和0x55555555相与,就可以分别得到10的奇数位和偶数位,得到奇偶数位如何交换呢?
👇 看这里👇
经过上述过程,10交换完奇偶数位后,变成了5
代码实现
#define CHANGE_BIT(n) ((n)&0xaaaaaaaa)>>1|((n)&0x55555555)<<1
运行结果
offsetof宏
写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明
具体思路
offsetof() 是C自带的一个宏,它的作用就是计算结构体成员相对于首地址处的偏移量。
💪💪让我们先来看一下offsetof本身是怎么用的,再模拟实现一下这个宏。
offsetof()宏是有两个参数,一个是结构体名字,另一个是结构体成员名,这样可能不大直观,写个代码看一下👀👀
struct test
{
char c1;
int i;
char c2;
};
💥 c1,i,c3相当于首地址的偏移量分别是多少呢?让我们先分析一下结构体对齐相关知识。
💥由上图还可以看到,三个结构体成员相对于首地址的偏移量分别为 0、4、8,让我们运行一下看看是不是这样。
代码实现
💥可以看出和我们分析的一样,那么体的宏怎么编写呢?我们在分析的时候,开始设为0偏移,然后看成员变量所占字节数,和默认对齐数,来确定在内存中存放的位置,那么我们可以使结构体开始为0地址,结构体成员取地址其实就是它本身的偏移量。
#define MY_OFFSETOF(structName,memberName) (size_t)&(((structName*)0)->memberName)
💥实现方式就是将0强制转换成结构体类型指针,然后指向的成员变量取地址,再强转成size_t类型,正好就是它的偏移量