C语言位运算符

C语言位运算符包括:

                              & 按位与    |  按位或     ~按位取反   ^ 按位异或     >> 左移   << 右移

位运算符是c语言一部分,而且这部分没有什么难度,但是仔细琢磨还是有点东西要注意的

一、首先对位运算符做些总结:

      1、位运算符只能对整形数据(包括字符型数据),不能对浮点数类型操作

      2、左移右移运算符右边操作数范围只能是[0,31]

              (1) 左操作数必须是整数类型 char和short被隐试转换成int后在操作

              (2)右操作数的范围[0,31]

              (3)左移运算符规则:高位去掉   低位补0

              (4)右移运算符规则:高位补符号位   低位去掉

              (5)左移运算符相当于乘以2的N次方,效率要比四则运算符效率高

              (6)右移运算符相当于除以2的N次方,效率要比四则运算符效率高

     3、位运算符没有短路规则(逻辑运算符有这种规则),所有操作数都会有值

     4、位运算符的效率高于四则运算符和逻辑运算符

     5、位运算符优先级:四则运算符 < 位运算符 < 逻辑运算符

二、说下几个运算符需要注意的地方:

   1、应该避免位运算符、逻辑运算符、四则运算符同时出现在一个表达式中,如果非得出现尽量使用()划分开来,表达运算顺序

   2、位运算符结果是整数而不是0或者1,逻辑运算符结果是0或者1

   3、位运算符优先级 > 逻辑运算符

三、下面我开始写2个程序测试上面结论 (平台Ubuntu10 gcc编译器)

#include <stdio.h>

int main(void)
{
   unsigned char i = 0x01; 
   unsigned int j = 0x80000000;
   unsigned int k = 1;
   unsigned int m = 3;
   //printf("%d\n",3.14&0x01);       //error 因为位操作符只能对整形数操作(char和short自动转换int)
   //printf("%d\n",3.14<<1);         //error 同上
   printf("%d,0x%.8x\n",sizeof(1),1);//4和0x00000001  说明字面量默认数据类型是int
   printf("%d\n",k << 2);          //1*2^2 = 4
   printf("%d\n",1 << 2);          //1*2^2 = 4
   
   printf("%d\n",k << 33);         //1<<2^(33%32) = 1*2^1=2
   printf("%d\n",1 << 33);         //0
   //通过上面测试,我们发现字面量和定义一个相同数,gcc编译器处理方式不一样
   //定义一个数时,进行左移或者右移时,当超过移除位数时,定义的数会进行对最大位数取模处理,然后再进行移位
   //而字面量数据时,当超过移除位数时,就是0 其中包括带符号数据
   printf("%d\n",k << 255);        //1<<2^(255%32) = 1*2^31=0x80000000 = -2^31
   printf("%d\n",1 << 255);        //0 超过移除位数
   
   printf("%d\n",m >> 1);          //3/2^1 = 1或者 0011 >> 1 = 0001 = 1
   printf("%d\n",3 >> 1);          //3/2^1 = 1或者 0011 >> 1 = 0001 = 1
   
   printf("%d\n",m >> 33);         //3/2^(33%32) = 1
   printf("%d\n",3 >> 33);         //0  超过移除位数
   
   printf("%d\n",m >> 255);        //3/2^(255%32) = 0
   printf("%d\n",3 >> 255);        //0  超过移除位数
   
   printf("%d\n",0x80000000>>33);  //0  带符号位数据,同样超过移除位数时,也还是 0
   printf("%d\n",0x80000000>>255); //0  带符号位数据,同样超过移除位数时,也还是 0
   
   printf("%d\n",-1 >> 1);         //-1 内存值 = FFFF FFFF >> 1 = FFFF FFFF = -1   
   printf("%d\n", 0x01 << 2 + 3);  //+号运算符优先级高于<<所以  0x01 << (2 + 3) = 32
    
   printf("%d\n", 3 << -1);        //1 不同编译器,结果不同,gcc = 1,BCC = 0 vs = 很大一个负数(int的最小数)                      
}
#include <stdio.h>

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

通过上面测试,位运算是没有短路规则,而且位运算算出来是一个整数,而不是像逻辑运算符是有短路规则,结果是0或者1

猜你喜欢

转载自blog.csdn.net/liuchunjie11/article/details/79997348
今日推荐