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


在这里插入图片描述

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

思路

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

  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,正确

在这里插入图片描述
在这里插入图片描述

代码

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

在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyPersist.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值