实习生面试题之一 C语言的位操作

题目要求:

将一个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保持原状, 无需调换.

 

对需要调换的位进行的操作:

我们就需要判断这几种情况, 并分类进行处理.

  1. 11时: 假设 n = 11 那么 n | 11 = n 一定成立, 另外三种情况 10 01 00 都不成立.
  2. 00时: 假设 n = 00, 那么 n | 11 = n ^ 11 一定成立, 另外三种情况都不成立.
  3. 01与10时: 不论 n = 01 还是 n = 10, 通过 n ^ 11 的这个操作 都能使其完成调换.
  4. 即      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;


}

转载于:https://www.cnblogs.com/hexor/archive/2012/03/02/2377501.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值