C#提供了大量的运算符,按需要操作数的数目来分:一元运算符(如++);二元运算符(如+,*);三元运算符(如? : )。
按运算功能来分,基本的运算符可以分为以下几类:(1) 算术运算符;(2) 关系运算符;(3) 逻辑运算符 ;(4) 位运算符;(5)赋值运算符;(6)条件运算符;(7)其它(分量运算符 ' .' ,下标运算符 ' [ ]'等)
1.算术运算符作用的操作数类型可以是整型也可以是浮点型,运算符如下表所示:
运 算 符 |
含义 |
示例(假设x,y是某一数值类型的变量) |
+ |
加 |
x+y; x+3 |
- |
减 |
x-y; y-3 |
* |
乘 |
x*y; 4*3 |
/ |
除 |
x/y; 5/3; 5.0/2.0 |
% |
取模 |
x%y; 11%3; 11.0%3 |
++ |
递增 |
++x; x++; |
-- |
递减 |
--x; x--; |
其中:
①“+-*/ ”运算与一般代数意义及其他语言相同,但需要注意:当“/”作用的两个操作数都是整型数据类型时,其计算结果也是整型。例如:
4/2 // 结果等于2
5/2 // 结果等于2
5/2.0 // 结果等于2.5
②“%”取模运算,即获得整数除法运算的余数,所以也称取余。例如:
11%3 // 结果等于2
12%3 // 结果等于0
11.0%3 // 结果等于2,这与C/C++不同,它也可作用于浮点类型的操作数
③“++”和“--”递增和递减运算符是一元运算符,它作用的操作数必须是变量,不能是常量或表达式。它既可出现在操作数之前(前缀运算),也可出现在操作数之后(后缀运算),前缀和后缀有共同之处,也有很大区别。例如:
++x // 先将x加一个单位,然后再将计算结果作为表达式的值。
x++ // 先将x的值作为表达式的值,然后再将x加一个单位
不管是前缀还是后缀,它们操作的结果对操作数而言,都是一样的,操作数都加了一个单位,但它们出现在表达式运算中是有区别的。例如:
int x , y ;
x=5 ; y=++x ; // x和y的值都等于6
x=5 ; y=x++ ; // x的值是6,y的值是5
关系运算符用来比较两个操作数的值,运算结果为布尔类型的值(true或false),如下表所示。
运 算 符 |
操 作 |
结果(假设x,y是某相应类型的操作数) |
> |
x>y |
如果x大于y,则为true,否则为false |
>= |
x>=y |
如果x大于等于y,则为true,否则为false |
< |
x |
如果x小于y,则为true,否则为false |
<= |
x<=y |
如果x小于等于y,则为true,否则为false |
== |
x==y |
如果x等于y,则为true,否则为false |
!= |
x!=y |
如果x不等于y,则为true,否则为false |
如果操作数是string类型的,则在下列两种情况下被视为两个string值相等。
①两个值均为null。
②两个值都是对字符串实例的非空引用,这两个字符串不仅长度相同,并且每一个对应的字符位置上的字符也相同。
例如:
string s1="ABCD", s2="1234" , s3 = "ABCD" ;
s1 ==s2; // 结果为false
s1 ==s3; // 结果为true
C#语言提供了四种逻辑操作符: 逻辑与(&&),逻辑或(||)、逻辑非(!)和逻辑判断(?:),其中逻辑与和逻辑或是二元操作符,逻辑非是一元操作符,而逻辑判断是三元操作符。
a |
b |
!a |
a&&b |
a||b |
true |
true |
false |
true |
true |
true |
false |
false |
false |
true |
false |
true |
true |
false |
true |
false |
false |
true |
false |
false |
位运算符如下表所示,借助这些位运算符可以完成对整型数的某一位测试、设置以及对一个数的位移动等操作,这对许多系统级程序设计是非常重要。
运算符 |
含义 |
运算符 |
含义 |
& |
按位与 |
~ |
按位取反 |
| |
按位或 |
>> |
右移 |
^ |
按位异或 |
<< |
左移 |
按位与、按位或、按位异或、按位取反运算与前面介绍的与之相应的逻辑运算符的与、或、异或、取反操作含义相同,只不过位运算把这种操作作用到每一个二进制位上,逻辑运算的真或假值对应位运算的位的1或0值。例如:
在实际使用中,按位与通常用于将某位置0或测试某位是0还是1;按位或通常用于将某位置1。 例如:
ushort n;
n=0x17ff ;
if ( (n & 0x8000) == 0 )
Console.WriteLine ("最高位第十五位为0" ) ;
else
Console.WriteLine ("最高位第十五位为1" ) ;
n = (ushort)(n & 0x7fff); //n 的最高位(第15位)置0,其它位不变
n = (ushort)(n | 0x8000); //n 的最高位(第15位)置1,其它位不变
按位异或运算有一个特别的属性,假设有两个整型数x和 y,则表达式 (x ^ y) ^ y值还原为x,利用这个属性可以创建简单的加密程序。例如:
public static void Main( )
{
char ch1 = 'O' , ch2 = 'K' ;
int key = 0x1f;
Console.WriteLine ("明文:" + ch1 + ch2 ) ;
ch1 = (char) (ch1 ^ key ) ;
ch2 = (char) (ch2 ^ key ) ;
Console.WriteLine ("密文:" + ch1 + ch2 ) ;
ch1 = (char) (ch1 ^ key ) ;
ch2 = (char) (ch2 ^ key ) ;
Console.WriteLine ("解码:" + ch1 + ch2 ) ;
}
移位运算符有两个:一个左移(<<),一个右移(>>)。其基本形式为:
value << num_bits
value >> num_bits
左操作数value是要被移位的值,右操作数num_bits是要移位的位数。
左移是将给定的value向左移动num_bits位,左边移出的位丢掉,右边空出的位填0。例如:
0x1A << 2;
0x1A(十进制26)经过左移2位运算,结果值是0x68(十进制104),相当于对0x1A的值乘以 。但如果左移丢掉的位含有1,那么左移之后的值可能反而会变小。例: 0x4A << 2 ;
右移是将给定的value向右移动num_bits位,右边移出的位丢掉,左边空出的位要根据value的情况填0或1。若value是一个无符号数,左边补0;若value是一个带符号数,则按符号(正数为0,负数为1)补。 例: 0x77 >> 2 ;
0x8A >> 2 ;
语法形式:var = exp
赋值运算符左边的称为左值,右边的称为右值。右值是一个与左值类型兼容的表达式(exp),它可以是常量、变量或一般表达式。左值必须是一个已定义的变量或对象(var),因为赋值运算就是将表达式的值存放到左值,因此左值必须是内存中已分配的实际物理空间。例如:
int a=1;
int b=++a; // a的值加1赋给了b
如果左值和右值的类型不一致,在兼容的情况下,则需要进行自动转换(隐式转换)或强制类型转换(显式类型转换)。一般原则是,从占用内存较少的短数据类型向占用内存较多的长数据类型赋值时,可以不做显式的类型转换,C#会进行自动类型转换,反之当从较长的数据类型向占用较少内存的短数据类型赋值时,则必须做强制类型转换。例如:
int a=2000;
double b=a; // 隐式转换,b等于2000
byte c=(byte)a; // 显示转换,c等于208
在进行如x = x +3 运算时,C#提供一种简化方式x +=3,这就是复合赋值运算。
语法形式: var op= exp
除了关系运算符,一般二元运算符都可以和赋值运算符在一起构成复合赋值运算。
语法形式: exp1 ? exp2 : exp3
其中,表达式exp1的运算结果必须是一个布尔类型值,表达式exp2和exp3可以是任意数据类型,但它们返回的数据类型必须一致。
首先计算exp1的值,如果其值为true,则计算exp2值,这个值就是整个表达式的结果;否则,取exp3的值作为整个表达式的结果。例如:
z = x > y ? x : y ; //z的值就是x,y中较大的一个值
z = x >=0 ? x : -x ; //z的值就是x的绝对值
new 操作符:new 操作符用于创建一个新的类型实例
typeof 操作符:typeof 操作符用于获得系统原型对象的类型,例如:typeof(int)、typeof(System.Int32) 、typeof(string)、typeof(double);
上面四个表达式的输出分别是:Int32 、 Int32 、string 、double
checked和unchecked 操作符:checked 和unchecked 操作符用于整型算术运算时控制当前环境中的溢出检查 。
当表达式包含多个运算符时,运算符的优先级控制各运算符的计算顺序。例如,表达式 x + y * z 按 x + (y * z) 计算,显然 * 运算符的优先级比 + 运算符高。
类 别 |
计算顺序 |
运 算 符 |
基本 |
高 低 |
() [] new typeof checked unchecked |
一元 |
++ -- + - ! ~ |
|
乘除 |
* / % |
|
加减 |
+ - |
|
位移 |
<< >> |
|
关系 |
< > <= >= |
|
相等 |
== != |
|
逻辑 AND |
& |
|
逻辑 XOR |
^ |
|
逻辑 OR |
| |
|
条件 AND |
&& |
|
条件 OR |
|| |
|
条件 |
?: |
|
赋值 |
= *= /= %= += -= <<= >>= &= ^= |= |
关系运算符的优先级总结出如下几点:
① (<,>,<=,>=)这4种关系运算符优先级相同,而(==,!=)这2种关系运算符的优先级相同。前4种高于后2种。
②关系运算符的优先级低于算术运算符。
③关系运算符的优先级高于赋值运算符。
关系运算符优先级
①a > b + c 等效于 a > (b + c)
②a + b != a * b 等效于 (a + b) != (a * b)
③ a == b > c 等效于 a == (b > c) (a必须为一个bool值)
④a = b > c 等效于 a = (b > c) (a必须为一个bool值)
用逻辑运算符将关系表达式或逻辑量连接起来就是逻辑表达式。逻辑表达式的值是一个bool值,也就是说,它只能返回true或false。在一个逻辑表达式中,通常使用3种运算符,按优先级从高到低的顺序进行如下排列。
①! 逻辑非
②&& 逻辑与
③|| 逻辑或
① a > b && x > y 的计算顺序为:(a > b) && (x > y)
②a == b || x == y 的计算顺序为:(a == b) || (x == y)
③ !a || a > b 的计算顺序为:(!a) || (a > b)