概述:运算符定义与分类、优先级与结合性。
零 运算符(operator)
0.定义
- 指定在表达式要对一系列称为操作数(opreand)的值执行那些运算或操作,以生成一个新值或者结果。
1.分类:
- 一元操作符(对应一个操作数)
- 二元操作符(对应二个操作数)
- 二元操作符要求两个操作数,分别称为左操作数和右操作数,二元运算符要求代码对结果值进行赋值,以避免丢失结果值。
- 三元操作符(对应三个操作数)
类别 | 运算符 | |
---|---|---|
算数运算符 | + - * / % |
|
逻辑运算符 | & | ^ ~ && || ! |
|
字符串连接运算符 | + |
|
自增自减运算符 | ++ -- |
|
移位运算符 | << >> |
|
比较运算符 | == != <> <= >= |
|
赋值运算符 | = += -= *= /= %= &= |= ^= <<= >>= |
|
成员访问运算符 | . |
|
索引运算符 | [] |
|
类型转换运算符 | () |
|
条件运算符 | ?: |
|
委托连接删除运算符 | + - |
|
对象运算符 | new |
|
类型信息运算符 | sizeof is typeof as |
|
溢出异常控制运算符 | checked unchecked |
|
简介寻址运算符 | [] |
|
名称空间别名运算符 | :: |
|
空合并运算符 | ?? |
- 备注:
sizeof(求取值类型占用空间大小,单位字节)
、*(获取地址的内容)
、->(间接寻址)
、&(取地址)
这个几个运算符只能用于不安全的代码(忽略C#类型安全检查的代码)
一 运算符使用
0.自增(自减)运算符(++
--
)
- 前置,把运算符放在前面;后置把运算符放在后面。
- x++单独使用表示:x=x+1
- 如果自增(自减)在表达式内部,那么前置会在计算表达式值的时候先递增(递减);后置会在计算表达式之后再递增(递减)。
var x = 1;
if (++x == 2)//true
Console.WriteLine("x==2");
if(x++==3)//false
Console.WriteLine("x==3");
1.条件运算符(?:
)
- 三元运算符,
if...else...
的简化形式 - condition?true_value:false_value
2.溢出检查运算符(checked
、unchecked
)
checked
溢出检查,把一个代码块标记为checked
,CLR(运行时)就会执行溢出检查,如果发生溢出,会抛出OverflowException
异常。unchecked
不会执行溢出检查,当发生溢出时候,不会抛出异常,但会丢失数据(因为类型不足以保存值)。unchecked
是默认行为。
//bMax是byte能存储的最大值
byte bMax = 255;
checked
{
//该句代码会抛出异常
bMax++;
}
2.is运算符
- is运算符:可以检查对象是否与特定的类型兼容。“兼容”表示对象是该类型,或者派生自该类型。
- 引用类型与值类型都可以使用。
int i = 10;
if (i is ValueType)//true
Console.WriteLine($"{nameof(i)} is ValueType");
var list = new List<string>();
if (list is IList<string>)//true
Console.WriteLine($"{nameof(list)} is IList<string>");
3.as运算符
-
用于执行引用类型的显示类型转换。如果要转换的类型与指定的类型兼容,转换就会成功进行;如果类型不兼容,as运算符就会返回null值。
- 安全强制类型转换,不会抛出异常。不成功就返回null。
- 不比在使用is 来判断类型,直接转换。
var s1 = (object)"字符串";
var s2 = s1 as string;
Console.WriteLine(s2);//s2 = "字符串"
4.sizeof运算符
- 可以确定栈中值类型需要的长度(单位字节)。
- 对于复杂类型(和非基元类型)使用sizeof运算符,就需要把代码放在usafe块中。
struct MyStruct
{
int Age { get; set; }
decimal Height { get; set; }
}
class MyClass
{
int Age { get; set; }
decimal Height { get; set; }
}
//测试代码
//size 4
Console.WriteLine($"int size :{sizeof(int)}");
//size 16
Console.WriteLine($"decimal size :{sizeof(decimal)}");
unsafe
{
//size 20
Console.WriteLine($"MyStruct size:{sizeof(MyStruct)}");
//引用类型无法使用
//Console.WriteLine($"MyClass size:{sizeof(MyClass)}");
}
5.空合并运算符(??
)
- 可以在处理可空类型和引用类型,当值为null,提供另外一个值。
- 第一个操作数必须是可空类型或者引用类型
- 第二个操作数必须与第一个操作数的类型相同,或者可以隐式地转换为第一个操作数的类型。
- 如果第一个操作数不是null,整个表达式就是第一个值
- 如果第一个操作数是null,整个表达式就是第二个操作数的值
二.结合性与优先级
- 结合性:规定了操作数如何组合,所以决定了运算符的求值顺序。
- 优先级:不同的运算符同时出现根据优先级来判定哪一个先求值。
优先级
| 组 | 运算符 |
| :——| :—— |
| 初级运算符 | ()
.
[]
x++
x--
new
typeof
sizeof
checked
unchecked
|
| 一元运算符 | +
-
!
~
++x
--x
数据类型强制转换()
|
| 乘除运算符 | *
/
%
|
| 加减运算符 | +
-
|
| 移位运算符 | <<
>>
|
| 关系运算符 | <
>
>=
<=
is
as
|
| 比较运算符 | ==
!=
|
| 按位AND运算符 | &
|
| 按位XOR运算符 | ^
|
| 按位OR运算符 | |
|
| 布尔AND运算符 | &&
|
| 布尔OR运算符 | ||
|
| 条件运算符 | ?:
|
| 赋值运算符 | =
+=
-=
*=
/=
%=
&=
|=
^=
<<=
>>=
>>>=
|