- C# 从入门到项目实践(超值版)
- 聚慕课教育研发中心
- 5668字
- 2021-03-24 02:36:15
4.4 运算符
运算符是处理和操作数据的一种符号单元,其作用是标识出数据与数据之间的运算关系,帮助程序来操作这些数据的运算过程。
运算符,又称为操作符。在C#中有6种运算符,包括算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符和特殊运算符。本节将逐一讲解各类运算符的使用。
4.4.1 算术运算符
算术运算符的作用是对整数型,或者实数型变量进行各种基本的算术运算。在C#中,算术运算符包括7种,如表4-7所示显示了C#支持的所有算术运算符。
表4-7 算术运算符
【例4-10】编写程序,声明两个变量,对这两个变量进行算术运算操作。
(1)在Visual Studio 2017中,新建名称为“Project10”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了算术运算符的操作。在代码中,首先定义三个变量,分别为a、b、c,并对变量a和b进行赋值;接着将运算的结果赋给变量c。
在Visual Studio 2017中的运行结果如图4-13所示。
图4-13 算术运算符
自增自减运算符是两个特殊的一元运算符。所谓元,是指操作数的数量,一个操作数为一元,两个操作数为两元,以此类推。
自增自减运算符除了分别进行加法运算和减法运算,还有赋值的功能,下面以自增运算符为例。
(1)后缀方式,变量先赋值再进行加法运算。
例如:
int a=5,b; b=a++;
该段语句表示,先把a的值赋给b,然后再对a进行自增运算。所以,最后的结果a为6,b为5。
(2)前缀方法,变量先进行加法运算再赋值。
例如:
该段语句表示,先对a进行自增运算,然后再把a的值赋给b。所以,最后的结果a为6,b也为6。
【例4-11】编写程序,对一个变量进行自增自减运算。
(1)在Visual Studio 2017中,新建名称为“Project11”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了自增自减运算符的使用。在代码中首先定义两个整型变量a和b,接着对变量a赋值为1。
当变量a和b以自增自减运算符的后缀方式进行操作时,语句“b=a++;”表示先将a的值赋给b,然后再对变量a进行自加1,所以,输出a的值为2,b的值为1;然后将a初始化为1,语句“b=a--;”表示先将a的值赋给变量b,然后再对变量a进行自减1,所以输出a的值为0,b的值为1。
当变量a和b以自增自减运算符的前缀方式进行操作时,先将变量a初始化为1,语句“b=++a”表示先将a进行自加1,再赋给变量b,所以输出a的值为2,b的值也为2;然后再将a初始化为1,语句“b=--a”表示先对a进行自减1运算,然后赋给变量b,所以最后输出a为0,b也为0。
在Visual Studio 2017中的运行结果如图4-14所示。
图4-14 自增自减运算符
4.4.2 赋值运算符
赋值运算符的作用是对常量和变量进行初始化,或者为变量赋予一个新的值。赋值运算符不仅可以在变量被声明时赋值,还可以对已经初始化的变量赋值。
例如:
Type VariableName = Value VariableName = NewValue
如果为某个变量多次赋值,改变量的值以最新的赋值为标准。表4-8列出了C#支持的赋值运算符。
表4-8 赋值运算符
【例4-12】编写程序,定义两个变量,对这两个变量进行赋值运算。
(1)在Visual Studio 2017中,新建名称为“Project12”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了赋值运算符的使用。在代码中,首先定义两个整型变量a、c,并初始化赋值;然后通过赋值运算符对这两个变量进行赋值运算。
在Visual Studio 2017中的运行结果如图4-15所示。
图4-15 赋值运算符
4.4.3 关系运算符
关系运算符又称为比较运算符,其作用是对运算符两侧的表达式进行比较,获取一个比较后的结果,若成立返回逻辑真true,否则返回逻辑假false。通常作为条件分支控制语句。表4-9显示了C#支持的所有关系运算符。
表4-9 关系运算符
【例4-13】编写程序,通过关系运算符对两个整数进行判断。
(1)在Visual Studio 2017中,新建名称为“Project13”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了关系运算符的使用。在代码中,首先定义两个整型变量a和b,并初始化赋值;然后通过使用关系运算符对这两个变量进行判断,最后输出判断的结果。
在Visual Studio 2017中的运行结果如图4-16所示。
图4-16 关系运算符
4.4.4 逻辑运算符
逻辑运算符用来连接多个bool类型表达式,实现多个条件的复合判断。如表4-10所示显示了C#支持的所有逻辑运算符。
表4-10 逻辑运算符
【例4-14】编写程序,通过逻辑运算符对两个bool值进行判断。
(1)在Visual Studio 2017中,新建名称为“Project14”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了逻辑运算符的使用。在代码中,定义两个bool类型的变量a和b,首先对这两个值都赋予true值;然后通过if语句进行判断,由于a和b都为真,所以a&&b、a||b都为真;接着,对变量a赋予false值,对b赋予true值;最后再通过if语句进行判断,由于a值为假,b值为真,所以a&&b为假,但是!(a&&b)则为真。
在Visual Studio 2017中的运行结果如图4-17所示。
图4-17 逻辑运算符
4.4.5 位运算符
在C#中可以对整型数据按位进行逻辑操作。位运算符&(与)、|(或)和^(异或)的真值表如表4-11所示。
表4-11 真值表
1. 位逻辑与运算(&)
位逻辑与运算将两个运算对象按位进行与运算。与运算的规则:1与1等于1,1与0等于0,0与0等于0。
例如,有两个整型变量A和B,其中,A=76,B=231,然后对这两个变量进行按位与计算。
图4-18 &运算
经过计算,十进制数76的二进制表达是0100 1100,十进制数231的二进制表达是1110 0111。对按位与操作符来说,只要对应的两个二进制位有一个为0时,结果就为0,如图4-18所示。
将得到的0100 0100转换成十进制数就是68,用C#语言表示就是:
int result = 76 & 231;
2. 位逻辑或运算(|)
位逻辑或运算将两个运算对象按位进行或运算。或运算的规则是:1或1等于1,1或0等于1,0或0等于0。
图4-19 |运算
例如,有两个整型变量A和B,其中,A=38,B=53,然后对这两个变量进行按位或计算。
经过计算,十进制数38的二进制表达是0010 0110,十进制数53的二进制表达是0011 0101。对按位或操作符来说,只要对应的两个二进制位有一个为1时,结果就为1,如图4-19所示。
将得到的0011 0111转换成十进制就是55,用C#表示就是:
int result = 38 | 53;
3. 位逻辑异或运算(^)
位逻辑异或运算将两个运算对象按位进行异或运算。异或运算的规则是:1异或1等于0,1异或0等于1,0异或0等于0。即:相同得0,相异得1。
图4-20 ^运算
例如,有两个整型变量A和B,其中,A=138,B=43,然后对这两个变量进行按位异或计算。
经过计算,十进制数138的二进制表达是1000 1010,十进制数43的二进制表达是0010 1011。对按位异或操作符来说,当两个对应的二进位相异时,结果为1,如图4-20所示。
将得到的1010 0001转换成十进制就是161,用C#语言表示就是:
int result = 138 ^ 43;
按位进行逻辑运算的意义在于,依次取被运算对象的每个位,进行逻辑运算,每个位的逻辑运算结果是结果值的每个位。
在进行&(与)、|(或)和^(异或)运算时,如果两个运算对象的类型一致,则运算结果的类型就是运算对象的类型。例如对两个int类型变量a和b做与运算,运算结果的类型还是int型。如果两个运算对象的类型不一致,则C#要对不一致的类型进行类型转换,变成一致的类型,然后进行运算。类型转换的规则同算术运算中整型量的转换规则一致。如表4-12所示列出了C#支持的位运算符。
表4-12 位运算符
4. 位逻辑非运算(~)
位逻辑非运算是单目的,只有一个运算对象。位逻辑非运算按位对运算对象的值进行非运算,即:如果某一位等于0,就将其转变为1;如果某一位等于1,就将其转变为0。
图4-21 ~运算
例如,有个十进制数52进行取反计算。
经过计算,十进制数52的二进制表达是0011 0100,对取反操作符来说,对应的二进制数按位求反,0变成1,1变成0,如图4-21所示。
把得到的1100 1011转换成十进制就是203,用C#语言表示就是:
int result = ~52;
5. 移位运算符
“<<”和“>>”运算符用于执行移位运算,分别称为左移位运算符和右移位运算符。对于X<<N和X>>N形式的运算,含义是将X向左或向右移动N位,得到的结果的类型与X相同。此处,X的类型只能是int、uint、long或ulong,N的类型只能是int,N的类型只能是int,或者显式转换为这些类型之一,否则编译程序时会出现错误。
(1)左移位运算符(<<)。
图4-22 <<运算
使用左移位运算符可以将二进制数据向左移位。其作用是所有的位都向左移动指定的次数,高次位就会丢失,低位以0来填充,移位操作从不导致溢出,如图4-22所示。
(2)右移位运算符(>>)。
右移位运算符是把二进制数据向右移位,其作用是所有的位都向右移动指定的次数。
图4-23 >>运算
注意:如果第一个操作数是int或uint(32位数),则移位数由第二个操作数的低5位给出,如果第一个操作数是long或ulong(64位数),则移位数由第二个操作数的低6位给出。如果第一个操作数为int或long,则右移位是算术移位(高序空位设置为符号位)。如果第一个操作数是uint或ulong类型,则右移位是逻辑移位(高位填充0),如图4-23所示。
【例4-15】编写程序,使用位运算符,对两个变量进行运算。
(1)在Visual Studio 2017中,新建名称为“Project15”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了位运算符的使用。在代码中,首先定义三个int类型的变量a、b、c;然后对a赋值为60,b赋值为13;接着,使用位运算符将变量a和b的运算结果赋给变量c。
在Visual Studio 2017中的运行结果如图4-24所示。
图4-24 移位运算符
4.4.6 特殊运算符
和C语言相比,在C#中多了一些特殊的运算符,如typeof、is和as。表4-13列出了C#支持的其他一些重要的运算符。
表4-13 特殊运算符
1. sizeof运算符
sizeof运算符用于获取值类型的字节大小。例如,可以检索int类型的大小:
int intSize = sizeof(int); Console.WriteLine(intSize);
注意:
(1)sizeof运算符仅适用于值类型,而不适用于引用类型。
(2)不能重载sizeof运算符。
2. typeof运算符
typeof运算符用于获得指定类型在system名字空间中定义的类型名字。typeof表达式采用以下格式:
System.Type type = typeof(x);
注意:
(1)typeof(x)中的x,必须是具体的类名、类型名称等,不可以是变量名称。
(2)不能重载typeof运算符。
【例4-16】编写程序,利用typeof运算符获取类型的信息。
(1)在Visual Studio 2017中,新建名称为“Project16”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】typeof运算符的主要作用是将类型的信息当作字符串返回。而在本段代码中,通过使用typeof,把char、int、float、double[]和string类型的对象信息当作字符串输出。
在Visual Studio 2017中的运行结果如图4-25所示。
图4-25 typeof运算符
3. &和*运算符
(1)&运算符既可作为一元运算符也可作为二元运算符。在当作一元运算符时称为取地址运算符,用于返回变量的地址。在当作二元运算符时,对两个整型数据进行逻辑按位与操作。
(2)*运算符同样既可作为一元运算符也可作为二元运算符。在作为一元运算符时,称为取消引用运算符或者间接寻址运算符,用于对指针执行读取和写入操作。在作为二元运算符时,用于表示乘法运算符。
注意:&和*在作为一元运算符使用时,仅可用于不安全的上下文,通过使用unsafe关键字表示,并且需要/unsafe编译器选项。
在设置编译器选项时,首先在Visual Studio 2017开发环境中打开项目的“属性”页,接着单击“生成”属性页,最后选中“允许不安全代码”复选框即可。
【例4-17】编写程序,获取一个变量的地址,并输出该地址所指向的值。
(1)在Visual Studio 2017中,新建名称为“Project17”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了&和*运算符的使用。在代码中,首先定义一个整型变量i,并赋值为5;然后使用取地址运算符&,获取变量i的地址;接着,再定义一个指针p,将i地址赋给指针p,并输出指针p所指向的地址;最后通过间接寻址运算符*,获取地址所指向的值,也就是变量i的值。
在Visual Studio 2017中的运行结果如图4-26所示。
图4-26 &和*运算符
4. is和as运算符
在C#中关于类型的判断和转换有is和as这两个操作符。
(1)is运算符用于检查变量是否为指定的类型。如果是,就返回true,否则就会返回false。
【例4-18】编写程序,判断整型变量a是否为整型。
① 在Visual Studio 2017中,新建名称为“Project18”的文件。
② 在代码编辑区域输入以下代码。
【程序分析】本例演示了is运算符的使用。在代码中,首先定义一个int类型的变量a,并赋值为1;然后再定义两个bool类型的变量x和y;接着将判断变量a为float类型的结果赋给x,将判断变量a为int类型的结果赋给y;最后输出判断结果。
在Visual Studio 2017中的运行结果如图4-27所示。
图4-27 is运算符
(2)as运算符主要用于在兼容的引用类型之间执行转换。如果要转换的类型与指定类型兼容,转换就会成功,如果类型不兼容,则返回null,并且不抛出异常,因此转换是否成功可以通过结果是否为null进行判断。
【例4-19】编写程序,对一个引用类型的变量进行类型转换。
① 在Visual Studio 2017中,新建名称为“Project19”的文件。
② 在代码编辑区域输入以下代码。
【程序分析】本例演示了as运算符的使用。在代码中,首先定义一个object类型的变量o,并进行初始化赋值;然后通过as运算符将变量o转换为string类型,再赋给变量s;最后输出这两个变量。
在Visual Studio 2017中的运行结果如图4-28所示。
图4-28 as运算符
5. 条件运算符
条件运算符“?:”是C#中唯一的一个三元运算符,其语法格式如下:
条件表达式?表达式1:表达式2;
该语句表示首先求出条件表达式的值(bool类型),为true时调用表达式1,为false时调用表达式2。其逻辑为“如果条件为真执行第一个,否则执行第二个”。
【例4-20】编写程序,使用条件运算符为变量赋予相应的值。
(1)在Visual Studio 2017中,新建名称为“Project20”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了条件运算符的使用。在代码中,首先定义两个整型变量a和b,并为a赋值为10;然后进行判断,如果a值为1条件成立,将20赋给变量b,否则就将30赋给变量b;接着判断a值为10的条件是否成立;最后输出两次的运算结果。
在Visual Studio 2017中的运行结果如图4-29所示。
图4-29 条件运算符
4.4.7 运算符优先级
运算符的优先级确定表达式中项的组合,这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
例如,x=7+6*2,在这里,x被赋值为19,而不是15,因为运算符“*”具有比“+”更高的优先级,所以首先计算乘法“6*2”,然后再加上7。
如表4-14所示,按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
表4-14 运算符优先级
【例4-21】编写程序,使用运算符计算出表达式的值。
(1)在Visual Studio 2017中,新建名称为“Project21”的文件。
(2)在代码编辑区域输入以下代码。
【程序分析】本例演示了运算符的优先级。在代码中首先定义了5个int类型的变量x、y、z、m和n,并为x赋值为20,y赋值为10,z赋值为15,n赋值为5;接着使用算术运算符和括号运算符将这4个赋值后的变量连接起来,并将运算后的值赋给变量m。
在Visual Studio 2017中的运行结果如图4-30所示。
图4-30 运算符优先级