|
|
51CTO旗下网站
|
|
移动端

2.1.4 字面量

《C# 6.0本质论(第5版)》第2章数据类型,本章将探讨这些数据类型,更深入地研究字符串类型,并引入数组的概念。本节为大家介绍字面量。

作者:周靖/庞燕 译来源:人民邮电出版社|2017-07-21 15:23

2.1.4 字面量

字面量或字面值(literal value)表示源代码中的固定值。例如,假定希望用System.Console.WriteLine()输出整数值42和double值1.618 034(黄金分割比例),可以使用如代码清单2-1所示的代码。

代码清单2-1 指定字面量

  1. System.Console.WriteLine(42);  
  2. System.Console.WriteLine(1.618034); 

输出2-1展示了代码清单2-1的结果。

输出2-1

  1. 42  
  2. 1.618034 

初学者主题:在硬编码值的时候要慎重

直接将值放到源代码中称为硬编码(hardcoding),因为以后若是更改了值,就必须重新编译代码。因为可能会为维护带来不便,所以开发者在硬编码值的时候必须慎重。例如,可以考虑从一个外部来源获取值,比如从一个配置文件中获取。这样,以后需要修改值的时候,就不需要重新编译代码了。

默认情况下,输入带小数点的字面量,编译器会自动把它解释成double类型。相反,整数值(没有小数点)通常默认为int,但前提是该值不要太大,以至于无法用int来存储。如果值太大,编译器会把它解释成long。此外,C#编译器允许向非int数值类型赋值,前提是字面量对于目标数据类型来说是合法的。例如,short s = 42和byte b =77都是允许的。但这一点仅对字面量成立。如果不使用额外的类型转换语法,b = s就是非法的,具体请参见2.6节。

2.1节讲过,C#有许多数值类型。在代码清单2-2中,一个字面量被直接放到C#代码中。由于带小数点的值默认为double类型,所以如输出2-2所示,结果是1.61803398874989(最后一个数字5丢失了),这符合我们预期的double值的精度。

代码清单2-2 指定一个double字面量

  1. System.Console.WriteLine(1.618033988749895); 

输出2-2

  1. 1.61803398874989 

要显示具有完整精度的数字,必须将字面量显式声明为decimal类型,这是通过追加一个M(或者m)后缀来实现的,如代码清单2-3和输出2-3所示。

代码清单2-3 指定一个decimal字面量

  1. System.Console.WriteLine(1.618033988749895M); 

输出2-3

  1. 1.618033988749895 

现在,代码清单2-3的输出与预期的结果相同:1.618033988749895。注意,d表示double,之所以用m表示decimal,是因为这种数据类型经常用于货币(monetary)计算。

还可以使用F和D作为后缀,将字面量显式声明为float或者double。对于整数数据类型,相应的后缀是U、L、LU和UL。整数字面量的类型是像下面这样确定的。

没有后缀的数值字面量按照以下顺序,解析成能够存储该值的第一种数据类型:int、uint、long、ulong。

具有后缀U的数值字面量按照以下顺序,解析成能够存储该值的第一种数据类型:uint、ulong。

具有后缀L的数值字面量按照以下顺序,解析成能够存储该值的第一种数据类型:long、ulong。

如果数值字面量的后缀是UL或LU,则解析成ulong类型。

注意,字面量的后缀不区分大小写。但对于long,一般推荐使用大写字母L,因为小写字母l和数字1不好区分。

某些时候应考虑使用指数记数法,避免在小数点前后写许多个0。为了使用指数记数法,需要使用e或E中缀,在中缀字母后面添加正整数或者负整数,并在字面量的最后添加恰当的数据类型后缀。例如,可以将阿伏伽德罗常数作为float输出,如代码清单2-4和输出2-4所示。

代码清单2-4 指数记数法

  1. System.Console.WriteLine(6.023E23F); 

输出2-4

  1. 6.023E+23 

规范

要使用大写的字面量后缀(如1.618033988749895M)。

初学者主题:十六进制记数法

我们一般使用的都是十进制记数法。换言之,每位数字都可以使用10个符号(0~9)表示。除此之外,还可以使用十六进制记数法。换言之,每位数字都可以使用16个符号表示:0~9,A~F(也可以用小写)。所以,0x000A对应于十进制值10,而0x002A对应于十进制值42。实际的数是相同的。十六进制和十进制的相互转换不会改变数本身,改变的只是数的表示形式。

每位十六进制数字都是4个二进制位,一个字节可以表示两位十六进制数字。

前面讨论数值字面量的时候只使用了十进制值。事实上,C#还允许指定十六进制值。

为了指定十六进制值,要为值附加0x前缀,再添加希望使用的任何十六进制数字,如代码清单2-5所示。

代码清单2-5 十六进制字面量

  1. // Display the value 42 using a hexadecimal literal.  
  2. System.Console.WriteLine(0x002A); 

输出2-5展示了结果。

输出2-5

  1. 42 

注意,代码输出的仍然是42,而不是0x002A。

高级主题:将数格式化成十六进制

要以十六进制形式输出一个数值,必须使用x或X数值格式说明符。大小写决定了十六进制字母的大小写。代码清单2-6展示了一个例子。

代码清单2-6 十六进制格式说明符的例子

  1. // Displays "0x2A"  
  2. System.Console.WriteLine($"0x{42:X}"); 

输出2-6展示了结果。

输出2-6

  1. 0x2A 

注意,数值字面量(42)可以随意采用十进制或十六进制形式,结果是一样的。为了得到十六进制格式,我们使用了格式说明符——用冒号分割的字符串插值表达式。

高级主题:round-trip格式化

默认情况下,执行System.Console.WriteLine(1.618033988749895);语句会显示1.61803398874989,最后一个数位会被丢弃。为了更准确地支持与double值对应的字符串形式,我们可以使用格式字符串和round-trip格式说明符R(或者r)进行转换。例如,string.Format("{0:R}", 1.618033988749895)会返回结果1.618033988749895。

将round-trip格式说明符返回的字符串转换回数值肯定能获得原始值。在代码清单2-7中,如果没有使用round-trip格式,两个数就不相等了。

代码清单2-7 使用R格式说明符进行格式化

  1. // ...  
  2. const double number = 1.618033988749895;  
  3. double result;  
  4. string text;  
  5. text = $"{number)";  
  6. result = double.Parse(text);  
  7. System.Console.WriteLine($"{result == number}: result == number");  
  8. text = string.Format("{0:R}", number);  
  9. result = double.Parse(text);  
  10. System.Console.WriteLine($"{result == number}: result == number");  
  11. // ... 

输出2-7显示了结果。

输出2-7

  1. False: result == number  
  2. True: result == number 

第一次为text赋值没有使用R格式说明符,所以double.Parse(text)的返回值与原始数值不同。相反,在使用了R格式说明符之后,double.Parse(text)返回的就是原始值。

对于不熟悉基于C语言的==语法的读者来说,只需要知道result == number在result等于number的前提下会返回true,result != number则相反。下一章将讨论赋值和相等操作符。

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:342347198

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

Microsoft SQL Server 2005技术内幕:存储引擎

本书是Inside Microsoft SQL Server 2000的作者Kalen Delaney的又一经典著作,是Inside Microsoft SQL Server 2005系列四本著作中的一本。...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊