2.4 编写表达式

  在了解了C#中的数据类型、变量的声明和初始化方式、以及类型转换等基本知识,就需要了解如何进行表达式的编写。表达式在C#应用程序开发中非常的重要,本节将说明如何使用运算符创建和使用表达式。

2.4.1 表达式和运算符
  表达式和运算符是应用程序开发中最基本也是最重要的一个部分,表达式和运算符组成一个基本语句,语句和语句之间组成函数或变量,这些函数或变量通过某种组合形成类。
1.定义
  表达式是运算符和操作符的序列。运算符是个简明的符号,包括实际中的加减乘除,它告诉编译器在语句中实际发生的操作,而操作数既操作执行的对象。运算符和操作数组成完整的表达式。

2.运算符类型
  在大部分情况下,对运算符类型的分类都是根据运算符所使用的操作数的个数来分类的,一般可以分为三类,这三类分别如下所示。
? 一元运算符:只使用一个操作数,如(!),自增运算符(++)等等,如i++。
? 二元运算符:使用两个操作数,如最常用的加减法,i+j。
? 三元运算符:三元运算符只有(?:)一个。
  除了按操作数个数来分以外,运算符还可以按照操作数执行的操作类型来分,如下所示。
? 关系运算符。
? 逻辑运算符。
? 算术运算符。
? 位运算符。
? 赋值运算符。
? 条件运算符。
? 类型信息运算符。
? 内存访问运算符。
? 其他运算符。
  在应用程序开发中,运算符是最基本也是最常用的,它表示着一个表达式是如何进行运算的。常用的运算符如表2-6所示。

表2-6 常用的运算符
运算符类型 运算符
元运算符      (x),x.y,f(x),a[x],x++,x--,new,typeof,sizeof,checked,uncheck
一元运算符     +,-,~!,++x,--x,(T)x,
算术运算符     +,-,*,/,%
位运算符      <<,>>,&,|,^,~
关系运算符     <,>,<=,>=,is,as
逻辑运算符     &,|,^
条件运算符     &&,||,?
赋值运算符     =,+=,-=,*=,/=,<<=,>>=,&=,^=,|=
  正如表2-5中所示,C#编程中所需要使用到的运算符都能够通过相应的类别进行相应的分类,但其分类的标准并不是唯一的。

3.算术运算符
  程序开发中常常需要使用算术运算符,算术运算符用于创建和执行数学表达式,以实现加、减、乘、除等基本操作,示例代码如下所示。
+展开
-C#
            int a = 1;//声明整型变量
            int b = 2;//声明整型变量
            int c = a + b;//使用+运算符
            int d = 1 + 2;//使用+运算符
            int e = 1 + a;//使用+运算符
            int f = b - a;//使用-运算符
            int f = b / a;//使用/运算符

  注意:当除数为0,系统会抛出DivideByZeroException异常,在程序开发中应该避免出现逻辑错误,因为编译器不会检查逻辑错误,只有在运行中才会提示相应的逻辑错误并抛出异常。
在算术运算符中,运算符“%”代表求余数,示例代码如下所示。
+展开
-C#
            int a = 10;//声明整型变量
            int b = 3;//声明整型变量
            Console.WriteLine((a%b).ToString());//求10除以3

  上述代码实现了“求10除以3”的功能,其运行结果为1。在C#的运算符中还包括自增和自减运算符,如“++”和“--”运算符。++和--运算符是一个单操作运算符,将目的操作数自增或自减1。该运算符可以放置在变量的前面和变量的后面,都不会有任何的语法错误,但是放置的位置不同,实现的功能也不同,示例代码如下所示。
+展开
-C#
            int a = 10;//声明整型变量
            int a2 = 10;//声明整型变量
            int b = a++;//执行自增运算
            int c = ++a2; //执行自增运算
            Console.WriteLine("a is " + a);//输出a的值
            Console.WriteLine("b is " + b);//输出b的值
            Console.WriteLine("c is " + c);//输出c的值

运行结果如图2-14所示。

++运算符


图2-14 ++运算符
  由运行结果所示,变量a、a2为10,在使用了++运算符后,a和a2分别变为了11,而b的赋值语句代码中使用的为后置自增运算符,示例代码如下所示。
+展开
-C#
int b = a++;//b=10

  当执行了上述代码后,b的值为10,而a会自增为11,因为上述代码首先会将变量a的值赋值给b变量,赋值后再进行自增。而c的赋值语句中使用的为前置自增运算符,示例代码如下所示。
+展开
-C#
int c = ++a2; //c=11

  当执行了上述代码后,变量c的值为11,是因为在执行自增操作时,首先进行自增,再将a2变量的值赋值给c。当运算符在操作数后时,操作数会赋值给新的变量,然后再自增1,当运算符在操作数前时,操作数会先进行自增或自减,然后再赋值给新变量。

4.关系运算符
  关系运算符用于创建一个表达式,该表达式用来比较两个对象并返回布尔值。示例代码如下所示。
+展开
-C#
string a="nihao";//声明字符串变量a
            string b="nihao";//声明字符串变量b
            if (a == b) //使用比较运算符
            {
                Console.WriteLine("相等");//输出比较相等信息
            }
            else
            {
                Console.WriteLine("不相等");//输出比较不相等信息
            }

关系运算符如“>”,“<”,“>=”,“<=”等同样是比较两个对象并返回布尔值,示例代码如下所示。
+展开
-C#
string a="nihao";//声明字符串变量a
            string b="nihao";//声明字符串变量b
            if (a == b)//比较字符串,返回布尔值
            {
                Console.WriteLine((a == b).ToString()); //输入比较后的布尔值
            }
            else
            {
                Console.WriteLine((a == b).ToString()); //输入比较后的布尔值
            }

  编译并运行上述程序后,其输出为true。若条件不成立,即如a不等于b的变量值,则返回false。该条件所以可以直接编写在if语句中进行条件筛选和判断。

  技巧:在使用判断的时候,可以直接使用表达式,只要表达式的返回值是布尔型的即可,同样也可以使用类型转换Convert.ToBoolean方法转换。

  初学者很容易错误的使用关系运算符中的“==”号,因为初学者通常会将等于运算符编写为“=”号,示例代码如下所示。
+展开
-C#
if (a = b)//使用布尔值布尔值

  在这里,“=”号不等于“==”号,“=”号的意义是给一个变量赋值,而“==”号是比较两个变量的值是否相等,如果写成上述代码,虽然编译器不会报错,但是其运行过程就不是开发人员想象的流程。

5.逻辑运算符
  逻辑运算符和布尔类型组成逻辑表达式。NOT运算符“!”使用单个操作数,用于转换布尔值,即取非,示例代码如下所示。
+展开
-C#
bool myBool = true;//创建布尔变量
            bool notTrue = !myBool;//使用逻辑运算符

  与其他编程语言相似的是,C#也使用AND运算符“&&”。该运算符使用两个操作数做与运算,当有一个操作数的布尔值为false时,则返回false,示例代码如下所示。
+展开
-C#
bool myBool = true;//创建布尔变量
            bool notTrue = !myBool;//使用逻辑运算符取反
            bool result = myBool && notTrue;//使用逻辑运算符计算

  同样,C#中也使用“||”运算符来执行OR运算,当有一个操作数的布尔值为true时,则返回true。当使用“&&”运算符和“||”运算符时,他们是短路(short-circuit)的,这也就是说,当一个布尔值能够由前一个或前几个操作数决定结果,那么就不取使用剩下的操作数继续运算而直接返回结果,示例代码如下所示。
+展开
-C#
bool myBool = true;//创建布尔变量
            bool notTrue = !myBool;//使用逻辑运算符取反
            bool result = myBool && notTrue;//使用逻辑运算符计算
            bool other = true;//创建布尔变量
            if (result&&other)//短路操作
            {
                Console.WriteLine("true");//输出布尔值
            }
            else
            {
                Console.WriteLine("false");//输出布尔值
            }

  从上述代码可以看到,变量other的值为true,而result的值为false,那么result&&other语句中,会直接返回false,说明条件失败。另外,在逻辑运算符中还包括XOR异或运算符“^”,该运算符确定是否操作数是否相同,若操作数的布尔值相同,则表达式将返回false。

  在C#应用程序开发中,并不支持从整型直接转换为布尔值,虽然在C/C++中能够直接编写数值进行逻辑判断,示例代码如下所示。
+展开
-C#
int result = 1;//使用整型
            if (result)//c++的转换
            {
                cout<<"true";
            }
            else
            {
                cout<<"false";
            }

  而上述代码如果在C#中运行,编译器会报错,说明C#并不支持显式的直接从int类型到bool类型的转换,但是使用Convert对象的静态方法可以实现同样的效果,代码如下所示。
+展开
-C#
int result = 1;
            if (Convert.ToBoolean(result))//使用Convert静态对象
            {
                Console.WriteLine("true");//输出布尔值
            }
            else
            {
                Console.WriteLine("false");//输出布尔值
            }

  注意:在编程语言中,非0的数值都为true,虽然C#不支持隐式的转换int到bool类型,但是Convert.ToBoolean静态方法提供了实现,任何非0的参数都将返回true。

6.位运算符
  位运算符通常使用为模式来操作整数类型,这些位运算符非常实用。位运算符包括“<<”、“>>”、AND、OR和XOR。左移位运算符“<<”将整型中的位左移指定位数,每一次左移,整型变量的值将乘以2,代码如下所示。
+展开
-C#
int result = 4;
            Console.WriteLine((result << 1).ToString());//左移并输出

运行结果为8,操作原理如图2-15所示。
  当使用“<<”运算符时,左移操作将舍弃移出的所有位,并用0来填充移入的位。同样,右移运算符“>>”也将操作数右移,每一次右移,整型变量的值将除以2。AND位运算符“&”通过逐位执行逻辑AND运算,从而生成新的操作数,AND运算中,两个对应的值,若有一个值为0,则全部为0,原理如图2-16所示。

左移

图2-15 左移

AND位运算

图2-16 AND位运算

  OR位运算符“|”的是用方法和原理和AND位运算符“&”基本相同,其区别在于使用的是OR运算,当有一个值为1,则结果为1,其原理如图2-17所示。

  XOR位运算符“^”的用法和AND位运算符类似,其区别在于当两个值相同时,执行计算的结果为0,否则为1,其原理图如2-18所示。

OR位运算

图2-17 OR位运算

图2-18 XOR位运算

图2-18 XOR位运算
取补运算符“~”将生成整型类型的补码。如原值中的1将变为0,而0则变为1,原理图如2-19所示。

取补位运算

图2-19 取补位运算

7.赋值运算符
  C#提供了几种类型的赋值运算符,最常见的就是“=”运算符。C#还提供了组合运算符,如“+=”、“-=”、“*=”等。“=”运算符通常用来赋值,示例代码如下。
+展开
-C#
int a,b,c;//声明三个整型变量
            a = b = c = 1;//使用赋值运算符


  上述代码声明并初始化3个整型变量a、b、c并初始化值这些变量的值为1。加法赋值运算符“+=”将加法和赋值操作组合起来,先把第一个数值的值加上第二个数值的值再存放到第一个数值的,示例代码如下所示。
+展开
-C#
 a += 1;//进行自加运算

上述代码会将变量a的值加上1并再次赋值回a,上述代码实现的功能和以下代码等效。
+展开
-C#
a = a + 1;//不使用+=运算符

同样,“-=”,“*=”,“/=”都是将第一个数值的值与第二个数值的值做操作再存放到第一个数值,同样也支持位运算符,示例代码如下所示。
+展开
-C#
a <<= 1;//移位运算

赋值运算符不仅支持加减乘除和位运算,同样也支持条件运算符,示例代码如下所示。
+展开
-C#
a &= 1;//条件运算

8.条件运算符
条件运算符“?:”需要三个操作数,示例代码如下所示。
+展开
-C#
bool ifisTrue=true;//创建布尔值
            string result = ifisTrue ? "true" : "false";//使用三元条件运算符
            Console.WriteLine(result.ToString());//输出布尔值

  上述代码中,使用了条件运算符“?:”,条件运算符“?:”会执行第一个条件,若条件成立,则返回“:”运算符前的一个操作数的数值,否则返回“:”运算符后的操作数的数值。上述代码中,变量ifisTrue为true,则返回“true”。

  技巧:当记忆条件运算符的时候,“?”可以被记忆为“条件成立吗”,如果成立,则执行第一个,否则执行第二个,如(1>2)?1:2可以解释成1大于2吗,大于则返回1,不大于则返回2,这样有助于记忆和阅读。

2.4.2 运算符的优先级
  开发人员需要经常创建表达式来执行应用程序的计算,简单的有加减法,复杂的有矩阵、数据结构等,在创建表达式时,往往需要一个或多个运算符。在多个运算符之间的运算操作时,编译器会按照运算符的优先级来控制表达式的运算顺序,然后再计算求值。例如在生活中也常常遇到这样的计算,如1+2*3。如果在程序开发中,编译器优先运算“+”运算符并进行计算就会造成错误的结果。

1.运算顺序
表达式中常用的运算符的运算顺序如表2-7所示。
表2-7 运算符优先级
运算符类型    运算符
元运算符     X.y,f(x),a[x],x++,x--,new,typeof,checked,unchecked
一元运算符    +,-,!,~,++x,--x,(T)x
算术运算符    *,/,%
位运算符     <<,>>,&,|,^,~
关系运算符    <,>,<=,>=,is,as
逻辑运算符    &,^,|
条件运算符    &&,||,?
赋值运算符    =,+=,-=,*=,/=,<<=,>>=,&=,^=,|=

  当执行运算1+2*3的时候,因为“+”运算符的优先级比“*”运算符的优先级低,则当编译器编译表达式并进行运算的时候,编译器会首先执行“*”运算符的乘法操作,然后执行“+”运算符的加法操作。当需要指定运算符的优先级,可以使用圆括号来告知编译器自定义运算符的优先级,示例代码如下所示。
+展开
-C#
c = a + b * c;//先执行乘法
            c = (a + b) * c;//先执行加法


2.左结合和右结合
  所有的二元运算符都是右两个操作数,除了赋值运算符以外其他的运算符都是左结合的,而赋值运算符是右结合,示例代码如下所示。
+展开
-C#
            a + b + c;//结合方式为(a+b)+c
            a = b = c;//结合方式为a=(b=c)

加支付宝好友偷能量挖...


评论(0)网络
阅读(77)喜欢(0)Asp.Net/C#/WCF