数组说明
数组说明继承了变量说明的一些特性。首先,我们应该注意,数组可以是全局的,也可以是局部的,取决于声明它们的位置。与变量类似,const 和 static 修饰符也可以用于描述数组。对于一维定长数组,声明语法如下所示:
type static1D[size]; |
此处,type 和 static1D 分别表示元素的类型名称和数组标识符,而方括号中的 size 是定义大小的整数常量。
对于多维数组,必须根据维度数量指定多个大小:
type static2D[size1][size2];
|
动态数组以类似的方式描述,只是跳过了第一个方括号(在使用这种数组之前,必须使用 ArrayResize 函数为它分配所需的内存大小,参见涉及 动态数组的章节)。
type dynamic1D[];
|
对于定长数组,允许初始化:在等号后面为各元素指定初始值,构成一个以逗号分隔的列表,整个列表用花括号括起来。例如:
int array1D[3] = {10, 20, 30}; |
此处,大小为 3 的整数数组取值 10、20 和 30。
使用初始化列表,就不需要在方括号中指定数组大小(仅限一维数组)。编译器将根据列表长度自动评估大小。例如:
int array1D[] = {10, 20, 30}; |
初始值可以是常量也可以是常量表达式,即编译器在编译时可以计算的公式。例如,下列数组由一分钟、一小时、一天、一周中的秒数构成(用公式表示比直接用 86400 或 604800 更直观):
int seconds[] = {60, 60 * 60, 60 * 60 * 24, 60 * 60 * 24 * 7}; |
这些值通常被设计为代码开头的预处理器宏,随后可以将这个宏的名称插入文本中任何需要的位置。此方法在 预处理器的相关章节中进行了说明。
初始化元素的数量不能超过数组大小。否则,编译器会显示错误消息“初始化器过多”。如果值数量小于数组大小,则剩余元素被初始化为零。因此,提供了一个将整个数组初始化为零的简单语句:
int array2D[2][3] = {0}; |
或者只使用一对花括号:
int array2D[2][3] = {}; |
不管是几维数组,这种方法都有效。
要初始化多维数组,必须嵌套列表。例如:
int array2D[3][2] = {{1, 2}, {3, 4}, {5, 6}}; |
此处,数组的第一个维度大小是 3;那么就用两个逗号分隔 3 个元素,并用花括号括起这三个元素。但是,由于数组是二维的,它的每个元素都是一个数组,大小都是 2。也就是每个元素用带花括号的列表表示,每个列表包含 2 个值。
假设,我们需要一个转置后的数组(第一个维度大小为 2,第二个维度大小为 3),那么数组的初始化会发生变化:
int array2D[2][3] = {{1, 3, 5}, {2, 4, 6}}; |
如果必要,我们可以跳过初始化列表中的一个或多个值,用逗号标记它们的位置。所有被跳过的元素也将被初始化为零。
int array1D[3] = {, , 30}; |
此处,第一个元素将等于 0。
语言的语法允许在最后一个元素后输入一个逗号:
string messages[] =
|
这简化了添加新元素的步骤,尤其是对于多字符串条目。特别是,如果我们忘记在字符串数组中新增元素前面输入逗号,那么新旧字符串将会合并为一个元素(具有相同索引),而不会生成新元素。此外,一些数组可以自动生成(借助其他程序或宏)。因此,自然所有元素都具有统一外观。
“堆”和“栈”
对于可能很大的数组,区分内存中的全局位置和局部位置非常重要。
全局变量和数组占用的内存是在“堆”内部分配的,即程序可用的空闲内存。除了计算机物理特性和操作系统之外,这种内存实际上不受任何限制。“堆”的名称可以这样解释:程序不停在分配或释放不同大小的内存区域,这导致空闲区域随机分布在整个块中。
局部变量和数组位于栈中,即预先为程序分配的有限内存区域,尤其用于存储局部元素。‘栈’的名称来源于这样一个事实:在算法执行期间发生函数的嵌套调用,这些调用根据“堆叠”原则累积其内部数据:例如,终端调用 OnStart,OnStart 调用应用代码中的另一个函数,这个函数又会调用另一个函数,以此类推。与此同时,每个函数时,都会创建其局部变量,在调用嵌套函数期间,这些变量一直存在。嵌套函数也会创建局部变量,这些局部变量在栈中的位置比此前创建的变量要高一些。结果是,栈通常包含多层局部数据,这些数据来自于到达当前代码字符串所经过的路径上激活的所有函数。直到位于栈顶部的函数执行完成,它的局部数据才会从此处移除。一般来说,栈是一种基于 FILO/LIFO(先进后出,后进先出)原则的存储。
由于栈的大小有限,建议只在其中创建局部变量。但是,数组可能非常大,很快就会耗光栈空间。与此同时,程序执行完成时出现错误。因此,我们应该将全局级别的数组描述为静态的 (static) 或者动态地为这些数组分配内存(在堆上分配)。