关于逻辑移位、算术移位可参见迅雷深大笔试题部分。的一道题。以前看到C标准上说移位运算符、出界时的行为并不确定The behavior is undefined if the right operand is negative, orgreater than or equal to the length in bits of the promoted left operand.我当时也没有深究过这个问题。前几天有个网友来信问起这件事我才发现这和IntelCPU的移位运算有关。下面是那位网友的来信以及我的回复您好运算符作为位操作中的高效的操作但我遇到一个问题下面在VC环境下发现一个很不明白的地方下面标注。#include stdio.h1234567891011121314151617voidmain(){unsignedinti,j;i35;//为什么下面两个左移操作结果不一样j1i;// j为8j135;// j为0}不知是哪里没有理解对。原因是这样的i35;j1i;这两句在VC没有做优化的情况下将被编译成下面的机器指令mov dword ptr [i],23hmov eax,1mov ecx,dword ptr [i]shl eax,clmov dword ptr [j],eax在shl一句中eax1cl35。而IntelCPU执行shl指令时会先将cl与31进行and操作以限制左移的次数小于等于31。因为35 31 3所以这样的指令相当于将1左移3位结果是8。而j135;一句是常数运算VC即使不做优化编译器也会直接计算135的结果。VC编译器发现35大于31时就会直接将结果设置为0。这行代码编译产生的机器指令是mov dword ptr [j],0对上面这两种情况如果把VC编译器的优化开关打开比如编译成Release版本编译器都会直接将结果设置为0。所以在C/C语言中移位操作不要超过界限否则结果是不可预期的。http://hovertree.com/menu/cpp/下面是Intel文档中关于shl指令限制移位次数的说明The destination operand can be a register or a memory location.The count operand can be an immediate value or register CL. The count is maskedto 5 bits, which limits the count range to 0 to 31. A special opcode encodingis provided for a count of 1.1.掩码就是一串2进制 对目标字段进行位与运算屏蔽当前的输入位。将源码与掩码经过逻辑运算得出新的操作数。其中要用到逻辑运算如OR运算。AND运算。用于如将ASCLL码中大写字母改作小写字母。2.与 或 异或 转换成补码运算3. 用法掩码 4. 用法打开位 |5.用法关闭位 ~6. 用法转置位 ^7. 将Value的第bit_number位置1 Value | 1 bit_number;8. 将Value的第bit_number位置0 Value ~( 1 bit_number );9.value 1 bit_number 如果该位置已被置为1则表达式的结果为非零值C/C 提供位逻辑运算符和移位运算符。二者只能用于整形和字符型。位运算符是对每位进行操作而不影响左右两位这有别于常规运算符|| !是将整个数进行操作的。一 位逻辑运算符1 ~ 按位取反将1变为0将0变为1EG~(10011010)(01100101)注VC编译器计算10得出的结果是11。为什么不是5呢10的二进制表示为1010按位取反应该为0101也就是十进制的5为什么会得出11VC是32位编译器所以10 00000000 00000000 00000000 00001010~10 11111111 11111111 11111111 11110101 -11可以通过掩码位与 与15位与15 00000000 00000000 00000000 00001111~10 00000000 00000000 00000000 00000101 -112 按位取与只有两个操作数都是1结果才是1否则为010 00000000 00000000 00000000 0000101012 00000000 00000000 00000000 000011008 00000000 00000000 00000000 000010003 | 按位取或两个操作数任意一位为1结果就是110 00000000 00000000 00000000 0000101012 00000000 00000000 00000000 00001100|14 00000000 00000000 00000000 000011104 ^ 按位异或两个操作数不同为1相同为010 00000000 00000000 00000000 0000101012 00000000 00000000 00000000 00001100^14 00000000 00000000 00000000 000001105 用法掩码掩码是通过位与将某些位设置为开1将某些位设置为关0。将掩码0看做不透明将1看着透明。EG如只显示第二、三位107 0110 10116 0000 01102 0000 00106 用法打开位打开位是通过 |位或打开一个值的特定位同时保持其他位的不变。这是因为和0位或都为0和1位或都为1。EG如只打开第二、三位107 0110 10116 0000 0110|111 0110 11117 用法关闭位关闭某些位EG如关闭第二、三位107 0110 10116 0000 0110 ~105 0110 10018 用法转置位如果一位为1则转置为0如果一位为1则转置为0EG如转置第二、三位107 0110 10116 0000 0110^105 0110 1101二 移位运算符 左移左移运算符是把操作数的值的每一位向左移动移动的位数有右边的操作数决定右侧空出的位数用0填充EG如转置第二、三位107 0110 1011 2172 1010 1100在计算机中由于是32位的107 0000 0000 0000 0000 0000 0000 0110 1011 2428 0000 0000 0000 0000 0000 0001 1010 1100 右移右移运算符是把操作数的值的每一位向右移动移动的位数有右边的操作数决定左边丢弃的位数用0填充EG如转置第二、三位107 0110 1011 226 0001 1010一、传统的C方式位操作1.基本操作使用一个unsigned int变量来作为位容器。2.操作符| 按位或操作符resultexp1|exp2;当exp1和exp2中对应位中至少有一个为1时result中对应位为1否则为0。 按位与操作符resultexp1exp2;当exp1和exp2中对应位全为1时result中对应位为1否则为0。^ 按位异或或操作符resultexp1^exp2;当exp1和exp2中对应位不相同时result中对应位为1否则为0。~ 反转操作符将位容器中的所有位都反转1变为00变为1。 按位左移操作符expn将容器中所有的位向左移n位空出的位用0填充。 按位右移操作符expn将容器中所有的位向右移n位空出的位用0填充。|,,^ 分别对应|^三种操作符的复合操作符。3.常用操作这里我们假设有一个result的unsigned int变量用来储存32个学生的成绩通过和不通过分别用0和1这样result就有33位result从右至左从0开始计算位数在这个例子中0位被浪费。(a) 将第27位设置为及格设作1其他位不变result|(127) //任意的位值与1作按位或操作其值为1而与0作按位与操作其值不变(b) 将第27位设置成不及格设为0。result~(127) //任意的位值与0作按位与操作其值为0而与1作按位与操作其值不变(c) 反转第27位的值。result^(127) //任意的位值与1作按位异或操作其值为1而与0作按位异与操作其值不变二、C中的bitset容器1.头文件#include bitset2.声明一个容器(a)声明一个指定位数的空容器所有位设为0: bitsetint bits;(b)声明一个指定位数并将指定的几个位初始化为相应值的容器 bitsetn bits(int);bitdetint bits(string)总结bitset模板类中类型参数传递容器的位数而构造函数参数通过一个int或一个string值来从右至左初始化容器中的相应值。3.bitset的基本用法操作功能用法test(pos)pos位是否为1?a.test(4)any()任意位是否为1?a.any()none()是否没有位为1?a.none()count()值是1的位的小数count()size()位元素的个数size()[pos]访问pos位a[4]flip()翻转所有位a.flip()flip(pos)翻转pos位a.flip(4)set()将所有位置1a.set()set(pos)将pos位置1a.set(4)reset()将所有位置0a.reset()reset(pos)将pos位置0a.reset(4)4.bitset与传统C位操作及字符串的转换可以通过to_string()成员将容器转输出为一个string字符串另外还可以用to_long()成员将容器输出到传统的用于C风格的位容器中。如unsigned long bits bits.to_long();sting str(bits.to_string());以上这篇深入理解C移位运算符就是小编分享给大家的全部内容了