• C语言 位运算


    1G=1024M;

    1M=102KB;

    1KB=1024B(字节);

    1B=8bits(位);

    #include<stdio.h>
    #include<stdlib.h>
    
    //C语言中的逻辑运算符
    //逻辑与(&&);逻辑或(||);逻辑非(!)。
    
    //强调逻辑运算符与位逻辑运算符不同
    
    //C语言中的位运算符有以下两类:
    //位逻辑运算符:&(位“与”)、^(位“异或”)、 | (位“或”)、~(位“取反”)。
    //移位运算符: << (左移)、 >> (右移)
    void main(){
        //一:取反运算(~)
        unsigned char ch1 = 165;
        //一个字符有8位,ch1换算成二进制是 1010 0101
        //位取反的操作符为“~”,
        //即每位都取反,0变成1,1变成0,需要注意的是,位取反运算并不改变操作数的值。
        //那么~ch1=0101 1010,换算成十进制是90
        unsigned char ch2 = ~ch1;
        //printf("
    %d", ~ch1);//  打印  -166  错误  解释: ~ch1是取反运算,值会存储在cpu的寄存器中,所以printf函数不确定~ch1的类型
        printf("
    取反运算%d", (unsigned char)~ch1);//  打印  90  正确
        printf("
    取反运算%d",ch2);//  打印  90  正确
    
        //二:与运算(&)----清零
        //位与运算的操作符为&,将对两个操作数的每一位
        //进行与运算,位“与”运算的准则如下:(两者都为1的时候才是1,有一个为0就是0)
        //1 & 1 = 1     1 & 0 = 0     0 & 1 = 0     0 & 0 = 0
        unsigned char ch3 = 15;
        //ch1        1010 0101
        //ch3        0000 1111
        //ch1&ch3    0000 0101   十进制是5
        unsigned char ch4 = ch1&ch3;
        printf("
    与运算%d", ch4);//  打印  5  正确
        //对于ch1&ch3的分析,发现与运算可以用来"保持一部分位不变(不变用1),部分为全部为0(变0用0)"
    
        //三:或运算(|)---置1
        //位或运算的操作符为|,将对两个操作数的每一位进行或运算,位“或”运算的准则如下:(两者有一个是1就是1,两者都为0才是0)
        //1 | 1 = 1      1 | 0 = 1      0 | 1 = 1      0 | 0 = 0
        //例子
        //ch1        1010 0101
        //ch3        0000 1111
        //ch1|ch3    1010 1111   十进制是175
        unsigned char ch5 = ch1|ch3;
        printf("
    或运算%d", ch5);//  打印  175  正确
        //对于ch1|ch3的分析,发现与运算可以用来"保持一部分位不变(不变用0),部分为全部为1(变1用1)"
    
        //四:异或运算(^)---取反
        //位或运算的操作符为^,将对两个操作数的每一位进行异或运算。
        //通俗地讲,如果位“异或”运算的两个位相同(同为0或同为1),结果为0,
        //若两个位不同(一个为0,另一个为1),结果为1,对应的准则为:(两者相同结果是0,两者不同结果是1)
        //1 ^ 1 = 0  1 ^ 0 = 1  0 ^ 1 = 1  0 ^ 0 = 0
        //例子
        //ch1        1010 0101
        //ch3        0000 1111
        //ch1^ch3    1010 1010  十进制170
        unsigned char ch6 = ch1^ch3;
        printf("
    异或运算%d", ch6);//  打印  170  正确
        //对于ch1^ch3的分析,发现与运算可以用来"保持一部分位不变(不变用0),部分取反(取反用1)"
    
        //五:左移运算(<<)
        //A称为操作数,其必须为数字型变量或数字型常量,
        //此处的数字型包括整型、浮点型和char型,A中存储的0、1序列向左或右移动n位,
        //移动后的值作为整个表达式的输出,执行移位运算并不改变操作数A的值。
        unsigned char ch7 = 1;
        //例子
        //ch7        0000 0001    十进制是1
        //ch7<<1     0000 0010    十进制是2  (1*2)
        //ch7<<2     0000 0100    十进制是4   (2*2)
        unsigned char ch8 = ch7<<1;
        unsigned char ch9 = ch7<<2;
        printf("
    左移运算ch7<<1=%d", ch8);//  打印  2  正确
        printf("
    左移运算ch7<<2=%d", ch9);//  打印  4  正确
        unsigned char cha = 128;
        //例子
        //cha        1000 0000    十进制是128
        //cha<<1     0000 0000    十进制是0  
        unsigned char chb = cha << 1;
        printf("
    左移运算cha<<1=%d", chb);//  打印  0  正确
    
        //六:右移运算(>>)
        unsigned char chc = 255;
        //例子
        //chc        1111 1111    十进制是255
        //chc>>1     0111 1111    十进制是127  (255/2)
        //chc>>2     0011 1111    十进制是63    (127/2)
        unsigned char chd = chc >> 1;
        unsigned char che = chc >> 2;
        printf("
    右移运算chc >> 1=%d", chd);//  打印  127  正确
        printf("
    右移运算chc >> 2=%d", che);//  打印  63  正确
    
    
        //练习
        // 1010 0101十进制是165
        //练习1:前四位不变,后四位清零
        //分析:清零操作使用与运算符;前四位不变1111,后四位清零0000,二进制是1111 0000---十进制是240
        unsigned char chf = 240;
        unsigned char chg = ch1&chf;
        //ch1        1010 0101    十进制是165
        //chf        1111 0000    十进制是240  
        //ch1&chf    1010 0000    十进制是160
        printf("
    前四位不变,后四位清零%d", chg);//  打印  160  正确
    
        //练习2:前四位不变,后四位置1
        //分析:置1使用或运算符,前四位不变--0000,后四位置1--1111,二进制是 0000 1111---十进制是15
        unsigned char chh = 15;
        unsigned char chi = ch1 | chh;
        //ch1        1010 0101    十进制是165
        //chh        0000 1111    十进制是15  
        //ch1|chf    1010 1111    十进制是175
        printf("
    前四位不变,后四位置1--%d", chi);//  打印  175  正确
    
        //练习3:前四位不变,后四位取反
        //分析:取反有2中方法,取反运算符和异或运算符,取反运算符只能全部取反,异或运算符可以部分取反
        //前四位不变,说明只能使用异或运算符;前四位不变0000;后四位取反1111,二进制是 0000 1111---十进制是15
        //注:异或相同为0,不同为1,两个0的值仍然是0,两个1的值是0,一个0和一个1结果是1
        unsigned char chj = ch1^chh;
        //ch1        1010 0101    十进制是165
        //chh        0000 1111    十进制是15  
        //ch1|chf    1010 1010    十进制是170
        printf("
    前四位不变,后四位取反--%d", chj);//  打印  170  正确
    
        system("pause");
    }

         

               在C语言的位运算中,左移也就是所说的逻辑移位,右端补0,而右移是算数移位,左端补齐的是最高位的符号位。因此负数左移,有可能变成正数
    ,但负数右移,肯定还是负数。

     特别注意,这是运算的变量是有符号类型的情况,如果是无符号类型,就算最高位是1,那么左移填充的符号位依然是0。

    位运算注意点
        在进行位运算时,要求所有参与运算变量必须是 unsigned char类型,这是因为正数和负数在内存中都是以补码方式存储
    如果使用char,这是有符号的类型,那么如果这个char小于0,那么在内存中的存储就会变化,当出现拷贝操作时,就会改变原数据
    如果使用unsigned char,所有的数据都是正数(正数的原码,补码一致),拷贝时,系统就不会修改原数据了
  • 相关阅读:
    MySQL查询所有库中表名
    MySQL统计数据库表大小
    Spring Cloud 自定义ConfigServer 解决敏感信息存储问题
    JQuery Ajax执行过程AOP拦截
    虚拟机下的centos断电(非正常关机)后mysql启动不了
    Ubuntu 13.10 如何修改背景色--豆沙绿
    CI框架CodeIgniter伪静态各种服务器设置
    MongoDB中MapReduce不同的写法,不同的结果
    分享个人预算系统源码(含说明文档)
    Java lambda 分组后多列求和
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5140189.html
Copyright © 2020-2023  润新知