(c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换

目录

  • 1. 写一个宏实现offsetof
    • 1.1 offsetof是什么
    • 1.2 模拟实现offsetof
      • (1)思路
      • (2)代码
  • 2. 写一个宏实现整数二进制奇偶位交换
    • 思路
    • 代码
    • 总结

在这里插入图片描述

1. 写一个宏实现offsetof

1.1 offsetof是什么

offsetof是一个宏,用来检索成员相对于其父结构开头的偏移量。

(c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换_第1张图片

1.2 模拟实现offsetof

(1)思路

1.先把将数字0转化成一个结构体类型的指针,这样等于某个结构体的首地址是0,此时这个指针指向的成员就是相对于0的偏移量

2.取出地址,因为偏移量不可能为负数,所以用size_t将偏移量进行强制转化,求得偏移量

(2)代码

#include
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. 写一个宏实现整数二进制奇偶位交换

思路

一看到二进制数,我们要对其进行操作,一定要想到用位操作符进行解决,虽然不能一下子解题,但是至少我们的大方向是正确的,顺着往下思考就会简单很多。

  1. 要交换奇偶位,那说明我们要先把奇偶位取出来,再交换
  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,正确

(c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换_第2张图片
(c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换_第3张图片

代码

#include
#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这两个十六进制数,我根本不会写!!!还是要多练

(c语言)写一个宏,实现offsetof,实现整数二进制奇偶位交换_第4张图片

你可能感兴趣的:(C语言进阶,c语言,算法,开发语言)