C生万物 | 使用宏将一个整数的二进制位的奇数位和偶数位交换

简介: 妙用位运算【按位与、按位或、移位】,交换一个二进制位的奇偶数位

✒题目分析 && 实现思路[位运算]

首先来说一下本题的实现思路🤔
  • 本题不仅是要使用宏来是实现,而且还要对一个数的二进制位进行操作,所以我们就可以想到位运算

1、获取这个整数的奇数位和偶数位

  • 因为需要交换的是这个整数二进制位的【奇数位】和【偶数位】,因此我们要先获取到它们,这里要使用到一个很巧妙的手法,可以将这个数的奇偶位分别保存下来,就要用到在十六进制中很奇特的两个数——>==5 和 a== ;因为5写成二进制的形式为0101,1均在奇数位上。a写成二进制的形式为1010,1均在偶数位上
  • 对于一个数来说可以分为32个比特位,所以我们就需要8个5和8个a,将它们展开后就是0x5555555500xaaaaaaaa;所以将这个整数与前者进行【&】运算便可以保留下它的奇数位;这个整数与后者进行【&】运算便可以保留下它的偶数位
  • [x] 按位与的运算规则是==全1才为1,有0即为0==

2、使用移位运算使【奇变偶】【偶变奇】

  • 在我们获取到奇数位和偶数位之后,就完成了第一步。接着去我们就可以将去交换奇数位和偶数位了,但是直接做整体的交换太麻烦了,也很难做到。既然在上一步中分别保留了奇数位和偶数位,那不妨分别对他们进行操作。
  • 对于奇数位来说,要将他们整体变为偶数位,就需要一个整体左移的操作,我们可以使用移位运算符<<
  • 对于偶数位来说,要将他们整体变为奇数位,就需要一个整体右移的操作,我们可以使用移位运算符>>
  • [x] 移位运算的运算规则是==左移表示÷2,右移表示×2==

3、合并奇数位和偶数位

  • 进行移位操作之后,奇变偶偶变奇也就相当于做了一次交换的操作,但是它们两个是一个独立的个体,并不完整,因此我们要将他们做一个拼接,这里我们使用到的又是另一个位运算符【|】按位或
  • [x] 按位或的运算规则是==只要有1即为1,全0才位0==

⌨代码分析

1、代码展示

看完整体的思路之后,相信你对本题一定有了大致的方向,我们将上述的思路转化为代码
如果对宏定义不太清楚的可以看看这篇文章——> C生万物 | 详解程序环境和预处理

#define SWAP(n) num = (((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1))

int main(void)
{
    int num = 36;

    int ret = SWAP(num);

    printf("num = %d\n", num);
    return 0;
}
  • 首先的一点就是对于【宏】来说它和函数不一样是它不需要声明类型,也没有复杂的函数体,直接给出运算规则即可
  • 所以你可以看到,我写的这个宏就是我在上面所说的思路转化为的代码。不过很重要的一点是写宏的时候一定要加足括号,因为对于宏来说在预编译阶段就会直接进行替换,若是没有加括号的话可能会导致出现优先级的问题

来看看运行结果吧💻

在这里插入图片描述

2、算法图解分析

再通过画图来分析一下,就看得更清楚了
  • 首先就是第一步,分别取出奇数位和偶数位

在这里插入图片描述

  • 然后进行移位操作,使奇变偶偶变奇

在这里插入图片描述

  • 最后再将32为的奇偶分列进行一个合并

在这里插入图片描述
👉可以看到最后的结果就是我们程序的执行结果【24】

📰总结与提炼

总结一下本文所学习到的内容
  • 本篇文章虽然讲解的内容并不多,但是攻克了一道难题,虽然宏的代码看起来比较简洁,但是要想到还是需要一些时间的。如果我们在写程序的时候能够巧妙地运用宏去进行解决,就能事半而功倍
  • 特此分享思路,记录这一瞬间( •̀ ω •́ )y

在这里插入图片描述

相关文章
|
7月前
|
Java
链表中奇数位和偶数位的置换
链表中奇数位和偶数位的置换
|
2月前
|
Java 开发者
【编程基础知识】2的n次幂与二进制位全为1之间的联系,为啥只差一个1
本文深入探讨了2的n次幂与二进制位全为1之间的数学联系,解释了2的n次幂减一的二进制表示为何全为1,并探讨了这一特性在HashMap中的应用。通过基础数学原理和实际代码示例,文章揭示了这一特性的实用价值,适合各水平的编程爱好者学习。
26 3
|
C语言
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换(C语言)
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换(C语言)
70 0
|
6月前
|
C语言
【C语言刷题系列】交换整数的奇数位和偶数位
【C语言刷题系列】交换整数的奇数位和偶数位
|
7月前
62.编程求所有的三位素数,且要求该数是对称数
62.编程求所有的三位素数,且要求该数是对称数
49 0
|
7月前
用一行代码(宏)交换一个二进制整数的奇数位和偶数位
用一行代码(宏)交换一个二进制整数的奇数位和偶数位
C语言第三十二弹---打印整数二进制的奇数位和偶数位
C语言第三十二弹---打印整数二进制的奇数位和偶数位
wustojc求三位整数的逆序数
wustojc求三位整数的逆序数
59 0
C语音:打印整数二进制的奇数位和偶数位
总体思路: (一). 输入数据 (二). 打印奇数位: 使用 for循环 循环产生 1~32 之间的偶数, 使用 移位操作符 移动偶数位,移动后就是奇数位, 这时再 按位与1 取出当前位, 进行打印。打印完奇数后进行 换行
105 0
进制转换--(2-8)为什么2的3次方=8,所以三位变一位
进制转换--(2-8)为什么2的3次方=8,所以三位变一位