实习生面试题之一 C语言的位操作
2012-03-02 17:07 Hexor Chang 阅读(524) 评论(2) 编辑 收藏 举报题目要求:
将一个2个字节的无符号16位数字做反转, 要求写出这个函数
例如:
0xABCD 通过反转之后 输出的是 0xDCBA
0xA34C 通过反转之后 输出的是 0xC43A
以此类推...
思路:
ABCD 即 1010 1011 1100 1101 要实现A与D B与C的对换 即实现第1位与第13位, 第2位与第14位的调换……各位置以此类推
作为16位无符号短整型, 以上的调换共需要8次
10调换为01, 01调换为10, 00与11保持原状, 无需调换.
对需要调换的位进行的操作:
我们就需要判断这几种情况, 并分类进行处理.
- 11时: 假设 n = 11 那么 n | 11 = n 一定成立, 另外三种情况 10 01 00 都不成立.
- 00时: 假设 n = 00, 那么 n | 11 = n ^ 11 一定成立, 另外三种情况都不成立.
- 01与10时: 不论 n = 01 还是 n = 10, 通过 n ^ 11 的这个操作 都能使其完成调换.
- 即 if(不是11 且 不是00)
{执行调换操作 }
进行下一次位调换
对不需要调换的位进行的操作:
对于ABCD 即 1010 1011 1100 1101 当第1位与第13位进行操作时, 其他位就要保持不变
这里用到的有: 当任意数字与 0 做 或运算(|)时, 得到的结果不改变自身; 当任意数字与 0 做异或运算(^)时, 得到的结果也不改变
所以当我们对需要调换的位进行操作的时候, 其他的位保持0, 就可以做到保持不需要调换的位始终没有改变.
例如 ABCD 即 1010 1011 1100 1101 , 要做第2位与第14位进行调换 那么就与这个数字进行异或运算
0100 0000 0000 0100
可见第2位与第14位为1, 其他位都为0, 这样经过异或运算之后 就完成了ABCD 第2位与第14位的调换操作.
代码:
#include <stdio.h> int main(){ unsigned n = 0xABCD; unsigned a,b; if( ( a = n | 0x8008) != n && ( ( b = n ^ 0x8008) != a) ) { n = b; } if( ( a = n | 0x4004) != n && ( ( b = n ^ 0x4004) != a) ) { n = b; } if( ( a = n | 0x2002) != n && ( ( b = n ^ 0x2002) != a) ) { n = b; } if( ( a = n | 0x1001) != n && ( ( b = n ^ 0x1001) != a) ) { n = b; } if( ( a = n | 0x0880) != n && ( ( b = n ^ 0x0880) != a) ) { n = b; } if( ( a = n | 0x0440) != n && ( ( b = n ^ 0x0440) != a) ) { n = b; } if( ( a = n | 0x0220) != n && ( ( b = n ^ 0x0220) != a) ) { n = b; } if( ( a = n | 0x0110) != n && ( ( b = n ^ 0x0110) != a) ) { n = b; } printf("%x\n",n); return 0; }