首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

2.4  预定义数据类型

前面介绍了如何声明变量和常量,下面要详细讨论C#中可用的数据类型。与其他语言相比,C#对其可用的类型及其定义进行了过分的修饰。

2.4.1  值类型和引用类型

在开始介绍C#中的数据类型之前,理解C#把数据类型分为两种是非常重要的:

       值类型

       引用类型

下面几节将详细介绍值类型和引用类型的语法。从概念上看,其区别是值类型直接存储其值,而引用类型存储对值的引用。与其他语言相比,C#中的值类型基本上等价于VBC++中的简单类型(整型、浮点型,但没有指针或引用)。引用类型与VB中的引用类型相同,与C++中通过指针访问的类型类似。

这两种类型存储在内存的不同地方:值类型存储在堆栈中,而引用类型存储在托管堆上。注意区分某个类型是值类型还是引用类型,因为这种存储位置的不同会有不同的影响。例如,int是值类型,这表示下面的语句会在内存的两个地方存储值20

// i and j are both of type int

i = 20;

j = i;

但考虑下面的代码。这段代码假定已经定义了一个类VectorVector是一个引用类型,它有一个int类型的成员变量Value

Vector x, y

x = new Vector ();

x.Value = 30;   // Value is a field defined in Vector class

y = x;

Console.WriteLine(y.Value);

y.Value = 50;

Console.WriteLine(x.Value);

要理解的重要一点是在执行这段代码后,只有一个Vector对象。xy都指向包含该对象的内存位置。因为xy是引用类型的变量,声明这两个变量只是保留了一个引用——而不会实例化给定类型的对象。这与在C++中声明指针和VB中的对象引用是相同的——在C++VB中,都不会创建对象。要创建对象,就必须使用new关键字,如上所示。因为xy引用同一个对象,所以对x的修改会影响y,反之亦然。因此上面的代码会显示3050

注意:

C++开发人员应注意,这个语法类似于引用,而不是指针。我们使用.(句点)符号,而不是->来访问对象成员。在语法上,C#引用看起来更类似于C++引用变量。但是,抛开表面的语法,实际上它类似于C++指针。

如果变量是一个引用,就可以把其值设置为null,表示它不引用任何对象:

y = null;

这类似于Java中把引用设置为nullC++中把指针设置为NULL,或VB中把对象引用设置为Nothing。如果将引用设置为null,显然就不可能对它调用任何非静态的成员函数或字段,这么做会在运行时抛出一个异常。

在像C++这样的语言中,开发人员可以选择是直接访问某个给定的值,还是通过指针来访问。VB的限制更多:COM对象是引用类型,简单类型总是值类型。C#在这方面类似于VB:变量是值还是引用仅取决于其数据类型,所以,int总是值类型。不能把int变量声明为引用(在第5章介绍装箱时,可以在类型为object的引用中封装值类型)

C#中,基本数据类型如boollong都是值类型。如果声明一个bool变量,并给它赋予另一个bool变量的值,在内存中就会有两个bool值。如果以后修改第一个bool变量的值,第二个bool变量的值也不会改变。这些类型是通过值来复制的。

相反,大多数更复杂的C#数据类型,包括我们自己声明的类都是引用类型。它们分配在堆中,其生存期可以跨多个函数调用,可以通过一个或几个别名来访问。CLR执行一种精细的算法,来跟踪哪些引用变量仍是可以访问的,哪些引用变量已经不能访问了。CLR会定期进行清理,删除不能访问的对象,把它们占用的内存返回给操作系统。这是通过垃圾收集器实现的。

把基本类型(intbool)规定为值类型,而把包含许多字段的较大类型(通常在有类的情况下)规定为引用类型,C#设计这种方式的原因是可以得到最佳性能。如果要把自己的类型定义为值类型,就应把它声明为一个结构。

2.4.2  CTS类型

如第1章所述,C#认可的基本预定义类型并没有内置于语言中,而是内置于.NET Framework中。例如,在C#中声明一个int类型的数据时,声明的实际上是.NET结构System.Int32的一个实例。这听起来似乎很深奥,但其意义深远:这表示在语法上,可以把所有的基本数据类型看作是支持某些方法的类。例如,要把int i转换为string,可以编写下面的代码:

string s = i.ToString();

应强调的是,在这种便利语法的背后,类型实际上仍存储为基本类型。基本类型在概念上用.NET结构表示,所以肯定没有性能损失。

下面看看C#中定义的类型。我们将列出每个类型,以及它们的定义和对应.NET类型(CTS 类型)的名称。C#15个预定义类型,其中13个是值类型,2个是引用类型(stringobject)

2.4.3  预定义的值类型

内置的值类型表示基本数据类型,例如整型和浮点类型、字符类型和bool类型。

1. 整型

C#支持8个预定义整数类型,如表2-1所示。

  2-1

   

CTS

   

   

sbyte

System.SByte

8位有符号的整数

–128 127 (–2727–1)

short

System.Int16

16位有符号的整数

–32 768 32 767 (–215215–1)

int

System.Int32

32位有符号的整数

–2 147 483 648 2 147 483 647(–231231–1)

long

System.Int64

64位有符号的整数

–9 223 372 036 854 775 8089 223 372 036 854 775 807(–263263–1)

byte

System.Byte

8位无符号的整数

0255(028–1)

ushort

System.Uint16

16位无符号的整数

065535(0216–1)

uint

System.Uint32

32位无符号的整数

04 294 967 295(0232–1)

ulong

System.Uint64

64位无符号的整数

018 446 744 073 709 551 615(0264–1)

 

Windows的将来版本将支持64位处理器,可以把更大的数据块移入移出内存,获得更快的处理速度。因此,C#支持864位的有符号和无符号的整数。

当然,VB开发人员会发现有许多类型名称是新的。C++Java开发人员应注意:一些C#类型名称与C++Java类型一致,但类型有不同的定义。例如,在C#中,int总是32位带符号的整数,而在C++中,int是带符号的整数,但其位数取决于平台(Windows上是32)。在C#中,所有的数据类型都以与平台无关的方式定义,以备将来C#.NET迁移到其他平台上。

byte0~255(包括255)的标准8位类型。注意,在强调类型的安全性时,C#认为byte类型和char类型完全不同,它们之间的编程转换必须显式写出。还要注意,与整数中的其他类型不同,byte类型在默认状态下是无符号的,其有符号的版本有一个特殊的名称sbyte

.NET中,short不再很短,现在它有16位,Int类型更长,有32位。 long类型最长,有64。所有整数类型的变量都能赋予10进制或16进制的值,后者需要0x前缀:

long x = 0x12ab;

如果对一个整数是intuintlong或是ulong没有任何显式的声明则该变量默认为int类型。为了把键入的值指定为其他整数类型,可以在数字后面加上如下字符:

uint ui = 1234U;

long l = 1234L;

ulong ul = 1234UL;

也可以使用小写字母ul,但后者会与整数1混淆。

2. 浮点类型

C#提供了许多整型数据类型,也支持浮点类型,如表2-2所示。CC++程序员很熟悉     它们。

 

 

  2-2

名称

CTS类型

 

范围 (大致)

float

System.Single

32位单精度浮点数

7

±1.5 × 10-45 ±3.4 × 1038

double

System.Double

64位双精度浮点数

15/16

±5.0 × 10-324 ±1.7 × 10308

 

float数据类型用于较小的浮点数,因为它要求的精度较低。double数据类型比float数据类型大,提供的精度也大一倍(15)

如果在代码中没有对某个非整数值(12.3)硬编码,则编译器一般假定该变量是double。如果想指定值为float,可以在其后加上字符F(f)

float f = 12.3F;

3. decimal类型

另外decimal类型表示精度更高的浮点数如表2-3所示。

  2-3

   

CTS类型

   

   

范围(大致)

decimal

System.
Decimal

128位高精度十进制数表示法

28

±1.0×10-28±7.9 × 1028

 

CTSC#一个重要的优点是提供了一种专用类型表示财务计算,这就是decimal类型,使用decimal类型提供的28位的方式取决于用户。换言之,可以用较大的精确度(带有美分)来表示较小的美元值,也可以在小数部分用更多的舍入来表示较大的美元值。但应注意,decimal类型不是基本类型,所以在计算时使用该类型会有性能损失。

要把数字指定为decimal类型,而不是double float或整型,可以在数字的后面加上字符M(m),如下所示。

decimal d = 12.30M;

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论