写一个宏,计算结构体中某变量相对于首地址的偏移。
结果
#define struct(struct_type,numname) (size_t)&(((struct_type*)0)->numname)
实现过程
#include<stdio.h> #define struct(struct_type,numname) (size_t)&(((struct_type*)0)->numname) //struct_type 是结构体类型名 numname是成员名 //先将0转换为一个结构体类型的指针,相当于某个结构体的首地址是0。结构体成员相对于首地址的偏移量就不需要减去首地址了。 //0指针->访问成员变量,取出成员变量的地址,就是相对于首地址的偏移量 //然后将取出来的地址强制类型转换转换成(size_t)打印即可 struct S { int i; char a; int b; }; int main() { printf("%zd\n", struct(struct S , i)); printf("%zd\n", struct(struct S, a)); printf("%zd\n", struct(struct S, b)); return 0; }
上面打印的结果如下
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换
结果
#define Swapnum(a) (((a)&0xAAAAAAAA)>>1|((a)&0x55555555)<<1)
实现过程
#include<stdio.h> #define Swapnum(a) (((a)&0xAAAAAAAA)>>1|((a)&0x55555555)<<1) int main() { int a = 6; printf("%d\n", Swapnum(a)); return 0; } //6的二进制为 0000 0000 0000 0000 0000 0000 0000 0110 //要取得奇数位0 1 那么偶数位必须全部清0 可采用按位与将偶数位全部清0 // 0000 0000 0000 0000 0000 0000 0000 0110 // 1010 1010 1010 1010 1010 1010 1010 1010 十六进制为0xAAAA AAAA // 0000 0000 0000 0000 0000 0000 0000 0010 使用右移操作符将二进制奇数位右移一位 //同样要去得偶数位1 0 那么奇数位也必须全部清0 可采用按位与将奇数位全部清0 // 0000 0000 0000 0000 0000 0000 0000 0110 // 0101 0101 0101 0101 0101 0101 0101 0101 十六进制为0x5555 5555 // 0000 0000 0000 0000 0000 0000 0000 0100 使用左移操作符将二进制偶数位左移一位 // // // 将移位后的二进制按位或即可 // 0000 0000 0000 0000 0000 0000 0000 0001 // 0000 0000 0000 0000 0000 0000 0000 1000 // 0000 0000 0000 0000 0000 0000 0000 1001 //十进制数为9