【C深入】16_位运算符分析

注意按位运算符|和&与逻辑运算符||和&&完全是两码事,别混淆了。

结合律:a&b&c  <=> (a&b)&c <=>  a&(B&c)

交换律:a&b  <=>  b&a

 

左移和右移

左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,“<<”右边的数指定移动的位数,高位丢弃,低位补0 。 
右移运算符“>>”是双目运算符。其功能把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。但注意:对于有符号数,当为正数时, 最高位补0 ;而为负数时,符号位为1。
 

0x1<<2+3的值是多少?

不是7,是32,因为+优先级高于<<。

防错准则:

1.避免位运算符,逻辑运算符和数学运算符同时出现在一个表达式中

2.当位运算符,逻辑运算符和数学运算符需要同时参与运算时,尽量使用括号()来表达计算次序

0x01<<2+30;或0x01<<2-3; 
这样行吗?不行。一个整型数长度为32 位,左移32 位发生了什么事情?溢出!左移-1位呢?反过来移?所以,左移和右移的位数是有讲究的。左移和右移的位数不能大于数据 的长度,不能小于0 。

小技巧:

左移n位相当于乘以2的n次方,右移相当于除以2的n次方,效率比数学运算符高

3种交换两个变量程序分析

#define SWAP1(a,b) \
{                                    \
    int temp = a;           \
    a = b;                       \
    b = temp;                \
}                                       //最常规,但要借助第三个变量,如果资源设备受限则不好,但是适用于任何类型的数

#define SWAP2(a,b) \
{                                    \
    a = a + b;                 \
    b = a - b;                  \  //  b = a+b-b;  =>  b = a;
    a = a - b;                  \  //  a= a+b-a;  =>  a = b;
}                                       //  如果a,b较大,则a+b可能会产生溢出

#define SWAP3(a,b) \
{                                    \
    a = a ^ b;                 \
    b = a ^ b;                 \   //  =>  b = a^b^b;   =>   b = a^(b^b);   =>   b = a^0;   =>   b = a;
    a = a ^ b;                 \   //   =>  a = a^b^a;   =>   a = a^a^b;    =>   a = 0^b;   =>   a = b;
}                                        //不会溢出,效率高,适用于整型

 

面试题

有一个数列,其中的自然数都是以偶数的形式出现,只有一个自然数出现的次数为奇数次。编写程序找出这个自然数。


#include <stdio.h>

#define DIM(a) (sizeof(a)/sizeof(*a))

int main()
{
    int a[] = {2,3,5,7,2,2,2,5,3,7,1,1,1};
    int find = 0;
    int i = 0;  
    for(i=0;i<DIM(a);i++)
    {
		find = find ^ a[i];
    }   
    printf("find=%d\n",find);  
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zjy900507/article/details/80897577
今日推荐