🌠 作者:@阿亮joy.
🎆专栏:《阿亮爱刷题》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
目录
- 👉交换奇偶位👈
- 👉offsetof 宏👈
- 👉总结👈
👉交换奇偶位👈
题目内容:写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。
注:二进制补码的最低位为第一位,最高位为第三十二位。
示例 1:
输入:10
输出:5
解释:10
的二进制补码为00000000000000000000000000001010
,交换奇偶位后为00000000000000000000000000000101
,该二进制补码为5
的二进制补码,故输出为5
。
思路:交换奇偶位,其实就当于将偶数位右移了一位,奇数位左移了一位。那现在的问题就转化成了如何得到偶数位和奇数位上的数字。如果想要得到奇数位上的数字,只需要让该数字和奇数位都为 1 的数字按位与,就能得到奇数位上的数字。同理,只需要让该数字和偶数位都为 1 的数字按位与,就能得到偶数位上的数字。得到这两个数字之后,对它们进行相应的移位,就能得到交换奇偶位后的结果了。
奇数位上都为 1 的数字
01010101010101010101010101010101
0x55555555
偶数位上都为 1 的数字
10101010101010101010101010101010
0xaaaaaaaa
#include <stdio.h>
#define SWAP(N) ((N & 0xaaaaaaaa) >> 1) + ((N & 0x55555555) << 1)
int Swap(const int num)
{
return ((num & 0xaaaaaaaa) >> 1) + ((num & 0x55555555) << 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret1 = Swap(n);
int ret2 = SWAP(n);
printf("ret1 = %d\n", ret1);
printf("ret2 = %d\n", ret1);
return 0;
}
👉offsetof 宏👈
题目内容:写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明。
示例 1:
输入:
输出:
offsetof(struct S, a) = 0
offsetof(struct S, b) = 0
offsetof(struct S, c) = 0
offsetof(struct S, d) = 0
struct S
的结构体内存对齐示意图
如果对结构体内存对齐这个知识点不熟悉的话,可以看一下这篇博客:【C语言】自定义类型详解。
思路:根据上面的struct S
的结构体内存对齐示意图可以知道,其实偏移量就是相对于起点的位置。所以,我们需要确定一个基准地址(起点)。为了方便,博主将 0 作为基准地址,当然也可以用任意一个数字作为基准地址。确定好基准地址后,我们就需要找到成员变量的地址,那么用成员变量的地址减去基准地址就能够得到结构体中某变量相对于首地址的偏移。
成员变量的地址
&( ( (struct_name*)0 )->mem_name)
#include <stdio.h>
#define OFFSETOF(struct_name, mem_name) (int)&( ( (struct_name*)0 )->mem_name)
struct S
{
int a;
short b;
int c;
char d;
};
int main()
{
printf("%d\n", OFFSETOF(struct S, a));
printf("%d\n", OFFSETOF(struct S, b));
printf("%d\n", OFFSETOF(struct S, c));
printf("%d\n", OFFSETOF(struct S, d));
return 0;
}
👉总结👈
本篇文章主要讲解了如何交换二进制补码的奇偶位和模拟实现
offsetof
宏。其中模拟实现offsetof
宏是百度曾经考过的原题,希望大家能过掌握。如果大家觉得文章写得不错,大家给个三连支持一下哦!谢谢大家啦!💖💝❣️