写一个宏,可以将一个整数字的奇数位和偶数位交换。写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明

写一个宏,可以将一个整数字的奇数位和偶数位交换

背景:
0xaaaaaaaa = 10101010101010101010101010101010 (偶数位为1,奇数位为0)

0x55555555 = 1010101010101010101010101010101 (偶数位为0,奇数位为1)

分析:
偶数位移动到奇数位((n&(0x55555555))<<1)):将奇数位先置0,向左移1位,偶数位就正好在奇数位上了;

奇数位移动到偶数位((n&(0xaaaaaaaa))>>1):将偶数位先置0,向右移1位,奇数位就正好在偶数位上了。
偶数位移动到奇数位:
写一个宏,可以将一个整数字的奇数位和偶数位交换。写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明_第1张图片
如上图所示,奇数位换偶数位一样。

写一个宏,可以将一个整数字的奇数位和偶数位交换。写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明_第2张图片

那么我们就可以想到&(按位与)位运算符,0x55555555

&(按位与,有0即为0,双1才为1)
所以我们得出:
整数n的奇数位左移1位:
(n&0x55555555)<<1

偶数位右移1位
便(n&0xaaaaaaaa)>>1

最后我们再把奇数位左移的结果和偶数位右移的结果用 | (按位或)位运算得出最终结果
写一个宏,可以将一个整数字的奇数位和偶数位交换。写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明_第3张图片

所以我们进行宏定义:(((n&(0x55555555))<<1)|((n&(0xaaaaaaaa))>>1))

#define CHANGE(n) (((n&(0x55555555))<<1)|((n&(0xaaaaaaaa))>>1))

写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明

分析:
A:我们可以知道,结构体变量的地址就是结构体中第一个变量的地址,偏移量为0,
B:所以我们如果要求结构体中的变量的偏移量,便可以和结构体变量地址相减即可,
C:最后转成char*类型,那便是最后偏移了多少个字节

/*
structur:结构体变量的地址,也就是首地址	例如结构体变量p,传参传&p
variable:需要求结构体中偏移量的那变量	例如结构体变量p,传参传&p.结构体中某变量名
把上面两个地址,强转成char*类型,然后(char*)variable-(char*)structur,便可算出variable的偏移量

*/
#define OFFSETOF(variable,structur) (((char*)variable)-((char*)structur))

//例如:
typedef struct Person{
char a;
int b;
double c;
}person;
//定义一个结构体变量
person p;
printf("偏移量:%d\n",OFFSETOF(&p.c,&p))	//结构体中c的偏移量为8

补充:
0x33333333 = 110011001100110011001100110011
(1和0每隔两位交替出现)

0xcccccccc = 11001100110011001100110011001100
(0和1每隔两位交替出现)

0x0f0f0f0f = 00001111000011110000111100001111
(1和0每隔四位交替出现)

0xf0f0f0f0 = 11110000111100001111000011110000
(0和1每隔四位交替出现)

你可能感兴趣的:(我的大学生活,c语言)