C# 之 常见和不常见的运算符汇总

举报
陈言必行 发表于 2021/08/13 22:17:49 2021/08/13
【摘要】 C# 之 C# 之 常见和不常见的运算符汇总 一,算术运算符二,逻辑运算符三,按位和移位运算符四,关系运算符五,成员访问运算符六,类型测试运算符七,?? 和 ??= 运算符 C# 提供了许多运算符。 其中许多都受到内置类型的支持,可用于对这些类型的值执行基本操作。 一,算术运算符 算术运算符: 一元: ++(增量)、–(减量)、+(加)和 ...

C# 提供了许多运算符。 其中许多都受到内置类型的支持,可用于对这些类型的值执行基本操作。

一,算术运算符

算术运算符:

  • 一元: ++(增量)、–(减量)、+(加)和 -(减)运算符
  • 二元 :*(乘法)、/(除法)、%(余数)、+(加法)和 -(减法)运算符

算术运算符是非常简单和常用的运算符,直接看代码吧;

using System;

namespace CsharpOp
{ class Program { static void Main(string[] args) { Console.WriteLine("C# -- 算数运算符"); int num = 1; // 前缀增量 先计算后执行... Console.WriteLine(++num);   //输出: 2 Console.WriteLine(num); //输出: 2 Console.WriteLine(--num);   //输出: 1 Console.WriteLine(num); //输出: 1  Console.WriteLine("---------------"); // 后缀增量 先执行后计算... Console.WriteLine(num++);   //输出: 1 Console.WriteLine(num); //输出: 2 Console.WriteLine(num--);   //输出: 2 Console.WriteLine(num); //输出: 1 Console.WriteLine("---------------"); int x = 3, y = 4; // 加,减,乘,除,取模 运算 Console.WriteLine(x + y); //输出: 7 Console.WriteLine(x - y); //输出: -1 Console.WriteLine(x * y); //输出: 12 Console.WriteLine(x / y); //输出: 0 Console.WriteLine(x % y); //输出: 3 Console.ReadKey(); } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

运算符优先级和关联性
优先级由高到低的顺序排序:

  • 后缀增量 x++ 和减量 x-- 运算符
  • 前缀增量 ++x 和减量 --x 以及一元 + 和 - 运算符
  • 乘法 *、/ 和 % 运算符
  • 加法 + 和 - 运算符

二元算数运算符是左结合运算符。 也就是说,具有相同优先级的运算符按从左至右的顺序计算。


二,逻辑运算符

逻辑运算:

  • 一元 !(逻辑非)运算符。
    我一般叫它为取反运算符,即计算结果为false,它是true,计算结果为true时它为true。
  bool bo = true;
  Console.WriteLine(!bo); //输出: False
  Console.WriteLine(!(3 == 4)); //输出: True

  
 
  • 1
  • 2
  • 3
  • 二元 &(逻辑与)、|(逻辑或)和 ^(逻辑异或)运算符。 这些运算符始终计算两个操作数。

    • & :运算符计算操作数的逻辑与。 如果 x 和 y 的计算结果都为 true,则 x & y 的结果为 true。 否则,结果为 false。
    • | 运算符计算操作数的逻辑或。 如果 x 或 y 的计算结果为 true,则 x | y 的结果为 true。 否则,结果为 false。
    • ^ 运算符计算操作数的逻辑异或(亦称为“逻辑 XOR”)。 对于 bool 操作数,^ 运算符的计算结果与不等运算符 != 相同,也就是说当X和Y同为true或false时,x^y 结果为 false;当X和Y不相同时,则其结果为true。
 // & 与运算 Console.WriteLine(true & true); //输出: True Console.WriteLine(true & false); //输出: False Console.WriteLine(false & true); //输出: True Console.WriteLine(false & false);   //输出: False // | 或运算 Console.WriteLine(true | true); //输出: True Console.WriteLine(true | false); //输出: True Console.WriteLine(false | true); //输出: True Console.WriteLine(false | false);   //输出: False // ^ 亦或运算 Console.WriteLine(true ^ true); //输出: False Console.WriteLine(true ^ false); //输出: True Console.WriteLine(false ^ true); //输出: True Console.WriteLine(false ^ false);   //输出: False

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 二元 &&(条件逻辑与)和 ||(条件逻辑或)运算符。 这些运算符仅在必要时才计算右侧操作数。
    • &&:也叫短路与,计算结果和 & 的执行结果一致。当x,y都为true时,结果为true,反之,结果为false;当x(左侧结果)为false时,不会计算y,直接得到结果false。
    • ||:也叫短路,计算结果和 | 的执行结果一致。当x,y有一个为true时,结果为true,反之,结果为false;当x(左侧结果)为true时,不会计算y,直接得到结果true。

逻辑运算符优先级
按优先级从高到低的顺序排序:

  • 逻辑非运算符 !
  • 逻辑与运算符 &
  • 逻辑异或运算符 ^
  • 逻辑或运算符 |
  • 条件逻辑与运算符 &&
  • 条件逻辑或运算符 ||

三,按位和移位运算符

  • 一元 ~(按位求补)运算符:即二进制下0和1的相互变换;
    4的二进制是:00000100
    则按位求补 : 11111011
 byte a = 4;  // 4的二进制: 00000100
 byte b = (byte)~a;
 Console.WriteLine(a);   // 输出: 4
 Console.WriteLine(b);   // 输出: 251
 Console.WriteLine(Convert.ToString(a, toBase: 2));// 输出: 100
 Console.WriteLine(Convert.ToString(b, toBase: 2));// 输出: 11111011

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 二进制 <<(向左移位)和 >>(向右移位)移位运算符;
    向左移位举例:
    4的二进制是 :00000100
    4左移两位是 :000100__ (下划线两位用0补位)
    左移两位结果:00010000
    向右移位同理
    4的二进制是 :00000100
    4右移两位是 :000000100 (多出来的直接舍弃)
    右移两位结果:00000001

    上面描述了二进制计算,那么对于十进制来说,左移几位就是乘以2的几次幂。(左移一位:2,两位:22,三位222);同理可知,右移时就是除以2的几次幂。

    因为位移比乘除速度快,对效率要求高,而且满足 2 的幂次方的乘除运方,可以采用位移的方式进行。

  // 左移两位
  byte a = 4;  // 4的二进制: 00000100
  byte b = (byte)(a << 2);
  Console.WriteLine(a);   // 输出: 4
  Console.WriteLine(b);   // 输出: 16
  Console.WriteLine(Convert.ToString(a, toBase: 2));// 输出: 100
  Console.WriteLine(Convert.ToString(b, toBase: 2));// 输出: 10000 // 右移两位
  byte c = 4;  // 4的二进制: 00000100
  byte d = (byte)(a >> 2);
  Console.WriteLine(c);   // 输出: 4
  Console.WriteLine(d);   // 输出: 1
  Console.WriteLine(Convert.ToString(c, toBase: 2));// 输出: 100
  Console.WriteLine(Convert.ToString(d, toBase: 2));// 输出: 1

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 二进制 &(逻辑 AND)、|(逻辑 OR)和 ^(逻辑异或)运算符

    • &:与运算,从第一个非0位开始计算,对应位两个都是1则结果为1,否则结果为0。举例:
      4: 00000100
      5: 00000101
      ---------------------
      4: 00000100

    • |:或运算,从第一个非0位开始计算,对应位有一个是1则结果为1,否则结果为0。举例:
      4: 00000100
      5: 00000101
      ---------------------
      5: 00000101

    • ^:亦或运算,从第一个非0位开始计算,对应位两个不同则结果为1,否则结果为0。举例:
      4: 00000100
      5: 00000101
      ---------------------
      1: 00000001

   byte x = 4; // 4的二进制: 00000100 byte y = 5; // 5的二进制: 00000101 // & 与运算 byte z = (byte)(x & y); Console.WriteLine(z);   // 输出: 4 Console.WriteLine(Convert.ToString(z, toBase: 2));// 输出: 100 // | 或运算 z = (byte)(x | y); Console.WriteLine(c);   // 输出: 5 Console.WriteLine(Convert.ToString(z, toBase: 2));// 输出: 101 // ^ 亦或运算 z = (byte)(x ^ y); Console.WriteLine(c);   // 输出: 5 Console.WriteLine(Convert.ToString(z, toBase: 2));// 输出: 1

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

四,关系运算符

  • ==(等于)、!=(不等于)、 <(小于)、>(大于)、<=(小于或等于)和 >=(大于或等于)关系运算符比较其操作数。

char 类型支持关系运算符。 在使用 char 操作数时,将比较对应的字符代码。

枚举类型也支持比较运算符。 对于相同枚举类型的操作数,基础整数类型的相应值会进行比较。

运算符可重载性:
用户定义类型可以重载 ==、!=、<、>、<= 和 >= 运算符。

如果某类型重载/ == 或 !=运算符之一,它必须同时重载 /== 和!=。
如果某类型重载 < 或 > 运算符之一,它必须同时重载 < 和 >。
如果某类型重载 <= 或 >= 运算符之一,它必须同时重载 <= 和 >=。


五,成员访问运算符

访问类型成员时,可以使用以下运算符和表达式:

  • .(成员访问):用于访问命名空间或类型的成员
double pai = System.Math.PI;

  
 
  • 1
  • [](数组元素或索引器访问):用于访问数组元素或类型索引器
 int[] arr = new int[3] { 1, 2, 3 };
 Console.WriteLine(arr[1]); // 输出: 2

  
 
  • 1
  • 2
  • ?. 和 ?[](null 条件运算符):仅当操作数为非 null 时才用于执行成员或元素访问运算

以?[]访问为例:

 var arr = new List<int[]>() { new int[] { 1, 2, 3 }, null };
 Console.WriteLine(arr[0][1]); // 输出: 2
 Console.WriteLine(arr?[0][1]);   // 输出: 2 Console.WriteLine(arr[1]); // 输出: 
 Console.WriteLine(arr?[1]?[0]);  // 输出: 
 //Console.WriteLine(arr?[1][0]); // 报错: System.NullReferenceException
 // 等价于
 if (arr != null)
 { Console.WriteLine(arr[1]); if (arr[1] != null) { Console.WriteLine(arr[1][0]); }
 }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里可以理解为:问号再谁后面就判断谁是否为null,为null则不执行后面操作。

  • ^(从末尾开始索引):指示元素位置来自序列的末尾。
    a[^]就是倒数第个的意思,使用时主要下别越界了。
 int[] array = new int[5] { 1, 2, 3, 4, 5 };
 Console.WriteLine(array[1]);  // 输出: 2
 Console.WriteLine(array[^1]); // 输出: 5
 //Console.WriteLine(array[^0]); // 报错:数组索引越界,System.IndexOutOfRangeException

  
 
  • 1
  • 2
  • 3
  • 4
  • . .(范围):指定可用于获取一系列序列元素的索引范围;
    写法为[startIndex. .endIndex) --> [开始索引. .结束索引) 是一个左闭右开区间;若开始索引不写,则默认0开始;若结束索引不写,则默认取到数组结束;若都不写,则就是整个数组。
    动态写法(. . ^):范围结束还可以这样定义,[startIndex. .^Index)–> 解释为从第startIndex个元素索引开始倒数第Index个元素结束。
 int[] array = new int[5] { 1, 2, 3, 4, 5 };
 Console.WriteLine();
 for (int i = 0; i < array[1..3].Length; i++)
 { Console.Write(array[1..3][i] + " "); //输出2 3
 }
 Console.WriteLine();
 // 开始索引不写,默认从0索引开始
 for (int i = 0; i < array[..3].Length; i++)
 { Console.Write(array[..3][i] + " "); //输出2 3 4
 }
 Console.WriteLine();
 // 结束索引不写,默认到数组长度结束
 for (int i = 0; i < array[1..].Length; i++)
 { Console.Write(array[1..][i] + " "); //输出2 3 4 5
 }
 Console.WriteLine();
 // 从1索引到倒数第二个元素的索引的区间。
 int[] indexArr = array[1..^2];
 for (int i = 0; i < indexArr.Length; i++)
 { Console.Write(indexArr[i] + " "); //输出2 3
 }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

六,类型测试运算符

  • is 运算符:用于检查表达式的运行时类型是否与给定类型兼容
    X is Y: 若X可以通过引用转换,装箱,拆箱来转换为类型Y,则X is Y返回True,否则,则返回False;is 运算符不会考虑用户定义的转换。
 // 基类 public class BaseClass { }
	// 派生类 public class DerivedClass : BaseClass { } class Program { static void Main(string[] args) { var b = new BaseClass(); Console.WriteLine(b is BaseClass); // 输出: True Console.WriteLine(b is DerivedClass); // 输出: False var d = new DerivedClass(); Console.WriteLine(d is BaseClass); // 输出: True Console.WriteLine(d is DerivedClass); // 输出: True Console.ReadKey(); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • as 运算符:用于将表达式显式转换为给定类型(如果其运行时类型与该类型兼容)。 如果无法进行转换,则 as 运算符返回 null。 与强制转换表达式 不同,as 运算符永远不会引发异常。
 // 基类
 	public class BaseClass { }
	// 派生类 public class DerivedClass : BaseClass { } class Program { static void Main(string[] args) { BaseClass b = new BaseClass(); // as DerivedClass d = b as DerivedClass; // 强制转换 DerivedClass d1 = (DerivedClass) b; Console.ReadKey(); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 运算符:用于获取某个类型的 System.Type 实例
	// 基类
 	public class BaseClass { }
	// 派生类 public class DerivedClass : BaseClass { } class Program { static void Main(string[] args) { var d = new DerivedClass(); Console.WriteLine(d is BaseClass); // 输出: True Console.WriteLine(d.GetType() == typeof(BaseClass)); // 输出: True Console.WriteLine(d is DerivedClass);   // 输出: True Console.WriteLine(d.GetType() == typeof(DerivedClass)); // 输出: True Console.ReadKey(); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

七,?? 和 ??= 运算符

  • 如果左操作数的值不为 null,则 null 合并运算符 ?? 返回该值;否则,它会计算右操作数并返回其结果。 如果左操作数的计算结果为非 null,则 ?? 运算符不会计算其右操作数。

??举例:

 int? a = null;
 int b = a ?? -1;
 Console.WriteLine(b);  // output: -1 // 等价于 三目运算符
 b = (a == null ? (int)a : -1);

 // 等价于 if else
 if (a == null) b = -1;
 else b = (int)a;

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

??=举例:变量!=null,则被表达式赋值

variable ??= expression;
//等价于
if (variable is null)
{ variable = expression;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

文章来源: czhenya.blog.csdn.net,作者:陈言必行,版权归原作者所有,如需转载,请联系作者。

原文链接:czhenya.blog.csdn.net/article/details/109230462

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。