返回首页
当前位置: 主页 > 编程语言 > C#教程 >

C#中基础运算操作与规则概述

时间:2017-02-08 22:39来源:电脑教程学习网 www.etwiki.cn 编辑:admin

控制优先级
优先级(precedence)控制着一个表达式中的各个操作符的求值顺序。例如以下表达式,它使用了操作符+和*:
2 + 3 * 4
如果没有优先级规则,该表达式就可能造成歧义。是先加还是先乘?换言之,3是绑定到它左边的操作符+,还是绑定到右边的操作符*?不同的求值顺序会造成不同的结果。
● 如果先加后乘,那么加法运算(2 + 3)的结果将成为操作符*的左操作数,所以整个表达式的结果是5 * 4,即20。 
● 假如先乘后加,那么乘法运算(3 * 4)的结果将成为操作符+的右操作数,所以整个表达式的结果是2 + 12,即14。 

在C#中,multiplicative操作符(*,/和%)的优先级高于additive操作符(+和-)。所以,2+ 3 * 4的结果是14。以后讨论每一种新的操作符时,我们都会指出它的优先级。
可以使用圆括号来覆盖优先级规则,强制操作数按你希望的任何方式绑定到操作符。例如在以下表达式中,圆括号强迫2和3绑定到操作符+(得5),再使结果成为操作符*的左操作数,最终的结果值是20:
(2 + 3) * 4
注意:本书所说的圆括号指的是();大括号或花括号指的是{};方括号指的是[]。

操作符优先级只能解决部分问题。假如一个表达式中的多个操作符具有相同的优先级,又该怎么办呢?这时就要用到结合性的概念。结合性(associativity)是指操作数的求值方向(向左或向右)。例如,以下表达式同时使用了操作符/和*:
4 / 2 * 6

该表达式仍有可能造成歧义。是先除,还是先乘?两个操作符的优先级是相同的(都是multiplicative操作符),但这个表达式的求值顺序至关重要,因为可能获得以下两个不同的结果。
● 如果先除,除法运算(4 / 2)的结果将成为操作符*的左操作数,整个表达式的结果是 (4 / 2) * 6,即12。 
● 如果先乘,那么乘法运算的结果(2 * 6)将成为操作符/的右操作数,整个表达式的结果是4 / (2 * 6),即4/12。 

在这种情况下,操作符的结合性决定着表达式的计算方式。由于操作符*和/具有相同的优先级,所以不能根据优先级来确定2绑定到*还是/。然而,决定操作符求值顺序的除了优先级之外,还有结合性。操作符*和/都具有左结合性;换言之,操作数是从左向右求值的。在本例中,4 / 2将在乘以6之前求值,所以正确结果是12。以后讨论每一种新的操作符时,我们都会指出它的结合性。

2.5.5 结合性和赋值操作符
在C#语言中,等号(=)称为赋值操作符。所有操作符都依据它们的操作数来返回一个值。赋值操作符(=)也不例外。它取两个操作数;右侧的操作数被求值,结果保存在左侧的操作数中。赋值操作符返回的值就是赋给左操作数的值。例如,在以下赋值语句中,赋值操作符返回的值是10,它也是赋给变量myInt的值。
 

int myInt;
myInt = 10; // 赋值表达式的值是10


至此,一切都甚合逻辑,但我们同时也会感到有些不解,这一切有什么意义呢?OK,由于赋值操作符返回了一个值,所以我们可以在另一个赋值语句中使用这个值,如下所示:
 

int myInt;
int myInt2;
myInt2 = myInt = 10;


赋给变量myInt2的值就是已经赋给myInt的值。赋值语句把同一个值赋给了两个变量。如果打算将多个变量初始化为同一个值,这个技术将非常有用。它使任何一个读代码的人清楚地理解所有变量都具有相同的值。
 

myInt5 = myInt4 = myInt3 = myInt2 = myInt = 10;


通过这里的讨论,我们可能已经推断出一点,赋值操作符是从右到左结合的。最右侧的赋值最先发生,被赋的值从右向左,在各个变量之间传递。如果任何一个变量以前已经有过值,就用当前赋的值覆盖它。

但是,使用这样的语法构造时要小心。新手C#程序员易犯的一个错误是试图将赋值操作符的这种用法与变量声明一起使用,如下所示:
 

int myInt, myInt2, myInt3 = 10;


上述C#代码在语法上没有错误(能通过编译),但它做的事情可能跟你想象的不同。它实际做的事情是声明变量myInt,myInt2和myInt3,并将myInt3初始化为10。然而,它不会初始化myInt或者myInt2。如果尝试在以下表达式中使用myInt或者myInt2:
 

myInt3 = myInt / myInt2;


编译器就会报告以下错误:
使用了未赋值的局部变量"myInt"
使用了未赋值的局部变量"myInt2"

2.6 变量的递增和递减
如果打算在一个变量上加1,可以使用+操作符:
 

count = count + 1;


然而,为变量加1是C#的一个非常普遍的操作,所以设计者专门为这个操作设计了一个操作符,即++操作符。例如,要使变量count递增1,可以像下面这样写:
 

count++;


类似地,C#提供了--操作符来从一个变量中减1:
 

count--;


++和--是一元操作符。换言之,它们只有一个操作数。它们和另一个一元操作符!具有相同的优先级和左结合性。操作符!的详情将在第4章讲述。

2.6.1 前缀和后缀 
递增(++)和递减(--)操作符与众不同的一个地方在于,它们既可以放在变量前面,也可以放在变量后面。在变量之前使用操作符称为这个操作符的前缀形式;在变量之后使用操作符则称为这个操作符的后缀形式。如下面几个例子所示:
 

count++; // 后缀递增
++count; // 前缀递增
count--; // 后缀递减
--count; // 前缀递减


对于被递增或者被递减的那个变量来说,++或--的递增和递减形式是没有区别的。例如,count++会使count的值递增1,++count也会使count的值递增1。那么,为何还要提供两种不同的形式呢?为了理解这个问题,必须记住一点:++和--都是操作符,而所有操作符都用于对一个表达式进行求值,并会返回求值结果。count++返回的是递增发生前的count值(先返回,再++),而++count返回的是递增发生后的count值(先++,再返回)。下面是一个例子:
 

int x;
x = 42;
Console.WriteLine(x++);// 执行这个语句后,x等于43,但控制台上输出的是42
x = 42;
Console.WriteLine(++x); // 执行这个语句后,x等于43,控制台上输出的也是43


其实很好记,只需看这种表达式的各个元素(操作符和操作数)出现的顺序即可。在表达式x++中,变量x首先出现,所以会先返回它现在的值,然后才会递增;在表达式++x中,++操作符首先出现,所以先对x进行递增,再将新值作为表达式的值来返回。

这些操作符在while和do语句中得到了广泛运用,第5章将详细讲述这些语句。如果只是孤立地使用递增和递减操作符7,请统一使用后缀形式。

2.7 声明隐式类型的局部变量
在本章前面,我们是通过指定数据类型和标识符的方式来声明变量,如下所示:
 

int myInt;


另外还提到,一个变量在使用前必须赋值。我们可以在同一个语句中声明并初始化一个变量,如下所示:
 

int myInt = 99;


还可以像下面这样(假定myOtherInt是一个已经初始化的整数变量):
 

int myInt = myOtherInt * 99;


请记。掣桓霰淞康闹当匦刖哂泻捅淞肯嗤睦嘈。例如,只能将int值赋给int变量。C#编译器可以迅速判断出用于初始化变量的一个表达式的类型,如果发现它和变量的类型不符,就会明确地告诉你。除此之外,还可要求C#编译器根据表达式推断一个变量的类型,并在声明变量时自动使用这个类型。为此,只需在类型的位置使用var关键字,如下所示:
 

var myVariable = 99;
var myOtherVariable = "Hello";


两个变量myVariable和myOtherVariable称为隐式类型(implicitly typed)变量。var关键字指示编译器根据用于初始化变量的表达式来推断变量的类型。在前面的例子中,myVariable是int类型,而myOtherVariable是string类型。必须认识到的一点是,var只是在声明变量的时候能为我们提供一些方便。但是,变量一旦声明,就只能将编译器推断的那种类型的值赋给它。例如,不能将float,double,string值赋给myVariable。还要认识到的一点是,只有在提供了一个表达式来初始化变量的时候,才能使用关键字var。以下声明是非法的,会导致编译错误:
 

var yetAnotherVariable; //错误-编译器不能推断类型


重要提示:如果用Visual Basic写过程序,就可能非常熟悉Variant类型,该类型可以用来在变量中保存任意类型的值。这里要强调的是,应该忘记当年用VB编程时学到的有关Variant变量的一切。虽然两个关键字貌似有联系,但var和Variant完全是两码事。在C#中用var关键字声明了一个变量之后,赋给该变量的值的类型就固定下来了,这个类型必须和用于初始化该变量的值的类型相同,不能随便改变 !

纯化论者可能不喜欢这个设计,他们会发出这样的质疑:像C#这样优雅的语言,设计者为什么竟然允许var这样的东西乘虚而入。它似乎是在助长程序员偷懒,使程序变得更难理解,而且更难找出错误(同时更容易在代码中引入新的bug)。但是,相信我,var在C#语言中占有一席之地是有缘由的。在学完后面几章之后,你肯定会有深切的体会。但是,就目前来说,应该坚持使用显式指定了类型的变量;除非万不得已,不要使用隐式类型的变量。

本章讲述了如何创建和使用变量,并讲述了C#变量的常用数据类型。另外,还讲述了标识符的概念。本章用大量操作符来构造表达式,并探讨了操作符的优先级和结合性如何影响表达式的求值顺序。
● 如果希望继续学习下一章的学习,请继续运行Visual Studio 2010,然后阅读第3章。 
● 如果希望现在就退出Visual Studio 2010,请选择“文件”|“退出”。如果看到“保存”对话框,请单击“是”按钮保存项目。

第2章快速参考

目 标 操 作
声明变量 按顺序写数据类型名称、变量名和分号,例如: 
int outcome;
更改变量值 按顺序写变量名、赋值操作符、用于计算新值的表达式和分号,例如: 
outcome = 42;
将string转换成int 调用System.Int32.Parse方法。例如: 
System.Int32.Parse("42");
覆盖优先级 在表达式中使用圆括号来强制一个求值顺序,例如: 
(3 + 4) * 5
将多个变量初始化为同一个值 使用赋值语句初始化所有变量,例如: 
myInt4 = myInt3 = myInt2 = myInt = 10;
递增或递减变量 使用++或--操作符,例如: 
count++;

------分隔线----------------------------
标签(Tag):c#
------分隔线----------------------------
推荐内容
猜你感兴趣