C# 表达式和运算符(表达式和字面量)
表达式
本章将定义表达式,并描述C#提供的运算符,还将解释如何定义C#运算符以使用用户定义
的类。
运算符是一个符号,它表示返回单个结果的操作。操作数(operand)是指作为运算符输入
的数据元素。运算符会:
- 将操作数作为输入;
- 执行某个操作;
- 基于该操作返回一个值。
表达式是运算符和操作数的宇符串。C#运算符有一个、两个或三个操作数。可以作为操作数
的结构有:
- 字面量;
- 常量;
- 变量;
- 方法调用;
- 元素访问器,如数组访问器和索引器;
- 其他表达式。
可以使用运算符组合表达式以创建更复杂的表达式,如下面的表达式所示,它有3个运算符
和4个操作数。
表达式求值()是将每个运算符以适当的顺序应用到它的操作数以产生一个值的过程。
- 值被返回到表达式求值的位置。在那里,它可能是一个封闭的表达式的操作数。
- 除了返回值以外,一些表达式还有副作用,比如在内存中设置一个值。
字面量
字面量(literal)是源代码中键入的数字或字符串,表示一个指定类型的明确的、固定的值。
例如,下面的代码展示了6个类型的字面量。请注意double字面量和float字面量的区别。
static void Main()
{Console.WriteLine("{0}",1024); //整数字母量Console.WriteLine("{0}",3.1415); //双精度型字面量Console.WriteLine("{0}",3.1416F); //浮点型字面量Cosnole.WriteLine("{0}",true); //布尔型字面量Console.WriteLine("{0},'X"); //字符型字面量Console.WriteLine("{0}","Hi there");//字符串字面量
因为字面量是写进源代码的,所以它们的值必须在编译时可知。几个预定义类型有自己的字
面量形式。
- bool有两个字面量:true和false。注意,像所有C#关键字一样,它们是小写的。
- 对于引用类型变量,字面量null表示变量没有指向内存中的数据。
整数字面量
整数字面量是最常用的字面量。它们被书写为十进制数字序列,并且:
- 没有小数点“
- 带有可选的后缀,指明整数的类型。
例如,下面几行展示了4个字面量,都是整数236。依据它们的后缀,每个常数都被编译器
解释为不同的整数类型。
236 //整型
236L //长整型
236U //无符号整型
236UL //无符号长整型
整数类型字面量还可以写成十六进制(hex)形式。数字必须是十六进制数(从0到F),而
且字符串必须以0x或0X开始(数字0,字母x)。
整数类型字面量的第三种格式是二进制记法。所有的数字必须是0或者1,并且必须以0b
或者0B开始(数字0,字母b)。
说明 只有整数类型字面量可以用十六进制或二进制格式表示。十六进制和二进制记法用前缀
指定,而实际的数据类型用后缀指定。
整数字面量格式的形式如图9- 1所示。方括号内带有名称的元素是可选的。
整数字面量的后缀见表9-1。对于已知的后缀,编译器会把数字字符串解释为能表示该值而
不丢失数据的相应类型中最小的类型。
例如,常数236和5000000000都没有后缀。因为236可以用32比特表示,所以它会被编译
器解释为一个int。然而第二个数不适合32比特,所以编译器会把它表示为一个long。
在之前的例子中,你很难知道数字5000000000到底有多大幸运的是,现在你可以在数字
字面量中插入分隔符了,这样更容易解析。
Console.WriteLine("5_000_000_000 is much easier to read than 5000000000");
实数字面量
C#有三种实数数据类型:float、double和decimal。它们分别对应32位、64位和128位精
度。这三种都是浮点数据类型,这意味着它们在内部由两个部分组成,其中一部分是实际的数字,
另一部分则是表示小数点位置的指数。在实际使用中,double是到目前为止最常用的实数数据类型。
实数字面量的组成如下:
- 十进制数字;
- 一个可选的小数点;
- 一个可选的指数部分;
- 一个可选的后缀。
例如,下面的代码展示了实数类型字面量的不同格式:
float f1=236f;
double d1=236.714;
double d3=.35192;
double d3=6.338e-26;
实数字面量的有效格式如图9-2所示。方括号内带有名称的元素是可选的。实数后缀和它们
的含义如表9-2所示。
说明 无后的实数字面量是double类型,不是类型!
字符字面量
字符字面量由两个单引号内的字符组成。字符字面量用于表示单个字符(a)、非打印字符(\n)
(换行符)或者执行特殊任务的字符,例如转义(\)。尽管可能需要多个字符来表示一个字符字
面量,但每个字符字面量只表示一个字符。要引用多个字符,必须使用字符串字面量,如下一节
所述。
字符字面量可以是下面任意一种:单个字符、一个简单转义序列、一个十六进制转义序列或
一个IJnicode转义序列。关于字符字面量需要知道以下几点。
- 字符字面量的类型是char。
- 简单转义序列是一个反斜杠后面跟着单个字符。
- 十六进制转义序列是一个反斜杠后面跟着一个大写或小写的x,再跟着4个十六进制数字。
- Umcode转义序列是一个反斜杠后面跟着一个大写或小写的u,再跟着4个十六进制数字
例如,下面的代码展示了字符字面量的不同格式:
char c1='d'; //单个字符
char c2='\n'; //简单转义系列
char c3='\x0061';//十六进制转义系列
char c4='\u005a';//Unicode转义系列
一些重要的特殊字符和它们的编码如表9-3所示。
字符串字面量
字符串字面量使用双引号标记,不同于字符字面量使用单引号。有两种字符串字面量类型:
- 常规字符串字面量;
- 逐字字符串字面量。
常规字符串字面量由双弓枵内的字符序列组成。常规字符串字面量可以包含:
- 字符;
- 简单转义序列;
- 十六进制和Umcode转义序列。
例如:
string st1="Hi there!";
string st2="Val1\t5,Val2\t10";
string st3="Add\x000ASome\u0007Interest";
逐字字符串字面量的书写如同常规字符串字面量,但它以一个@字符为前缀。逐字字符串字
面量有以下重要特征。
- 逐字字符串字面量与常规字符串字面量的区别在于字符串中的转义序列不会被求值。在
双引号中间的所有内容,包括通常被认为是转义序列的内容,都被严格按字符串中列出
的那样打印。 - 逐字字符串字面量的唯一例外是相邻的双引号组,它们被解释为单个双引号字符。
例如,下面的代码比较了常规字符串字面量和逐字字符串字面量:
说明 编译器让相同的字符串字面量共享堆中同一内存位置以节约内存。