"C语言中的左移和右移"
C语言中的左移和右移是两个基本的位运算符,分别用 << 和 >> 表示。左移是指将一个数的所有位向左移动若干位,而右移是指将一个数的所有位向右移动若干位。
左移的规则是,将该数的所有位向左移动指定的位数,并在最右边补零。如果左移的位数超过该数值类型的最大位数,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位。例如,int i = 1; i = i << 2; 将 i 的值左移 2 位,也就是说,1 的 2 进制是 000...0001,左移 2 位之后变成 000...0100,也就是 10 进制的 4。左移 1 位相当于乘以 2,那么左移 n 位就是乘以 2 的 n 次方了。
需要注意的一个问题是 int 类型最左端的符号位和移位移出去的情况。我们知道,int 是有符号的整形数,最左端的 1 位是符号位,即 0 正 1 负,那么移位的时候就会出现溢出。例如,int i = 0x40000000; i = i << 1; 那么,i 在左移 1 位之后就会变成 0x80000000,也就是 2 进制的 100000...0000,符号位被置 1,其他位全是 0,变成了 int 类型所能表示的最小值,32 位的 int 这个值是-2147483648,溢出。如果再接着把 i 左移 1 位会出现什么情况呢?在 C 语言中采用了丢弃最高位的处理方法,丢弃了 1 之后,i 的值变成了 0。
右移的概念和左移相反,就是往右边挪动若干位,运算符是>>。右移对符号位的处理和左移不同,对于有符号整数来说,右移会保持符号位不变。例如,int i = 0x80000000; i = i >> 1; i 的值不会变成 0x40000000,而会变成 0xc0000000,就是说,符号位向右移动后,正数的话补 0,负数补 1,也就是汇编语言中的算术右移。
在 C 中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变。实际应用中可以根据情况用左/右移做快速的乘/除运算,这样会比循环效率高很多。
在实际应用中,我们需要注意左移和右移的规则,并且根据情况选择合适的位运算符号。例如,在unsigned char x = 3; 时,x << 1 是多少?x >> 1 是多少?答案是 x << 1 是 6,x >> 1 是 1。又例如,在char x = 3; 时,x << 1 是多少?x >> 1 是多少?答案是 x << 1 是 6,x >> 1 是 1。但是,我们需要注意,有符号数和无符号数的右移规则可能不同,而大多数的机器都是使用算术右移的。
C 语言中的左移和右移是两个基本的位运算符,分别用 << 和 >> 表示,左移是逻辑/算术左移,右移是算术右移,会保持符号位不变。在实际应用中,我们需要根据情况选择合适的位运算符号,并且注意左移和右移的规则,以免出现溢出和错误的结果。