C# 之 常见和不常见的运算符汇总
发布日期:2021-06-29 19:09:56 浏览次数:2 分类:技术文章

本文共 9122 字,大约阅读时间需要 30 分钟。

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(); } }}

运算符优先级和关联性

优先级由高到低的顺序排序:

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

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


二,逻辑运算符

逻辑运算:

  • 一元 !(逻辑非)运算符。
    我一般叫它为取反运算符,即计算结果为false,它是true,计算结果为true时它为true。
bool bo = true;  Console.WriteLine(!bo);       //输出: False  Console.WriteLine(!(3 == 4)); //输出: True
  • 二元 &(逻辑与)、|(逻辑或)和 ^(逻辑异或)运算符。 这些运算符始终计算两个操作数。

    • & :运算符计算操作数的逻辑与。 如果 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
  • 二元 &&(条件逻辑与)和 ||(条件逻辑或)运算符。 这些运算符仅在必要时才计算右侧操作数。
    • &&:也叫短路与,计算结果和 & 的执行结果一致。当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
  • 二进制 <<(向左移位)和 >>(向右移位)移位运算符;

    向左移位举例:
    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
  • 二进制 &(逻辑 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

四,关系运算符

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

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

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

运算符可重载性:

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

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

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


五,成员访问运算符

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

  • .(成员访问):用于访问命名空间或类型的成员
double pai = System.Math.PI;
  • [](数组元素或索引器访问):用于访问数组元素或类型索引器
int[] arr = new int[3] {
1, 2, 3 }; Console.WriteLine(arr[1]); // 输出: 2
  • ?. 和 ?[](null 条件运算符):仅当操作数为非 null 时才用于执行成员或元素访问运算

以?[]访问为例:

var arr = new List
() {
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]); } }

在这里可以理解为:问号再谁后面就判断谁是否为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
  • . .(范围):指定可用于获取一系列序列元素的索引范围;
    写法为[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 }

六,类型测试运算符

  • 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(); } }
  • 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(); } }
  • 运算符:用于获取某个类型的 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(); } }

七,?? 和 ??= 运算符

  • 如果左操作数的值不为 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;

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

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

转载地址:https://czhenya.blog.csdn.net/article/details/109230462 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:程序人生 -- 写给亲爱的自己 →→ 也写给陌生的你!
下一篇:Unity 之 UGUI RectTransform矩形变换组件详解

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月12日 23时07分07秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章