4.6.2 CLR数组(1)
CLR数组与本地C++(www.cppentry.com)数组不同。供CLR数组使用的内存是在可回收垃圾的堆上分配的,但区别远不止这些。CLR数组具有本地C++(www.cppentry.com)数组所没有的内置功能,这一点我们很快就将看到。我们必须使用关键字array指定数组变量的类型,还必须在array关键字后面的尖括号内指定数组元素的类型,因此引用一维数组的变量使用的通用形式是array<element_type>^。因为CLR数组是在堆上创建的,所以数组变量总是一个跟踪句柄。下面是一个声明数组变量的例子:
- array<int>^ data;
数组变量data可以存储任何对元素类型为int的一维数组的引用。
在声明数组变量的同时,我们可以使用gcnew运算符创建CLR数组:
- array<int>^ data = gcnew array<int>(100);
- // Create an array to store 100 integers
该语句创建一个名为data的一维数组。注意,数组变量是跟踪句柄,因此在尖括号内指定元素类型之后,不要忘记还必须写上^号。元素数量出现在数组类型说明后面的圆括弧内,因此该数组包含100个元素,各个元素可以存储一个int类型的数值。
与本地C++(www.cppentry.com)数组相同,CLR数组中元素的索引值也是从0开始的,因此我们可以像下面这样给data数组中的元素赋值:
- for(int i = 0 ; i<100 ; i++)
- data[i] = 2*(i+1);
该循环将数组元素的值设置为2,4,6,…,直到200。CLR数组中的元素都是对象,因此该循环是在数组中存储Int32类型的对象。当然,这些对象在算术表达式中就像普通整数一样,因此说它们是对象的事实在那些场合下是透明的。
在前面的循环中,元素数量是以字面值形式出现的。更好的方法是像下面这样使用数组的Length属性,该属性记录着元素的数量:
- for(int i = 0 ; i < data->Length ; i++)
- data[i] = 2*(i+1);
我们使用->运算符来访问Length属性,因为data是跟踪句柄,就像指针一样工作。Length属性是32位的整数值,记录着元素的数量。如果需要,也可以通过LongLength属性得到64位的数组长度。
我们还可以使用for each循环,逐一处理数组中所有元素。
- array<int>^ values = { 3, 5, 6, 8, 6};
- for each(int item in values)
- {
- item = 2*item + 1;
- Console::Write("{0,5}",item);
- }
在该循环内,item依次引用values数组中的每个元素。循环体内的第一条语句使当前元素的值乘以2再加1。第二条语句在5字符宽的字段中以右对齐方式输出当前元素的新值,因此该代码段产生的输出如下:
- 7 11 13 17 13
数组变量可以存储任何等级(即维数,比如前面data数组的等级是1)和元素类型相同的数组的地址。例如:
- data = gcnew array<int>(45);
该语句新建一个包含45个int类型元素的一维数组,并将该数组的地址存入data中。原来的数组被抛弃。
我们还可以通过为数组中各元素提供初值的方式来创建数组:
- array<double>^ samples = { 3.4, 2.3, 6.8, 1.2, 5.5, 4.9. 7.4, 1.6};
该数组的大小取决于大括号内初值的数量-- 这里是8,这些初值被顺序赋给各个元素。
当然,数组元素可以是任意类型,因此我们可以轻松地创建一个字符串数组:
- array<String^>^ names = { "Jack", "Jane",
"Joe", "Jessica", "Jim","Joanna"};
该数组的元素是用大括号内的字符串进行初始化的,字符串的数量决定着数组元素的数量。String对象是在CLR堆上创建的,因此数组元素属于跟踪句柄类型String^。
如果我们声明数组变量时不进行初始化,那么在使用一列初值时必须显式地创建该数组。例如:
- array<String^>^ names; // Declare the array variable
- names = gcnew array<String^>{ "Jack", "
Jane", "Joe", "Jessica", "Jim", "Joanna"};
第二条语句创建数组,并用大括号内的字符串进行初始化。如果没有显式的gcnew限定,这条语句将不能编译。
我们可以使用Array类中定义的静态Clear()函数,将数组中任意的连续数组元素清零。使用类名可以调用静态函数,当我们详细介绍类时将学习关于静态函数的更多知识。下面是Clear()函数的用法示例:
- Array::Clear(samples, 0, samples->Length);
// Set all elements to zero
Clear()的第一个参数是要被清零的数组,第二个参数是要清除的第一个元素的索引值,第三个参数是要清除的元素数量。因此,该语句将samples数组的所有元素都置为0.0。如果我们对某种跟踪句柄(如String^)的数组应用Clear()函数,则所有元素都被置为空值;如果是元素为bool类型的数组,则所有元素都被置为false。
现在该让CLR数组在示例程序中一试身手了。
试一试:使用CLR数组
在本示例中,我们将生成一个随机数数组,然后找出其中的最大值。代码如下:
- // Ex4_13.cpp : main project file.
-
- // Using a CLR array
- #include "stdafx.h"
-
- using namespace System;
-
- int main(array<System::String ^> ^args)
- {
- array<double>^ samples = gcnew array<double>(50);
-
- // Generate random element values
- Random^ generator = gcnew Random;
- for(int i = 0 ; i< samples->Length ; i++)
- samples[i] = 100.0*generator->NextDouble();
-
- // Output the samples
- Console::WriteLine(L"The array contains the following values:");
- for(int i = 0 ; i< samples->Length ; i++)
- {
- Console::Write(L"{0,10:F2}", samples[i]);
- if((i+1)%5 == 0)
- Console::WriteLine();
- }
-
- // Find the maximum value
- double max = 0;
- for each(double sample in samples)
- if(max < sample)
- max = sample;
- Console::WriteLine(L"The maximum value in the array is {0:F2}", max);
- return 0;
- }