题目:将十六进制数12345678 转换为87654321并输出
通过两种方法进行解答
1.指针交换法
2.蝶式交换法
指针交换法:
#include <stdio.h>
#include <iostream>
using namespace std;
int main(){
int x = 0x12345678; //初始化十六进制数12345678
int a[10]; //用于保存交换相关的数据
char *p_char; //获取数据的指针
char *pex_char; //输出数据的指针
p_char = (char *)&x; //获取一字节数据 进行半字节交换
pex_char = (char *)&x;
//半字节交换
for (int i = 0; i < 4; i++){
a[i] = *p_char; //获取1字节数据,如0x78
a[i] = ((a[i] & 0x0f) << 4) | (a[i] >> 4);
//1.取后四位 左移四位
// 0x78 = 01111000, 0x78 & 0x0f --> 01111000 & 00001111 = 00001000
// 左移四位-->10000000(右边自动补0)
//2.因为左边四位为0000,所以右边直接右移四位
// 0x78 = 01111000, 右移四位 --> 00000111
//3.左右两边进行按位或运算 10000000 | 00000111 = 10000111 -->0x87
p_char++; //获取下1字节数据
//通过循环将 12345678 -> 21 43 65 87
}
//循环结束后 a[0]=0x21 a[1]=0x43 a[2]=0x65 a[3]=0x87
//将21 43 65 87 逆序输出 即 87 65 43 21,循环从高位开始。
for (int i = 3; i >= 0; i--){
*pex_char = a[i]; //通过指针修改x的值
*pex_char++; //指向下一位
}
printf("x = %#x\n", x);//按十六进制输出
return 0;
}
蝶式交换法
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
//设原始位为 1234 5678
int data = 0x12345678;
data = (data << 16) | (data >> 16);
//data<<16,数据左移16位,5678 0000;data>>16,数据右移16位,0000 1234;|按位或 ,之后位序为 5678 1234
data = ((data << 8) & 0xff00ff00) | ((data >> 8) & 0x00ff00ff);
//5678 1234 data<<8左移8位,7812 3400;&按位与ff00 ff00,得7800 3400;data>>8,
// 右移8位,0056 7812,位与00ff 00ff,得0056 0012;位或之后位序为 7856 3412
data = ((data << 4) & 0xf0f0f0f0) | ((data >> 4) & 0x0f0f0f0f);
//7856 3412左移4位8563 4120,位与f0f0 f0f0得8060 4020;右移4位 0785 6341,
// 位与0f0f 0f0f得0705 0301,;位或之后位序为 8765 4321
printf("data = %#x\n", data);
return 0;
}
小结:两种算法的核心都是半字节交换,其核心是相关的位操作(按位与、或,位移等等)