【C】16.位运算符分析

C语言中的位运算符

位运算符直接对 bit 位进行操作,其效率最高

左移和右移注意点

  1. 左操作数必需为整数类型
  2. 右操作数的范围必需为:【0,31】
  3. 左移运算符 << 将运算符的二进制位左移动
  4. 右移运算符 >> 把运算符的二进制位右移动
  • char 和short 被隐士转换为 int 后进行移位操作
  • 如果出现负数(-1)的情况编译厂家不同,结果不同
  • 规则:高位丢弃,低位补0
  • 规则:高位补符号位,低位丢弃

问题:

下面的运算结果是什么?

0x1 << 2 + 3 

实验:

#include <stdio.h>

int main()
{
    printf("%d\n", 3 << 2); 
    printf("%d\n", 3 >> 1); 
    printf("%d\n", -1 >> 1); 
    printf("%d\n", 0x01 << 2 + 3);
    
    printf("%d\n", 3 << -1); // oops!
    
    return 0;
}

输出

12
1
-1
32
1  // GCC编译器下认为左移-1 相当于右移1

运算优先级:四则运算>位运算>逻辑运算

移位为负数的情况下和不同编译器情况是不一样的(依赖编译器)

编程试验:交换两个整型变量的值

#define Swap1(a,  b)        \
{                           \
    int c = a;              \
    a = b;                  \
    b = c;                  \
}   


// 这个问题 a b 数据过大,会导致数据溢出
#define Swap2(a,  b)         \
{                            \
    a = a + b;               \
    b = a - b;               \
    a = a - b;               \
}  

#define Swap3(a,  b)        \
{                           \
    a = a ^ b;              \
    b = a ^ b;              \
    a = a ^ b;              \
}  

 

位运算与逻辑运算不同

  • 位运算没有短路原则,每个操作都参与运算
  • 位运算的结果为整数,而不是0和1
  • 位运算优先级高于逻辑运算
#include <stdio.h>

int main()
{
    int i = 0;
    int j = 0;
    int k = 0;
    
    // if( ++i || ++j && ++k )
    if( ++i | ++j & ++k )  
    {
        printf("Run here...\n");
    }
    
    printf("%d\n", i);
    printf("%d\n", j);
    printf("%d\n", k);
    
    return 0;
}

输出:

//Run here...
//1
//0
//0

Run here...
1
1
1

小结

  • 位运算只能用于整数类型
  • 左移或者右移的操作数范围必需是【0:32】
  • 位运算没有短路原则,所有操作数均会求值
  • 运算优先级:四则运算 > 位运算 > 逻辑运算
发布了84 篇原创文章 · 获赞 0 · 访问量 748

猜你喜欢

转载自blog.csdn.net/zhabin0607/article/details/103509433