【C语言】交换奇偶位和 offsetof 宏的实现

简介: 【C语言】交换奇偶位和 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;
}

c00715ad63544421bb122d3f0e64eec2.png


👉offsetof 宏👈


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

8115d4fad13d4775b30f3618793840f2.png

示例 1:

输入:

b6b3a04fde9d4a5182ece67f61b1c0aa.png


输出:

offsetof(struct S, a) = 0

offsetof(struct S, b) = 0

offsetof(struct S, c) = 0

offsetof(struct S, d) = 0



struct S结构体内存对齐示意图

b7118137729c49d39738d413b348a79f.png


如果对结构体内存对齐这个知识点不熟悉的话,可以看一下这篇博客:【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;
}

5727adf70a11477c882ea8a2a90b46b4.png



👉总结👈


本篇文章主要讲解了如何交换二进制补码的奇偶位和模拟实现offsetof宏。其中模拟实现offsetof宏是百度曾经考过的原题,希望大家能过掌握。如果大家觉得文章写得不错,大家给个三连支持一下哦!谢谢大家啦!💖💝❣️












相关文章
|
1天前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(下)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
6 0
|
1天前
|
C语言
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)(上)
C语言进阶21收尾(编程练习)(atoi,strncpy,strncat,offsetof模拟实现+找单身狗+宏交换二进制奇偶位)
9 0
|
1天前
|
自然语言处理 编译器 Linux
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(下)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
5 0
|
1天前
|
程序员 编译器 C语言
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(中)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
11 0
|
1天前
|
存储 程序员 编译器
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(上)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
10 0
|
6天前
|
存储 Linux C语言
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-2
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
6天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
5天前
|
C语言
C语言—内存函数的实现和模拟实现(内存函数的丝绸之路)
C语言—内存函数的实现和模拟实现(内存函数的丝绸之路)
18 0
|
5天前
|
C语言
C语言—字符函数与字符串函数(字符问题变简单的关键之技)
C语言—字符函数与字符串函数(字符问题变简单的关键之技)
6 0
|
1天前
|
C语言 C++
C语言进阶⑭(内存函数_以字节操作)momcpy+mommove+memcmp+memset
C语言进阶⑭(内存函数_以字节操作)momcpy+mommove+memcmp+memset
5 0