操作符

表达式由操作数和操作符组成。操作数可以是变量、常量、或另一个表达式,操作符则指明对操作数的操作方式。依据所作用的操作数的个数,操作符可以分为3类:

一元操作符:作用于一个操作数的操作符。

二元操作符:作用于两个操作数的操作符。

三元操作符:作用于三个操作数的操作符,C#中仅有一个三元操作符,即条件操作符“?:”。

一个表达式可以包含多个操作符,此时表达式求值的顺序由操作符的优先级决定:先取优先级较高的操作符进行运算,当两个操作符优先级相同时,表达式将按照操作符出现的顺序以及操作符的结合性来决定求值的顺序。赋值操作符和条件操作符(?:)属于右结合的操作符,在操作符优先级相等的情况下,表达式按照从右向左的顺序进行运算;其他所有操作符均属于左结合的操作符,在操作符优先级相等的情况下,表达式按照从左向右的顺序进行运算。

下表按优先级从高到低的顺序列出了C#中的所有操作符,其中同一行中的操作符优先级相等。

算术表达式

C#中的算术表达式能够进行加、减、乘、除和取模5种数学运算。

算术运算需要注意的事项:

1.整数运算超出范围,超出部分作为负数处理;实数运算超出范围时,结果将会被设置为正无穷大或负无穷大。

2.当两种不同类型的操作数进行运算时,结果的类型与精度最高的操作数类型相同。

3.除以0的情况:任何数除以常数0都是不合法的,而除以值为0的变量则是合法的。对于整数类型,运行时执行到除以0的代码将会发生异常,而对于实数类型,除以0的结果始终是无穷大,符号则根据被除数和除数的符号来共同确定。C#中也有正0和负0之分,不过认为正0和负0是相等的。

4.用于枚举运算:加减操作符可以用于枚举运算,这时默认的操作是将枚举类型转换为整数类型,执行加减运算后在将结果转换为枚举类型。如果运算超出了枚举列出的成员范围,枚举变量仍有效,只不过是以整数形式来表现。

5.用于字符串运算:加法操作符用于字符串时,表示两个字符串首尾相连之后的结果。

6.用于委托的运算:C#中的加减法操作符可以作用于委托类型,这称为“委托的合并和删除”。

模运算:用来求两个数相除的余数。C#中的模运算不仅适用于整数类型,还适用实数类型。例如:5%3的结果为2,而5%1.5的结果为0.5。

模运算在数论中的一个典型例子是伪随机数的生成,.NET类库中的程序集System提供了一个随机数生成器类Random。

自增、自减表达式

所有的整数类型和实数类型,以及可以转换为这些类型的其他类型,都可以使用一元操作符“++”和“--”,运算的结果是对操作数的值加1或者减1。

当操作符位于操作数的前面,我们称其为“前缀操作符”,当操作符位于操作数的后面,我们称其为“后缀操作符”。前缀操作符和后缀操作符的区别在于:前者是“先增减,后使用”,后者是“先使用,后增减”。

注:不管是前缀操作符还是后缀操作符,操作数本身都会改变,但使用时的情况不同。

位运算表达式

位运算就是对数据按二进制位进行运算。C#中的位操作符有:~、&、|、^、<<、>>,分别代表对二进制位的取补、与、或、异或、左移和右移。位运算不会像算术运算那样发生溢出。

位运算的操作数要求是整数类型,或是能够转换为整数类型的其他类型:在运算过程中这些整数均被视为二进制整数,然后通过位操作符对各个二进制位进行运算。

赋值表达式

赋值表达式用于给变量赋予一个新值,赋值表达式有:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=.

赋值表达式可以分为两种:简单赋值和复合赋值。

复合赋值(x op= y)实际上等效于(x=x op y)

关系表达式

关系表达式用于对指定的条件进行判断,并以布尔值返回判断的结果是真(true)还是假(false)。C#中的关系操作符有:==、!=、<、>、<=、>=、is。其中,前6个又叫“比较操作符”,用于两个操作数的比较;而is操作符则用于在运行时动态地检查左操作数的类型是否与右操作数兼容。

比较运算:

“==”和“!=”对于值类型,两个操作数是否相等取决于两个数包含的值是否相等,对于float和double类型,还要考虑正负无穷大、正负0、以及非数值的情况。C#中认为正0和负0是相等的,对于非数字NaN,C#中认为不等于任何值。所以两个NaN值也是被认为互不相等的;而对于引用类型,默认情况下要使两个操作数相等,要么它们均为空值null,要么它们指向同一个对象。不过,很多引用类型在定义时可以重载相等和不等这两个操作符,此时两个对象是否相等就不一定取决于它们是否指向同一内存地址。典型的像字符串类型string,它规定两个字符串只要长度相等,并且各位字符对应相等,那么两个字符串也就相等。

类型判断:

类型判断表达式的书写格式为:e is T ,其中is操作符的左操作数e要求是一个变量或表达式,而右操作数T要求本身就是一个类型。不过对于值类型,使用类型判断表达式没有什么实际意义。

is操作符用于检查对象释放与给定的类型兼容。(即is是C#中用于类型兼容性判断的操作符,检查一个对象是否兼容于其他指定的类型, 如果一个对象是某个类型或是其父类型的话就返回为true,否则的话就会返回为false。)

is的规则如下:1.检查对象类型的兼容性,并返回结果,true或者false; 2.不会抛出异常;3. 对于值类型,使用类型判断表达式没有什么实际意义。例如x为int类型的变量,那么表达式x is int始终返回true;而将右操作数改为其他任何值类型(如x is short或x is long)则都将始终返回false。C#编译器会对这类代码给出警告;对于引用类型,如果e(对象)的值为null,则返回值永远为false。当e不为null时,只要e的类型为T,或者存在从e的类型到T的隐式引用转换,那么表达式将返回true,否则返回false。

条件逻辑表达式

条件逻辑表达式主要用于对多个条件进行组合判断。C#中提供了3种条件逻辑操作符,逻辑与,逻辑或和逻辑非:&&、||、!。条件逻辑操作符只能用于布尔类型的操作数,且返回值总是布尔类型。

注:逻辑表达式&&和位运算&;逻辑表达式||和位运算|的区别:

&&:当左侧表达式返回false时,就不在运算右侧表达式而直接返回false;

&:不管左侧表达式返回何值,均会运算右侧表达式

||:当左侧表达式返回TRUE时,就不在运算右侧表达式而直接返回TRUE;

|:不管左侧表达式返回何值,均会运算右侧表达式

三元条件操作符

C#中唯一的三元操作符是条件操作符“?:”。使用该操作符的表达式,功能上相当于只有两个选择条件的if-else控制语句。

表达式形如:b?x : y。其中第一个操作数b为一个布尔类型的表达式。条件表达式执行时,首先计算出b的值,如果为true,则计算表达式x的值并返回该结果;如果为false,则计算并返回表达式y的值。

条件表达式要求后两个操作数的类型兼容,结果类型则是x和y中最兼容的类型。即:

如果x和y的类型相同,那么该类型也是整个表达式的类型。

如果x的类型可以隐式转换为y的类型,则整个表达式的类型与y的类型相同。

如果y的类型可以隐式转换为x的类型,则整个表达式的类型与x的类型相同。

如果上述条件均不成立,那么表达式不合法,将发生编译时错误。

类型表达式

.NET类库的System程序集提供了一个名为Type的类,它对程序中的各个数据类型进行了抽象,具体的数据类型名称可由其属性Name得到。

C#中有3个与类型有关的表达式:

①一般类型转换。该表达式形如(T) e;其中T要求为某种数据类型,即为类Type的一个实例。

②as操作符。as操作符要求其左操作数是一个变量或表达式,而右操作数是Type类的一个实例。

as操作符强制要求左操作数必须为引用类型。as是C#中用于类型兼容性判断和类型转换的操作符,它同时进行类型的判断和类型的转换。

as的规则如下:一、检查对象类型的兼容性并进行转换,如果左右操作数类型兼容把左操作数转换为右操作数所代表的类型,并作为结果返回,如果不兼容就返回null; 二、不会抛出异常; 三、如果结果判断为空,则强制执行类型转换将抛出NullReferenceException异常。

as表达式:e  as  T等价于:e  is  T ? (T) e :  (T) null.

as操作符与is操作符比较

相同点:左操作数要求是一个变量或表达式,而右操作数是type类的一个实例。

不同点:as操作符强制要求左操作数为引用类型,而且表达式返回结果不同,如果左右操作数类型兼容,is运算返回布尔值true,而as运算将左操作数转换为右操作数所代表的类型;如果转换失败,is运算返回布尔值false,而as运算返回空值null。

③typeof操作符

从类型本身来得到类型原型,可以使用一元操作符typeof,其操作数和返回结果的类型均为Type类型。.NET对类型原型采用全名描述,“程序集名称.类型名称”;如果还存在嵌套类型,那么类型之间应使用加号连接。

 

posted @ 2014-07-29 21:38  百年一人  阅读(681)  评论(0编辑  收藏  举报