CLI数组与枚举
CLI数组与枚举
太交从宙明使用方法以及类型掰皇釜方面=讨诠_(
■文/StanleyLippman译/李建忠
类型.其中前者为弓|用类型.后者为值类型,两种类型在通用娄型系统(cTS) 虫赶宣一仝熨应的基础娄型(under|yingtype~分别System.Arfay秘System Enum耗管环堵审的藿}誊绢s祷堂拳酗s太的晦太相.窬毒做7嗽些
…一一砉揎:_
托稚酣
namespaceclj{
template<typenameT.intrank=1>
refclassarray:Array{}:
}
在下面的代码中我们声明了一个元素类型为字符串
的一维CLI数组:
array<String>words
这个声明看起来不怎么漂亮.原因在于其中的两个
帽子"().但是它们却是必要的.因为:
(a)数组的元素类型为一个引用类型:
(b)数组类型本身也是一个引用类型.这意味着words
是一个句柄(handle).
我们可以使用gcnew操作符来分配实际的数组实例:
array<String>wordsgcnewarray<String>(1024)
其中圆括号内的1024表示所分配数组的元素个数.
我们还可以使用简化的初始化方法来为数组提供初始化
列表:
array<String>words={"piglet"."pooh"."eyeore"};
这里words被声明为一个含有3个元素的数组我们可
1OO?程序员?2O0506
以通过查询其Length属性来确认这一点
if(words->Length!=3)…
由于数组是一个引用类型.我们可以通过箭头"一>"
这样的成员选择操作符来访问其内的成员.利用Length属性我们可以很方便地遍历一个数组:
for(jntix=0:ix<words->Length;++jx)
Console::WriteLine("{0}…".ix.words【ix】)
在C++/CLI中.对于使用传统的for循环语句有一种
新的替代方案.那就是foreach语句.注意这里for和each 之间有一个空格两者合在一起构成一个"上下文关键宇(contextualkeyword)"下面演示了其用法:
foreach(Stringwinwords)
Console::WriteLine(w):
该语句会遍历数组(更一般地讲.可以是任何实现了IEnumerable接口的类型我们稍后解释)对象中的元素.事实上.foreach语句包含3个部分:
■■■■■●唧iiII硼II●■…III
l,一个类型与数组元素类型相匹配的实体的声明,
即String^W.每次遍历时数组内的元素会被拷贝给该实体.如果元素类型为引用类型,那么拷贝将是一个浅拷贝(shallowcopy),即拷贝的是地址.
2,上下文关键词ifl.
3,容器对象,其中包含着我们期望遍历的元素.在
我们的例子中,就是words这一数组对象.
使用foreach语句时两个主要的约束为:(a)只能对
持有数组内元素地址的对象实体做读取操作,例如我们不能将W改写为别的引用,否则会导致编译时错误.(b)集
合对象必须实现lEnumerable接口.这意味着至少目前来讲,我们还不能在本地数组.或者STL容器上使用foreach 语句.
我们还可以在gcnew表达式后提供一个显式的初始化
列表来分配数组对象:
array<String>wordsgcnewarray<String>(8) {"piglet"."pooh"."eyeore"}
在初始化列表中,我们提供初始值的个数可以比圆括
号内指定的元素个数少,但不可以超出.或者我们就不要在圆括号内指定元素个数,直接让编译器来根据初始化列表判断数组的长度:
array<int>Fibor~ccigcnewarray<int>()
{1.1.2.3.5.8.13.21.34.55.89.144.233.377.610}
这种显式初始化动态数组的能力在ISO—c++中还做不到虽然很多程序员都希望能够这样.
CLI数组由维数和元素类型唯一地标识.因此,下面的
维字符串数组变量:
array<String>wordlist
可以使用一个任意元素个数的一维字符串数组对象来
怎么给数组赋值赋值或者初始化,例如下面都是正确的赋值语句: wordlistgcnewarray<String>(){"a".…t'.g".…C} wordlistgcnewarray<String>() {"tae"."gcg"."aat"."ttt"."ate"};
CLI数组长度是关乎其使用时的一个方面(anaspectof tsuse),而非其类型的一部分.
多维数组
托管数组声明中有一个隐含的参数可以用来指定数组
的维数.利用它,我们可以声明多维数组.如果没有指定
的话,该参数的缺省值为1.下面的代码分别声明了一个一维数组.二维数组和三维数组:
//一维数组
array<Object>myAr~ygcnewarray<Object>(4); //二维数组
array<String.2>myMatgcnewarray<String.2>(4.4) {{…a'.…b'.…C'}{…e'."f,,
//三维数组
array<int.3>myMygcnewarray<int.3>(2.3.4)
在函数签名与返回值类型中使用数组
我们可以将托管数组直接作为一个函数的返回值类型.
例如:
//方法声明
array<String>linesOfText(Stringfilename);
//方法调用
array<String>textlines=linesOfText("C:\\c++一CLI Primer..)
但是,由于托管数组是一个追踪句柄,它可能指向托
管堆上的有效对象,也可能根本不指向任何对象.这意味
着我们在使用时可能需要判断它的值是否为nullptr:
//隐式判断追踪句柄是否有效
f(!textlines)…
或者
//显式判断追踪句柄是否有效
f(textlines==nullptr)…
同样,在将数组作为函数的参数使用时,也存在这样
的问题.我们在使用之前也要进行判断. separateWords(array<String>textlines)
{
if(!textlines)return;
//
I
J
//可能的一种调用
separateWords(1inesOfText("C:\\c++一CLIPrimer"))
_■ii●■●■■■■■■●■■■■■_■●_■iii
在声明separateWords函数时,我们在返回值
类型的位置上放了3个问号,这不是什么新的类型,而是一
个要留待下一小节解决的问题.
交错数组
有时候,多维数组并不能满足我们的需要,因为它要
求所有维数都是定长的.交错数组(jaggedarrays)为我们
提供了一种替代的方案,它在每一个slot上允许有不同的元素个数.使用交错数组,我们可以将上一小节中的separateWords函数实现得更为高效.
在上--/J\节中,textlines数组中的各个元素存储着一个
文本的各行文字.我们需要遍历每一个元素,将其解析成一
些单个的字符串存储到字符串数组中,然后再将这些数组存储起来并返回.换言之,我们需要一个"数组的数组". 其中外层的数组表示整个文本.第一个索引处的数组表示第一行文字,第二个索引处的数组表示第二行文字,依2O0506-程序员101
此类推.显然,对这样的问题使用多维数组可能会导致一些存储空间的浪费.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。