第 2 章 数据类型与流程控制

24
第 2 第 第第第第第第第第第 2.2.2 第第第第 C# 第第第第第 第第第第第第第第第第第 “第第”第第第第第第第第第第第 一。 第第第第第第第第第第第第 第第第第第第第第第第第第 ,。 C# 第第第第第第第第第 4 第 第第 ,、 第第 第第第第第第 、。 1 第第第第第第第第第第第第第 第第 第第第第第第第第 第第第第第第第第第第第第第 ,一、 第第第第第第第第第第 第第第第第 第第第第第第第第第 第第第 第第第第第第 第第第第 。、。、、、、 第第第第第第第第第 第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第 第 。,: 第第第第第 第第第第第第第第 ,。 第第第第第第第 第第第第第 第第第第第第第第第第第第第第第第第第 第第第第第第 ,,, 第第第第第第第第第第

Upload: claudia-gay

Post on 03-Jan-2016

133 views

Category:

Documents


8 download

DESCRIPTION

第 2 章 数据类型与流程控制. 2.2.2 引用类型 C# 语言中的另一大数据类型是引用类型。 “ 引用 ” 指的是该类型的变量不是直接存储所包含的实际数据,而是存储实际数据的地址。 C# 语言中的引用类型有 4 种,类、委托、接口和数组。 1 、类 类是面向对象编程的基本单位,是一种包含数据成员、函数成员和嵌套类型的数据结构。类的数据成员有常量、域和事件。函数成员包括方法、属性、索引指示器、运算器、构造函数和析构函数。类和结构同样都包含了自己的成员,但它们之间最主要的区别在于:类是引用类型,而结构是值类型。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 2 章 数据类型与流程控制

第 2 章 数据类型与流程控制 2.2.2 引用类型 C# 语言中的另一大数据类型是引用类型。“引用”指的是该类型的变量不是直接存储所包含的实际数据,而是存储实际数据的地址。 C# 语言中的引用类型有 4 种,类、委托、接口和数组。1 、类 类是面向对象编程的基本单位,是一种包含数据成员、函数成员和嵌套类型的数据结构。类的数据成员有常量、域和事件。函数成员包括方法、属性、索引指示器、运算器、构造函数和析构函数。类和结构同样都包含了自己的成员,但它们之间最主要的区别在于:类是引用类型,而结构是值类型。 类支持继承机制,通过继承,派生类可以扩展基类的数据成员和方法,进而达到代码重用和设计重用的目的。

Page 2: 第 2 章 数据类型与流程控制

第 2 章 数据类型与流程控制 2.2.2 引用类型 2 、委托 委托是指引用方法的类型,它实际上相当于 C++ 语言中的函数指针原型,但与指针不同的是,委托在 C# 语言中是安全的,它允许实例化和调用类的静态方法,也可以调用类的指定实例的方法。在声明委托类型时,只需要指定委托指向的原型的类型,它不能有返回值,也不能带有输出类型的参数。

Page 3: 第 2 章 数据类型与流程控制

第 2 章 数据类型与流程控制 2.2.2 引用类型 3 、接口 接口是一组包含了方法的数据结构。通过这组数据结构,可以在代码中调用组件对象的功能。接口可以从父接口中继承,但实际含义是说明继承,而不是实现性继承。它的实现需要通过类或结构来完成。接口的成员可以是方法、属性、索引指示器和事件,但不能是常量、域、操作符和构造函数,而且不能包含任何静态成员。

Page 4: 第 2 章 数据类型与流程控制

第 2 章 数据类型与流程控制 2.2.2 引用类型 4 、数组 数组和结构不同,结构一般用于存储多种类型的数据,而数组则用于存储同一种类型的数据。数组是一种引用类型,而不是值类型。数组是按照数组名、数据元素的类型和维数来描述的。 C# 语言中可以有一维数组和多维数组,多维数组中又可以分为矩形数组和交错数组。( 1 )数组的声明 C# 语言可以在声明时不对数组进行初始化,需要使用数组时再在程序中动态地指定其大小,如表 2-6 所示。

Page 5: 第 2 章 数据类型与流程控制

4 、数组( 1 )数组的声明

数组类型 语法 例子 说明

一维数组 数据类型 [ ] 数组变量 ; int [] myArray;

二维数组 数据类型 [,] 数组变量 ; int [,] myArray;

三维数组 数据类型 [,,] 数组变量 ; int [,,] myArray;

交错数组 数据类型 [ ][ ] 数组变量 ; int [ ] [ ]myArray; 指元素为数组的数组

表 2-6 数组的声明语法

Page 6: 第 2 章 数据类型与流程控制

4 、数组( 1 )数组的声明

例如:int[ ] Integers; // 声明一个 int 型的数组 Integers ;Integers=new int[30]; // 指定数组 Integers 共有 30 个元素; 在实际使用中,如果预先知道数组的大小,也可以将这两个语句合而为一,

例如:int[] Integers=new int[30]; // 创建一个包含 30 个 int 型元素的数组

Integers ; 如果在数组声明时已经知道数组元素的初始值,也可以在声明语句中直接

为其赋值,例如:string[ ] mystring={”first”,”second”,”third”}; 它等价于:string[ ] mystring=new string[] {”first”,”second”,”third”};

Page 7: 第 2 章 数据类型与流程控制

4 、数组( 2 )数组的使用

访问共有 32 个元素数组中的单个元素时,其下标是从 0 开始索引的,例如:

Integers[0]=23; // 为 Integers 数组中的第一个元素赋值23 ;

Integers[31]=67; // 为 Integers 数组中的最后一个元素赋值 67 ;

在数组操作中经常使用的一个重要属性是数组的长度。要确定一维数组的长度,可以使用 Length 属性,例如:

int ArrayLength=Integers.Length; 如果是多维数组,则可以使用 GetLength 方法确定其某一特定

维的长度,例如:int ArrayLength=Integers.GetLength(0); //获取

Integers 数组第一维的长度 C# 语言中还提供了 Sort 和 Reverse 这样的静态方法,可以

将数组按照升序或降序排列。

Page 8: 第 2 章 数据类型与流程控制

[ 例 2-4] 使用 Sort 和 Reverse 方法对数组排序。using System;namespace ArrayExample1{ class Program { static void Main() { // 定义一维数组 Artists ,并赋初始值 string[] Artists={"Leonardo","Monet","Van Gogh","Klee"}; // 将数组 Artists做升序排列,并输出其结果; Array.Sort(Artists); for(int i=0;i<Artists.Length;i++) { Console.WriteLine(Artists[i]); } // 将数组 Artists 做降序排列,并输出其结果; Array.Reverse(Artists); for(int i=0;i<Artists.Length;i++) { Console.WriteLine(Artists[i]); } Console.ReadLine(); } }}

输出结果:KleeLeonar

doMonetVan Go

ghVan Go

ghMonetLeonar

doKlee

Page 9: 第 2 章 数据类型与流程控制

( 3 )多维数组 C# 语言支持两种类型的多维数组,一种是矩形数组,另一种是交错数组。在多维数组中,最常用的是二维数组。对于二维矩形数组,数组中的每一行都有相同的列数;而二维交错数组的每一行可以有不同的列数。显然,交错数组比矩形数组更灵活,但它的创建和初始化也更复杂一些。 [ 例 2-5] 数组的常用形式和使用的方法。

using System;namespace ArrayExample2{ class Program { static void Main() { // 一维数组 string[] strArray1={"C","C+

+","C#"}; string[] strArray2=new string

[3]; // 指定元素个数并赋初值 int[] intArr1=new int[4]{0,1,2,3}; // 直接赋初值 int[] intArr2={5,6,7}; int nVar=5; int[] arrToo=new int[nVar];

Page 10: 第 2 章 数据类型与流程控制

// 二维矩形数组 int[,] myArr1={{0,1},{2,3},{4,5}}; int[,] myArr2=new int[2,3] {{11,12,13},{21,22,23}}; // 二维交错数组 string[][] stra=new string[3][]; stra[0]=new string[2]{"a11","a12"}; stra[1]=new string[3]{"b11","b12","b13"}; stra[2]=new string[5]{"a","e","u","i","o"}; // 输出一维数组 for(int i=0;i<strArray1.Length;i++) { Console.Write("strArray1[{0}]={1}",i,strArray1[i]); } Console.WriteLine(); // 输出二维矩形数组的元素 for(int i=0;i<3;i++) { for(int j=0;j<2;j++) Console.Write("myArr1[{0},{1}]={2}",i,j,myArr1[i,j]); Console.WriteLine(); }

Page 11: 第 2 章 数据类型与流程控制

// 输出二维交错型数组的元素 for(int i=0;i<stra.Length;i++) { for(int j=0;j<stra[i].Length;j++) Console.Write(" stra[{0}][{1}]={2}",i,j,stra[i][j]); Console.WriteLine(); } Console.ReadLine(); } }}

输出结果:strArray1[0]=C strArray1[1]=C++ strArray1[2]=C#myArr1[0,0]=0 myArr1[0,1]=1myArr1[1,0]=2 myArr1[1,1]=3myArr1[2,0]=4 myArr1[2,1]=5stra[0][0]=a11 stra[0][1]=a12stra[1][0]=b11 stra[1][1]=b12 stra[1][2]=b13stra[2][0]=a stra[2][1]=e stra[2][2]=i stra[2][3]=o stra[2]

[4]=u

Page 12: 第 2 章 数据类型与流程控制

第 2 章 数据类型与流程控制 2.2.3 值类型之间的数据交换 值类型之间的数据交换可以相互转换。如果仅仅是数据表示范围不同的数据类型之间的转换,例如, int 型和 long 型的数据转换,比较常用的两种转换方式是:隐式转换与显示转换。如果是不同值类型之间的转换,则可以使用 Convert 类。1 、隐式转换 隐式转换就是系统默认的、不需要加以声明就可以进行的转换,如从 int 类型转换到 long 类型: int k=1; long i=2; i=k; //隐式转换 在进行隐式的类型转换时,其实就是从低精度、小范围的数据类型转换为高精度、大范围的数据类型。这种转换一般没有问题,这是因为大范围类型的变量具有足够的空间存放小范围类型的数据。表 2-7 中列出了 C# 语言支持的隐式转换的类型。

Page 13: 第 2 章 数据类型与流程控制

源类型 目的类型

sbyte short、 int、 long、 float、 double、 decimal

byte short 、 ushort 、 int 、 uint 、 long 、 ulong 、 float 、double 、 decimal

short int、 long、 float、 double、 decimal

ushort int 、 uint 、 long 、 ulong 、 float 、 double 、 decimal

int long、 float、 double、 decimal

uint long、 ulong、 float、 double、 decimal

long 、 ulong

float、 double、 decimal

float double

char ushort 、 int 、 uint 、 long 、 ulong 、 float 、 double 、 decimal

表 2-7 隐式转换类型

Page 14: 第 2 章 数据类型与流程控制

2 、显式转换 显式转换,又称强制转换。显式转换需要用户明确指定转换的类

型。例如: long k=5000; int i=(int)k; 所有的隐式转换也都可以采用显式转换的形式来表示。例如: int i=10; long j=(long)i; 在将大范围类型的数据转换为小范围类型的数据时,必须特别谨

慎,因为此时有丢失数据的危险。例如: long r=3000000000; int i=(int)r; 执行上述语句之后,得到的 i 值为 -1294967296 ,显然是不

正确的。这是因为上述语句中, long 型变量 r 的值比 int 型的最大值+2147483647还要大,而语句中又使用了强制的类型转换,系统对这种转换不会报错,会强制执行,从而导致数据溢出,发生错误。

Page 15: 第 2 章 数据类型与流程控制

2 、显式转换 如果的确需要使用显式的类型转换,但又不知

是否会发生溢出而导致数据错误,可以使用checked 运算符来检查数据类型是否安全。如上例,可以写为:

long r=3000000000; int i=checked(int)r; 在这种情况下,如果出现溢出,系统就会在运

行时抛出一个溢出异常,不会使程序继续运行。另外, C# 语言中还提供了一个 Convert 类,

也可以用于各种值类型之间的转换,有关Convert 类的使用方法将在第 3 章介绍。

Page 16: 第 2 章 数据类型与流程控制

[ 例 2-6] 显式转换和隐式转换。using System;namespace TypeConvertExample{ class Program { public static void Main() { int i=10; long j=20; double k=30D; // 隐式转换 j=i; k=j; Console.WriteLine("{0},{1},{2}",i,

j,k); k=36.0D; // 显式转换 j=(long)k; i=(int)j; Console.WriteLine("{0},{1},

{2}",i,j,k); Console.ReadLine(); } }}

输出结果为:

10,10,10

36,36,36

Page 17: 第 2 章 数据类型与流程控制

2.2.4 装箱和拆箱 装箱和拆箱功能使得 C# 语言中所有的值类型都可

以与 object 类型实现双向转换。1 、 Object 类 Object 类是所有其他类型的基类, C# 语言中

的所有类型都直接或间接地从 Object 类中继承。因此,可以使用 Object 类引用绑定任何特定子类型的对象。

值类型与 Object 类型之间的转换有什么意义呢?举个例子,在程序中可以直接这样写:

string s=(10).ToString(); 数字 10 只是一个堆栈上的 4 字节的值,怎么能

实现调用它上面的方法呢?实际上, C# 语言是通过装箱和拆箱操作来实现的,即先把 10转换为引用类型,然后再调用引用类型的方法来实现指定的功能。

Page 18: 第 2 章 数据类型与流程控制

2.2.4 装箱和拆箱2 、装箱 装箱是将值类型隐式地转换为 Object 类型。装箱一个数值会为其分配一个对象实例,并把该数值复制到新对象中。例如: int i=123; object o=i; //装箱 这条装箱语句执行的结果是在堆栈( Stack )中创建了一个对象 o ,该对象引用了堆(Heap )上 int 类型的数值,而该数值是赋给变量 i 的数值的备份。3 、拆箱 拆箱是显式地把Object 类型转换成数值类型。拆箱操作包括以下两个步骤:( 1 )检查对象实例,确认它是给定值类型的包装数值;( 2 )把实例中的值复制到值类型的变量中;下面的语句演示了装箱和拆箱操作。 int i=123; // 值类型 object box=i; //装箱操作 int j=(int)box; //拆箱操作 可以看出来,拆箱正好是装箱的逆过程,但必须注意的是,装箱和拆箱必须遵循类型兼容的原则。

Page 19: 第 2 章 数据类型与流程控制

2.2.5 运算符与优先级 C# 语言有三大类运算符。 一元运算符:带有一个运算对象,例如, i++ 。 二元运算符:带有两个运算对象,例如, x+y 。 三元运算符:带有 3 个运算对象,例如, < 条件 >?<条件成立时结果表达式>:<条件不成立时结果表达式

> 。 5>3?58:98 // 结果为 58

表 2-8列出了常用运算符及其相关说明。

Page 20: 第 2 章 数据类型与流程控制

运算符类型 范例 说明

比较运算符 = = != 比较两个值是否相等或不等

关系运算符 <> <= >= is 比较两个值的大小

条件运算符 && || ! ?: 用布尔值判断两个数的关系:条件与、条件或、条件非、三元运算符

递增运算符 ++ 将变量的值加 1

递减运算符 -- 将变量的值减 1

算术运算符 + - * / % 加、减、乘、除、求余数

逻辑操作运算符(按位操作运算

符 )

& | ! ~ ^ << >> 逻辑与、逻辑或、逻辑非、按位取反、逻辑异或、逻辑左移、逻辑右移

赋值运算符 = *= /= %= += -= <<= >>= &= ^= |=

例如: i*=2; 相当于 i=i*2;

表 2-8 常用运算符

Page 21: 第 2 章 数据类型与流程控制

当一个表达式包含多个操作符时,表达式的值就由各操作符的运算优先级决定。表 2-9列出了常见运算符的优先级。

特殊运算符 ()

一元运算符 + (正)、 - (负) ! (条件非) ++ - -

乘 /除运算符 * / %加 /减运算符 + -

移位运算符 << >>

关系运算符 < > <= >= is

比较运算符 = = !=

按位取反运算符 ~

逻辑与运算符 &

逻辑异或运算符 ^

逻辑或运算符 |

条件与运算符 &&

条件或运算符 ||

三元运算符 ?:

赋值运算符 = += -= *= /= %= <<= >>=

Page 22: 第 2 章 数据类型与流程控制

当一个操作数出现在两个有相同优先级的操作符之间时,操作符按照出现的顺序由左至右执行。如果无法确定操作符的有效顺序,则可以在编程时采用括号“ ()” 进行指定,从而保证运算的顺序正确无误,也使得程序一目了然。

Page 23: 第 2 章 数据类型与流程控制

// 表达式举例using System;class OperatorExample{ public static void Main() { int i=1,j=2,a,b; Console.WriteLine("{0},{1},{2}",i++,i,++i); Console.WriteLine("{0},{1},{2}",--j,j,j--); Console.WriteLine(65>12?65:98); a=b=2; a+=5; b*=5; Console.WriteLine("{0},{1},{2}",a,b,a+b); Console.WriteLine("{0}",5>10&&100>200||38>16); Console.ReadLine(); }}

Page 24: 第 2 章 数据类型与流程控制

小 结

• 介绍了 C# 数据类型的引用类型、装箱和拆箱

• 介绍了 C# 的运算符