C#运算符

通过运算符,可以对操作数进行运算。运算符和操作数组成了表达式。

操作数本身也可以是字面量、常量、变量或表达式。

运算符需要n个操作数,这运算符就是n元运算符。

一元运算符可以放在操作数的前面或后面,分别是一元前置运算符和一元后缀运算符。

算术运算

整数、浮点数、小数支持算术运算。

运算符 说明
+a 计算a本身
-a 计算a的相反数
a+b 计算a与b的和
a-b 计算a与b的差
a*b 计算a与b的积
a/b 计算a除以b的商
a%b 计算a除以b余数

整数的算术运算

static void Main(string[] args){
    int a = 5,b=2;
    System.Console.WriteLine(a + b);//7
    System.Console.WriteLine(a - b);//3
    System.Console.WriteLine(a * b);//10
    System.Console.WriteLine(a / b);//2
    System.Console.WriteLine(a % b);//1
}

浮点数的四则运算

static void Main(string[] args){
    double a = 5.0,b=2.0;
    System.Console.WriteLine(a + b);//7
    System.Console.WriteLine(a - b);//3
    System.Console.WriteLine(a * b);//10
    System.Console.WriteLine(a / b);//2.5
    System.Console.WriteLine(a % b);//1
}

溢出

不同于数学,计算机中的数字使用表达范围的,各种运算可能会超出范围。

默认不做溢出检查的情况下,溢出会导致绕回。

static void Main(string[] args){
    int a = Int32.MaxValue;
    System.Console.WriteLine(a + 1);//-2147483648
}

如果要进行检查,可以使用checked.

static void Main(string[] args){
    int a = Int32.MaxValue;
    System.Console.WriteLine(checked(a + 1));
}

上面的代码会报溢出OverFlowException

关系运算符

关系运算用来判断两个操作数之间的大小、相等关系是否为真。如果为真,则为true,否则为false

运算符 说明
a<b a是否小于b
a<=b a是否小于或等于b
a>b a是否大于b
a>=b a是否大于或等于b
a==b a是否等于b
a!=b a是否不等于b
static void Main(string[] args){
    System.Console.WriteLine(5 > 2);//true
    System.Console.WriteLine(4 == 5);//false
    System.Console.WriteLine(9 < 6);//false
    System.Console.WriteLine(7 != 8);//true
}

逻辑运算符

逻辑运算符用来对bool类型进行运算.

逻辑运算符用来进行逻辑运算。

运算符 说明
a&&b 与。如果a和b同时为true,结果为true,否则为false
a||b 或。如果a和b有一个为true,结果为true;否则为0。
!a 非。a如果为true,结果为false;a如果为false,结果为true
static void Main(string[] args)
{
    System.Console.WriteLine(true && true);//true
    System.Console.WriteLine(true && false);//false
    System.Console.WriteLine(true || false);//true
    System.Console.WriteLine(false || false);//false
    System.Console.WriteLine(!true);//false
    System.Console.WriteLine(!false);//true
}

逻辑运行经常和关系运算一起使用

static void Main(string[] args)
{
    int a = 10;
    System.Console.WriteLine(a>0 && a<100);//true
    System.Console.WriteLine(!(a<0));//true
}

位运算符

位运算符用于对整数的每一位进行运算。

运算符 说明
a&b 位与。对a和b的每一位进行与运算。如果位都为1,返回1;否则为0。
a|b 位或。对a和b的每一位进行或计算。如果有一位为1,返回1;否则为0。
a^b 位亦或。对a和b的每一位进行亦或计算。如果位不相等,返回1;否则为0。
~a 位非。对a的每一位进行非计算。如果位为1,返回0;否则为1。
static void Main(string[] args){
    System.Console.WriteLine(1 | 2);//3 0001 & 0010
    System.Console.WriteLine(7 & 2);//2 0111 & 0010
    System.Console.WriteLine(7 ^ 2);//5 0111 ^ 0010
    System.Console.WriteLine(!0);//-1
}

位移运算符

位运算符用于对整数的每一位进行移动。

运算符 说明
a<<n 左位移运算符。将a的每一位向左移动n位。
a>>n 右位移运算符。将a的每一位向右移动n位。
static void Main(string[] args){
    System.Console.WriteLine(1 << 3);//8 0001 ->1000
    System.Console.WriteLine(7 >> 2);//1 0111 ->0001
}

自增自减运算符

自增自减运算符用于在操作数自身加1或减去1。

运算符 说明
a++ 后置自增。返回a自身,然后a自身加1。
++a 前置自增。返回a自身加1,然后返回a。
a-- 后置自减。返回a自身,然后a自身减1。
--a 前置自减。返回a自身减1,然后返回a。

赋值运算符

赋值运算符将右边的值赋给左边,左边必须是可变的。

运算符 说明
a=b 赋值。将b的值赋值给a,返回a。

复合赋值运算符

复合赋值运算符可以在变量自身进行运算后赋值。 算数运算符、位移运算符和位运算符支持符合赋值运算。

运算符 说明
a+=b 将a+b的值赋值给a。
a-=b 将a-b的值赋值给a。
a*=b 将a*b的值赋值给a。
a/=b 将a/b的值赋值给a。
a%=b 将a%b的值赋值给a。
a&=b 将a&b的值赋值给a。
a<<=n a<<n的值赋值给a。
a>>=n a>>n的值赋值给a。
a^=b 将a^b的值赋值给a。
a|=b a|b的值赋值给a。
a&=b 将a&b的值赋值给a。
a^=b 将a^b的值赋值给a。

a=a+b并不是总和a+=b等价。

byte a = 100,b = 100;
a=a+50;//编译错误,类型不匹配
b+=50;

a+b会将类型提升为范围较大的类型,而a+=b总是保持类型一致。

条件运算符

条件运算符可以进行判断。 条件运算符又叫做三目运算符。

运算符 说明
a?b:c 如果a为true,结果为b;否则为c。

其他运算符

运算符 说明
typeof(a) 获取类型。计算类型a的System.Type
sizeof(a) 计算字节。计算变量或类型a所占字节。
a.b 取成员。取一个结构或类a的成员b。
a->b 取成员。取一个结构或类a指针的成员b,用于不安全代码。
&a 取地址。取变量a的地址,类型是类型a的指针,用于不安全代码。
*a 取值。取指针a指向值,用于不安全代码。
f(a,b,c) 函数调用。调用函数f。
a[n] 取数组元素。获取数组的第n+1个元素的值。
(type)a 强制类型转换。将变量a强制转换为type类型。
o is type 判断类型。判断o是否是type类型。
o as type 转换类型。尝试将o转换为type类型,不能转换为null。
a??b 空合并运算符。如果a为null返回b;否则返回a。
o?.m 空条件运算符(C#6.0)。如果o为null,返回null;否则返回o.m。
o?[x] 空条件运算符(C#6.0)。如果o为null,返回null;否则返回o[x]。
b?==a 空条件赋值运算符(C#8.0)。如果b为null,b=a;否则无操作。
//sizeof
int size = sizeof(int);//4
//typeof
Type t = typeof(int);
//is as
object o = "hello";
bool b = o is string;//true
string s = o as string;//s="hello"
//?. ?[]
List<int> list = new List<int>{1,2,3};

int count = list?.Count;
int item = list?[2];
//??
int? a = null;
int b = 10;
int c = a ?? b;//c=10
//??=
int? a = null;
a ??= 100;//a=100

运算符优先级

优先级决定有多个运算符的表达式的计算顺序。比如乘法优先于加法。

可以通过圆括号()包围表达式更改优先级。

结合性决定运算符的计算方向,是从左向右还是从右向左。只有一元前缀、条件和赋值运算符是从右到左。

名称 运算符 结合性
一元后缀 f(),a[], a->b, a.b ,a++ ,a-- 从左到右
一元前缀 +, -, !, ~, ++a,--a, (type)a,*a, &a, sizeof,typeof 从右到左
乘除 *, / ,% 从左到右
加减 +, - 从左到右
移位 <<, >> 从左到右
关系 <, <=, >, >= 从左到右
相等 ==, != 从左到右
位与 & 从左到右
位异或 ^ 从左到右
位或 | 从左到右
逻辑与 && 从左到右
逻辑或 || 从左到右
条件 ?: 从右到左
赋值 =, +=, -=, *=, /=, %=,>>=, <<= ,&=, ^=,|= 从右到左

在四则运算中,乘除的优先级是高于加减的,C#中也是如此。

static void Main(string[] args){
    Console.WriteLine(9 + 2 *3);//15
}

如果要调整优先级,需要使用括号。

static void Main(string[] args){
    Console.WriteLine((9 + 2) *3);//33
}

优先级