移位运算符
计算机中任何数据都是以二进制来保存的。二进制和十进制一样都是一种数值的表示方式。十进制数由印度人发明,每一位可以表示十个数字,是我们日常使用的数制。比如十进制数值1011就是指一千零一十一,它是这样计算出来的:右边第1位乘以10的0次方,加上右边第2位乘以10的1次方,再加上右边第3位乘以10的2次方,再加上右边第4位乘以10的3次方:
1X100+1X101+0×102+1X103=1011
二进制的每一位可以表示0和1两个数,比如二进制的1011就是十进制的11。二进制的计算原理和十进制相同,对于二进制的1011是这样计算出来的:右边第1位乘以2的0次方,加上右边第2位乘以2的1次方,加上右边第3位乘以2的2次方,加上右边第4位乘以2的3次方:
1X20+1×21+0×22+1X23=11
也就是说二进制1011实际上就相当于十进制的11,这就是二进制。因为计算机的存储单元是电子管,每一个电子管分有电和无电两种状态,所以只能存储两个数,所以计算机内的数据存储都是以二进 制进行的。任何数据,不管是整型还是浮点型实际上最终都会转变成二进制来保存。移位运算就是指二进制的移位,比如1011左移一位就是10110,右移一位就是0101,移位运算要求移进的空位要补零,移出的数位要丢掉。移位运算是相对底层的运算,直接操作内存,实际上对于C#这种面向组件面向对象的语言来说很少用到。C#中的移位运算只能用于整数型的数据,移位运算符主要用来完成移位运算,移位运算符主要有左移和右移两种,如表:
运算符 , 作用 , 示例 , 运算符 , 作用 , 示例
<< ,左移 , 4<<2结果是16 ,>>,右移 ,4>>2结果是1
在移位之前你最好先把要移位的十进制整数换算成与此相当的二进制数再计算。当然也有个简单的方法,那就是:x向左移动n位相当于x乘以2的n次方,向右移动n位相当于x除以2的n次方,
如,下面示例:
using System;
namespace MyTest
{
class Test
{
[STAThread]
static void Main(string[] args)
{
int n=1000>>2;
Console.WriteLine("n={0}",n);
int r=n<<2;
Console.WriteLine("r={0},n={1}",r,n);
}
}
}
运行结果:
n=250
r=1000,n=250
要注意一点,如果向右移位超出最低位,那么超出的就被“砍”掉,如2>>3为零。如果向左移超出该类型的范围(以整型为例),则所移位数由第二个操作数的低5位给出,如1<<33,33二进制为100001,后五位为1,所以相当于移了一位,结果为2。
运算符的优先级
现在,你几乎已经了解所有的运算符,是你大显身手的时候了,那么你能计算下面的式子吗:
r=(2-1)×3+!2 - 5 % 2 * 2 && 3;
你如果没有接触过其他程序语言,相信你应该懵了,这么多运算符应该先算哪个呢?我们在学小学数学时就知道运算符有优先级,我们知道乘法和除法的优先级高于加减运算,而括号的优先级最高,一 个式子如果既有加减又有乘除,还有括号,那么计算的顺序的是:括号里面的→乘除→加减,如“3*4+2/(5+2+1)”式子,结是“12.25”。我们知道C#中的运算符远比数学中的运算符多,而且这些运 算符都可以出现在同一个表达式中,那么它们的优先级是怎样的呢?
C#中运算符优先级从高到低排列如下表所示:
运算符号 结合性 描述 运算符号 结合性 描述
() ,从左到右 ,括号优先级最高 ,=、!=,从左到右,等于、不等于
++、--、!,从右到左,递增、递减、逻辑非运算符,&& , 从左到右 ,逻辑与
*、/、%,从左到右,乘、除、取模操作,||,从左到右,,逻辑或
+、-,从左到右,加、减运算,=、+=、*=、/=、%=、-=,从右到左,赋值运算符和复合赋值运算符
<、<=、>、>=,从左到右,小于、小于等于、大于、大于等于
运算符的结合性是指同时出现多个该运算符号时的计算方向。比如优先级最高的括号,如果在一个表达式中出现多个括号,那么将从左向右依次计算这些括号里面的内容。再比如大于、小于号,如果几个大于、小于号连在一起,那么是从左往右进行计算的。通常,能接两个操作数的运算符称作二元运算符,比如“+”号,接一个操作数的我们称为一元运算符,比如“!”、“++”号等。从上面的优先级例子可以看出,除了括号外,一元运算符优先级最高。除此之外,从大的范围来讲算术运算符优先级高于关系运算符,关系运算符优先级高于逻辑运算符,优先级最低的是赋值运算符。