C# 图解教程 第5版 —— 第9章 表达式和运算符

9.1 表达式(*)

9.2 字面量

9.2.1 整数字面量

  • 十六进制整数:以 0x 或 0X 开始。
  • 二进制整数:以 0b 或 0B 开始。
image-20231026194657016
图9.1 整数字面量的格式

​ 十六进制和二进制记法用前缀指定,实际的数据类型用后缀指定。

表9.1 整数字面量的后缀
image-20231026194806035

​ 可以在数字字面量中插入分隔符以看清数字大小:

Console.WriteLine("5_000_000_000 is much easier to read than 5000000000");

9.2.2 实数字面量

image-20231026195103342
图9.2 实数字面量的格式
表9.2 实数字面量的后缀
image-20231026195144225

9.2.3 字符字面量

​ 字符字面量包括:

  • 单个字符:char。
  • 简单转义序列:反斜杠 + 单个字符。
  • 十六进制转义序列:反斜杠 + x/X + 4 位十六进制数字。
  • Unicode 转义序列:反斜杠 + u/U + 4 位十六进制数字。
char c1 = 'd';      // 单个字符
char c2 = '\n';     // 简单转义序列
char c3 = '\x0061'; // 十六进制转义序列
char c4 = '\u005a'; // Unicode 转义序列

9.2.4 字符串字面量

​ 字符串字面量类型包括两种:

  1. 常规字符串字面量。

    可以包含上述 4 种字符字面量。

  2. 逐字字符串字面量。

    • 以 @ 字符为前缀。
    • 字符串中的转义序列不会被求值。
image-20231026200219671 image-20231026200249679 image-20231026200307102
图9.3 逐字字符串字面量示例

​ 说明:编译器让相同的字符串字面量共享堆中的同一内存位置以节约内存。

9.3 求值顺序

9.3.1 优先级

表9.3 运算符优先级:从高到低
image-20231026200928386

9.3.2 结合性

表9.4 运算符结合性总结
image-20231026201032831

9.4 简单算术运算符

表9.5 简单算术运算符
image-20231026201130164

9.5 求余运算符

表9.6 求余运算符
image-20231026201232186

​ 求余运算符还可以用于实数以得到实余数:

image-20231026201344103 image-20231026201351887
图9.4 求余运算符计算实余数

9.6 关系比较运算符和相等比较运算符

image-20231026201459909
图9.5 关系比较运算符和相等比较运算符

比较操作和相等性操作

  • **浅比较:**对于大多数引用类型来说,比较相等性时,只比较它们的引用。
    • 如果指向相同的引用对象,则为 true;否则为 false。
    • 因此,若两个不同的引用指向的对象值内容相同,也返回 false。
image-20231026201825975
图9.6 比较引用类型的相等性
  • **深比较:**string 类型对象不使用浅比较,而是比较字符值是否相等。
    • 如果两个字符串有相同的长度和内容(区分大小写),则为 true;否则为 false;
    • 即使两个字符串占用不同的内存区域,如果值相同,也会返回 true。

​ 委托也是引用类型,也使用深比较。

9.7 递增运算符和递减运算符(*)

9.8 条件逻辑运算符(*)

9.9 按位逻辑运算符(*)

9.10 移位运算符(*)

9.11 赋值运算符(*)

9.12 条件运算符(*)

9.13 一元算术运算符(*)

9.14 用户定义的类型转换

隐式转换

​ 使用 public 和 static 修饰符,implicit 表明为隐式转换:

image-20231026203218549
图9.7 定义隐式转换

显示转换

​ 和隐式转换一样,但使用 explicit 而不是 implicit。图 9.8 使用箭头标出了不同之处:

image-20231026203349461
图9.8 定义显示转换

9.15 运算符重载

  • 运算符重载只能用于类和结构。
  • 使用 operator x 重载运算符 x。
    • 一元运算符重载方法只带一个单独的 class 或 struct 参数。
    • 二元运算符重载方法带两个参数,至少有一个需要为 class 或 struct。
image-20231026203647301
图9.9 一元/二元运算符重载区别

​ 运算符重载的说明:

  • 必须同时使用 public 和 static。
  • 运算符方法必须是要操作的类或结构的成员。
image-20231026203844526
图9.10 运算符重载示例

9.15.1 运算符重载的示例(*)

9.15.2 运算符重载的限制

​ 可重载的一元运算符:+、-、!、~、++、–、true、false。

​ 可重载的二元运算符:+、-、*、/、%、&、|、^、<<、>>、==、!=、>、<、>=、<=。

​ 运算符重载不能:

  • 创建新运算符。
  • 改变运算符的语法。
  • 重新定义运算符如何处理预定义类型。
  • 改变运算符的优先级或结合性。

​ 对于 ++ 和 – 运算符,重载只能提供一个方法体。当对对象使用前置或后置运算时,编译器将做出不同操作的处理:

  • 前置运算:
    • 直接在对象上执行重载代码。
    • 返回对象。
  • 后置运算:
    • 首先浅拷贝对象。
    • 在拷贝对象上执行重载代码。
    • 返回拷贝对象。

​ 因此,对引用类型(class)使用后置操作,返回结果将和前置操作一样,因为浅拷贝引用指向的对象就是原对象。但是对值类型(struct)使用后置操作不会出现这种现象。

​ 最好对 struct 使用后置递增 / 递减,而不是 class。

9.16 typeof 运算符

​ typeof 运算符返回参数对应的 System.Type 对象。

9.17 nameof 运算符

​ 即使参数使用完全限定名,nameof 运算符也只返回其参数的非限定名称。

image-20231026233007302
图9.11 nameof 运算符示例

9.18 其他运算符

  • 空接合运算符
  • 空条件运算符
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔗理苦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值