第十四章 数组[《.net框架程序设计》读书笔记]

.net框架|笔记|程序|设计|数组

第十四章 数组.

内容摘要:

本章讨论了数组的方方面面,对于这种常用类型进行深入研究。

一、 数组简介

三种类型:一维数组、多维数组、交错数组(jagged aray)

l 一维数组:

Int32[] myIntegers;

myIntegers = new Int32[100];

l 多维数组:

Int32[,] myIntegers;

myIntegers = new Int32[100,100];

l 交错数组:交错数组不受CLS支持

Point[][] myPolygons = new Point[3][];

myPolygons[0] = new Point[10];

myPolygons[1] = new Point[20];

myPolygons[2] = new Point[30];

二、 System.Array

请参考.net framework sdk中相关描述

三、 数组转型

l 两数组必须有同样的维数

l 两数组中元素类型间存在隐式或显式转换

l 除使用Array.Copy()方法外,不允许将值类型数组转换为其他类型数组(Array.Copy方法会根据需要进行强制类型转换或装箱操作)

Array.Copy()方法能够执行的类型转换如下:

l 将值类型转换为引用类型,将Int32转换为Object

l 将引用类型转换为值类型,将Object转换为Int32

l 拓宽(widen)CLR基类型,如将Int32转换为Double

下面这个示例提供了一个反面教材(切勿效仿,后果自负!)了值类型的装换:

using System;

//自定义一个值类型,该类型可以与Int32进行互转换

struct MyAge

{

private Int32 m_nAge;

public MyAge(Int32 nAge)

{

this.m_nAge = nAge;

}

//转换操作符

public static implicit operator MyAge(Int32 nAge)

{

return new MyAge(nAge);

}

public static explicit operator Int32(MyAge age)

{

return age.ToInt32();

}

public Int32 ToInt32()

{

return m_nAge;

}

public override string ToString()

{

return "Age : " + m_nAge;

}

}

public class ArrayTest

{

public static void Main()

{

Int32[] arrInt = new Int32[10];

for(int i = 0; i < arrInt.Length; i ++)

{

arrInt[i] = i;

}

MyAge[] arrAge = new MyAge[arrInt.Length];

Array.Copy(arrInt, arrAge, arrInt.Length);

foreach(MyAge age in arrAge)

{

Console.WriteLine(age.ToString());

}

}

}

/*运行结果

未处理的异常: System.ArrayTypeMismatchException: 不能将源数组类型分配给目标数组

类型。

at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationA

rray, Int32 destinationIndex, Int32 length)

at System.Array.Copy(Array sourceArray, Array destinationArray, Int32 length)

at ArrayTest.Main()

*/

注:1、上述代码是不能运行的。虽然为值类型定义了转换操作,但仍不满足上述转换条件,可见自定义的转换操作不被Array.Copy()认可。

2、上述代码中涉及到类型转换操作符的应用,请参考读书笔记第九章 方法

四、 数组传递与返回

注意事项:

l 为获得对数组元素的深拷贝,要求每个元素都实现ICloneable接口。需要注意的是应在适当时候使用深拷贝操作(详情请参见《c# primer》p185)

l 返回数组引用的方法若不含数组元素应该返回一个包含0个元素的数组而不是null

l 不在方法中返回类型内部的数组引用,而是重新构造一个深拷贝的数组返回。

五、 创建下限非0的数组

使用Array.CreateInstance()方法:

public static Array CreateInstance(Type elementType, int[] lengths, int[] lowerBounds);

elementType : 要创建的 Array 的 Type。

lengths : 一维数组,它包含要创建的 Array 的每个维度的大小

lowerBounds : 一维数组,它包含要创建的 Array 的每个维度的下限(起始索引)。

六、 快速数组访问

要点:

l 使用非安全的代码

l 使用指针访问数组

l 可进行非安全数组操作的元素为数值基元类型、Boolean、枚举类型或字段为上述类型的结构类型,或字段为上述结构类型的结构类型……(递归定义的结构类型)

如下面例程所示:

using System;

public class ArrSafe

{

unsafe public static void Main() //此处表明使用非安全代码

{

Int32[] arr = new Int32[]{1,2,3,4,5};

fixed(Int32 *element = arr) //使用指针访问

{

for(Int32 i = 0; i < arr.Length; i ++)

{

Console.WriteLine(element[i]);

}

}

}

}

七、 重新调整数组的长度

l 使用如下方法获取创建新的数组长度(请参见.net framework sdk中的详细描述)

创建使用从零开始的索引、具有指定 Type 和长度的一维 Array。

[C#] public static Array CreateInstance(Type, int);

创建使用从零开始的索引、具有指定 Type 和维长的多维 Array。维的长度在一个 32 位整数数组中指定。

[C#] public static Array CreateInstance(Type, params int[]);

创建使用从零开始的索引、具有指定 Type 和维长的多维 Array。维的长度在一个 64 位整数数组中指定。

[C#] public static Array CreateInstance(Type, params long[]);

创建使用从零开始的索引、具有指定 Type 和维长的二维 Array。

[C#] public static Array CreateInstance(Type, int, int);

创建具有指定下限、指定 Type 和维长的多维 Array。

[C#] public static Array CreateInstance(Type, int[], int[]);

创建使用从零开始的索引、具有指定 Type 和维长的三维 Array。

[C#] public static Array CreateInstance(Type, int, int, int);

l 然后使用Array.Copy()方法,将原来的数组拷贝到新数组中

时间: 2024-12-02 21:17:46

第十四章 数组[《.net框架程序设计》读书笔记]的相关文章

.net 框架程序设计 读书笔记(一)---.net 平台构成

笔记|程序|设计 .net 平台构成 1 底层操操作系统 windows 由于Web服务和使用Web服务的应用程序仍然运行在计算机上,而且既然是计算机都 要有外设,所以我们仍然需要一个操作系统.. Windows添加了Xml支持.. Windows XP和Windows.net (现在改名为windows Server 2003 ) 所有版本都都 为服务驱动的世界提供最好的支持. 特别地windowsXp和Windows 2003 Server 集成了Microsoft .net Passpor

python 教程 第十四章、 地址薄作业

第十四章. 地址薄作业 #A Byte of Python #!/usr/bin/env python import cPickle import os #define the contacts file, list global file_contacts global list_contacts file_contacts = 'AddressBook.txt' list_contacts = [] #delete the file try: file_path = os.getcwd()

精通ios开发 第七...-精通iOS开发 第七版 第十四章 书上例子错误

问题描述 精通iOS开发 第七版 第十四章 书上例子错误 精通iOS开发 第7版 十四章 书上例子在Xcode7.2上运行不了!怎么改? 解决方案 在哪里买的书,赶快要求退货吧,噗次 解决方案二: 7.2的语法可能有更新了 你需要修正代码 毕竟书是对应老版本xcode

连载,LINQ兵法十四章,7(2of3)

问题描述 下面我们为MyLinq添加第二个有用的方法,SelectMany,这个方法的作用是,选取序列中的每个元素,每个元素转换成一个序列,再把这些选取的序列连起来,得到一个整体的序列作为结果输出.我们用SelectMany来遍历交错数组:staticvoidMain(string[]args){int[][]data=newint[][]{newint[]{1,2,3},newint[]{4,5},newint[]{},newint[]{6,7,8,9},newint[]{10}};varre

连载,LINQ兵法十四章,1(1of1)

问题描述 第一章从类型到接口先看一个简单的程序:intx=1;objecty=2;Console.WriteLine(x.GetType());Console.WriteLine(y.GetType()); 运行结果:System.Int32System.Int32我们定义了两个变量,x和y,它们都是整数.现在的问题是,intx和objectx这两种定义究竟有什么不同.我们利用VS的智能感知提示来观察下:这是x的这是y的我们发现y只有4个方法,而x有6个.CompareTo和GetTypeCod

连载,LINQ兵法十四章,2(1of1)

问题描述 第二章从函数到委托看这样的程序:intsum=0;for(inti=1;i<=100;i++){sum=sum+i;}Console.WriteLine(sum);sum=0;for(inti=1;i<=1000;i++){sum=sum+i;}Console.WriteLine(sum); 这个程序有一点点呆,很明显程序的前半部分和后半部分拥有类似的结构,只是控制i的循环变量的终值不同.因此我们可以提取出一个函数:staticvoidMain(string[]args){Conso

C语言学习教程第四章-数组(5)

用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志'\0'.上面的数组c在内存中的实际存放情况为: C program\0`\0'是由C编译系统自动加上的.由于采用了`\0'标志,所以在用字符串赋初值时一般无须指定数组的长度, 而由系统自行处理.在采用字符串方式后,字符数组的输入输出将变得简单方便. 除了上述用字符串赋初值的办法外,还可用printf函数和scanf函数一次性输出输入一个字符数组中的字符串, 而不必使用循环语句逐个地输入输出每个字符.void main(){

WF从入门到精通(第十四章):基于状态的工作流

学习完本章,你将掌握: 1.理解状态机的概念以及它怎样被模拟到工作流处理中的 2.创建基于状态的工作流 3.运用初始(initial)和终止(terminal)状态条件 4.使用代码进行状态的切换 在第四章"活动和工作流类型介绍"中,我阐述过你使用WF所能创建的工作流类型,在那里我提到过基于状态的工作流.基于状态的工作流模型被认为是有限自动机(finite state machine).基于状态的工作流在工作流需要和外部事件进行许多交互的场合中大出风头.在事件触发并被工作流处理的时候,

Scala程序设计读书笔记[1:5]

Scala程序设计: Java虚拟机多核编程实战 一直好奇什么样的语言能够不需要加锁解决线程同步问题,能够解决Twitter的性能问题,想了解什么是函数式编程.于是找工作的间隙看了这本书,扩展一下视野. Source Code: http://media.pragprog.com/titles/vsscala/code/vsscala-code.zip Scala Online Editor: URL: http://www.scala-tour.com/#/expression-and-val