第06天C语言(04):位运算

一、概念
/*
 位运算 (和二进制相关)
 
 1.& 按位与
 规律 : 一假则假, 1真 0假
 规律 : 任何数和 1 相& 得到的结果还是那个数 
        1001 & 1111 = 1001

 2.| 按位或
 规律 : 一真则真

 3.^ 按位异或
 重点 : 异或的结果 和 参与运算的顺序没有关系
 规律1 : 不相同为1, 相同为0 (异或)
         1001 ^ 0101 = 1100
 规律2 : 相同的两个数 异或 等于0
        5 ^ 5 = 0101 ^ 0101 = 0
 规律3 : 任何数 和 0 异或上0 结果不变
        5 ^ 0 = 0101 ^ 0000 = 0101 = 5
 规律4 : 任何一个数 异或上 同一个数两次, 结果不变
        9 ^ 5 ^ 5 = ?  == 9 ^ 0 = 9
 ~ 取反
    计算机是以补码形式存在的
    1.先拿到数 的原码 [进行一个取反] 在 -1 变成反码 再将反码 转为原码
   一 . 9 原码 0000 0000 0000 0000 0000 0000 0000 1001
   二 . 取反的得到补码 -->
       1111 1111 1111 1111 1111 1111 1111 0110 的到的补码
   三 .  再将 补码 -1变成反码 -->
        1111 1111 1111 1111 1111 1111 1111 0101
   四 . 再将反码取反变回原码  --->
        1000 0000 0000 0000 0000 0000 0000 1010 == -10
  ~9 = -10
 
 
 原码 --> 反码(取反) -->(补码)+1
 补码 -->  反码(-1) --> 原码(取反)
 */
二、代码
#include <stdio.h>
int main()
{
#pragma 1.按位与
    /*
     9 & 5 = ?
     1001
    &0101
     ----
    0001
     
     规律 : 任何数和 1 相& 得到的结果还是那个数
     1001
    &1111
     -----
     1001
     */
    printf("1.按位与 %i\n",9 & 5);

#pragma 2.按位或
    /*

     9 | 5 = ?
     1001
   | 0101
     ----
     1101 == 13
     */
    printf("2.按位或 %i\n",9 | 5);

#pragma 3.按位异或
    /*
     规律 : 不相同为1, 相同为0 (异或)
     9 ^ 5 = ?
     
     1001
   ^ 0101
     ----
     1100 == 12
     
     重点 : 异或的结果 和 参与运算的顺序没有关系
     9 ^ 5 ^ 6 = ?
     
     1001
   ^ 0101
     ----
     1100
   ^ 0110
     ----
     1010  == 10
     
     5 ^ 6 ^ 9 = ?
     0101
     0110
     ----
     0011
     1001
     ----
     1010 == 10
     
     规律 : 相同的两个数 异或 等于0
     5 ^ 5 = ?
     6 ^ 6 = ?
     
     0101
     0101
     ----
     0000
     
     
     规律 : 任何数 和 0 异或上0 结果不变
     9 ^ 0 = ?
     
     1001 
     0000
     ----
     1001  == 9
     
     
     规律 : 任何一个数 异或上 同一个数两次, 结果不变
     9 ^ 5 ^ 5 = ?  == 9 ^ 0 = 9
        
     1001
   ^ 0101
     ----
     1100
  ^  0101
     ----
     1001 == 9
     
     
     */
//    printf("3.按位异或 %i\n",9 ^ 5);
    printf("3.按位异或 %i\n",9 ^ 5 ^ 6);
    printf("3.按位异或  同的两个数 异或 等于0 %i\n",5 ^ 5);
    printf("3.按位异或  任何数 和 0 异或上0 结果不变 %i\n",9 ^ 0);
    printf("3.按位异或  任何一个数 异或上 同一个数两次, 结果不变 %i\n",5 ^ 9 ^ 5);
#pragma 4.取反
    /*
     取反
     ~9 = ?
     
     0000 0000 0000 0000 0000 0000 0000 1001 // 原码
    ~1111 1111 1111 1111 1111 1111 1111 0110 // 补码
    -0000 0000 0000 0000 0000 0000 0000 0001 (补码转成反码要-1)
     ---------------------------------------
     1111 1111 1111 1111 1111 1111 1111 0101 // 反码
   转成原码(符号位不变,其他取反)
     1000 0000 0000 0000 0000 0000 0000 1010 // 原码
     
     原码 --> 反码(取反) -->(补码)+1
     补码 -->  反码(-1) --> 原码(取反)
     */
    printf("4.取反 %i\n",~11);

    return 0;
}

推荐阅读更多精彩内容