網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
C生萬(wàn)物C語(yǔ)言宏將整數(shù)二進(jìn)制位的奇偶數(shù)位交換_C 語(yǔ)言
作者:Fire_Cloud_1 ? 更新時(shí)間: 2023-04-18 編程語(yǔ)言?題目分析 && 實(shí)現(xiàn)思路[位運(yùn)算]
首先來說一下本題的實(shí)現(xiàn)思路?
- 本題不僅是要使用宏來是實(shí)現(xiàn),而且還要對(duì)一個(gè)數(shù)的二進(jìn)制位進(jìn)行操作,所以我們就可以想到位運(yùn)算
1、獲取這個(gè)整數(shù)的奇數(shù)位和偶數(shù)位
- 因?yàn)樾枰粨Q的是這個(gè)整數(shù)二進(jìn)制位的【奇數(shù)位】和【偶數(shù)位】,因此我們要先獲取到它們,這里要使用到一個(gè)很巧妙的手法,可以將這個(gè)數(shù)的奇偶位分別保存下來,就要用到在十六進(jìn)制中很奇特的兩個(gè)數(shù)——>==5 和 a== ;因?yàn)?寫成二進(jìn)制的形式為
0101
,1均在奇數(shù)位上。a寫成二進(jìn)制的形式為1010
,1均在偶數(shù)位上 - 對(duì)于一個(gè)數(shù)來說可以分為32個(gè)比特位,所以我們就需要8個(gè)5和8個(gè)a,將它們展開后就是
0x555555550
、0xaaaaaaaa
;所以將這個(gè)整數(shù)與前者進(jìn)行【&】運(yùn)算便可以保留下它的奇數(shù)位;這個(gè)整數(shù)與后者進(jìn)行【&】運(yùn)算便可以保留下它的偶數(shù)位 - 按位與的運(yùn)算規(guī)則是==全1才為1,有0即為0==
2、使用移位運(yùn)算使【奇變偶】【偶變奇】
- 在我們獲取到奇數(shù)位和偶數(shù)位之后,就完成了第一步。接著去我們就可以將去交換奇數(shù)位和偶數(shù)位了,但是直接做整體的交換太麻煩了,也很難做到。既然在上一步中分別保留了奇數(shù)位和偶數(shù)位,那不妨分別對(duì)他們進(jìn)行操作。
- 對(duì)于奇數(shù)位來說,要將他們整體變?yōu)榕紨?shù)位,就需要一個(gè)整體左移的操作,我們可以使用移位運(yùn)算符
<<
- 對(duì)于偶數(shù)位來說,要將他們整體變?yōu)槠鏀?shù)位,就需要一個(gè)整體右移的操作,我們可以使用移位運(yùn)算符
>>
- 移位運(yùn)算的運(yùn)算規(guī)則是==左移表示÷2,右移表示×2==
3、合并奇數(shù)位和偶數(shù)位
- 進(jìn)行移位操作之后,奇變偶、偶變奇也就相當(dāng)于做了一次交換的操作,但是它們兩個(gè)是一個(gè)獨(dú)立的個(gè)體,并不完整,因此我們要將他們做一個(gè)拼接,這里我們使用到的又是另一個(gè)位運(yùn)算符【|】按位或
- 按位或的運(yùn)算規(guī)則是==只要有1即為1,全0才位0==
?代碼分析
1、代碼展示
看完整體的思路之后,相信你對(duì)本題一定有了大致的方向,我們將上述的思路轉(zhuǎn)化為代碼 如果對(duì)宏定義不太清楚的可以看看這篇文章——> C生萬(wàn)物 | 詳解程序環(huán)境和預(yù)處理
#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; }
- 首先的一點(diǎn)就是對(duì)于【宏】來說它和函數(shù)不一樣是它不需要聲明類型,也沒有復(fù)雜的函數(shù)體,直接給出運(yùn)算規(guī)則即可
- 所以你可以看到,我寫的這個(gè)宏就是我在上面所說的思路轉(zhuǎn)化為的代碼。不過很重要的一點(diǎn)是寫宏的時(shí)候一定要加足括號(hào),因?yàn)閷?duì)于宏來說在預(yù)編譯階段就會(huì)直接進(jìn)行替換,若是沒有加括號(hào)的話可能會(huì)導(dǎo)致出現(xiàn)優(yōu)先級(jí)的問題
來看看運(yùn)行結(jié)果吧?
2、算法圖解分析
再通過畫圖來分析一下,就看得更清楚了
首先就是第一步,分別取出奇數(shù)位和偶數(shù)位
- 然后進(jìn)行移位操作,使
奇變偶
、偶變奇
- 最后再將32為的奇偶分列進(jìn)行一個(gè)合并
?可以看到最后的結(jié)果就是我們程序的執(zhí)行結(jié)果【24】
?總結(jié)與提煉
總結(jié)一下本文所學(xué)習(xí)到的內(nèi)容
本篇文章雖然講解的內(nèi)容并不多,但是攻克了一道難題,雖然宏的代碼看起來比較簡(jiǎn)潔,但是要想到還是需要一些時(shí)間的。如果我們?cè)趯懗绦虻臅r(shí)候能夠巧妙地運(yùn)用宏去進(jìn)行解決,就能事半而功倍
原文鏈接:https://juejin.cn/post/7197790401494597689
相關(guān)推薦
- 2022-09-05 Hbase之查看RowKey所在Region
- 2022-05-15 Python使用chrome配置selenium操作詳解_python
- 2022-09-07 C語(yǔ)言函數(shù)調(diào)用約定和返回值詳情_C 語(yǔ)言
- 2022-03-21 C++二維數(shù)組螺旋加密信息_C 語(yǔ)言
- 2022-05-09 C#特性(Attribute)_C#教程
- 2022-08-04 Python?venv虛擬環(huán)境跨設(shè)備遷移的實(shí)現(xiàn)_python
- 2023-08-16 uniapp插件uni-combox實(shí)現(xiàn)失去焦點(diǎn)驗(yàn)證數(shù)據(jù)是否存在
- 2022-08-04 pandas添加新列的5種常見方法_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支