VLA
C99新增了变长数组(variable-length array VLA),允许使用变量表示数组的维度。如下所示:
int quarters = 4;
int regions = 5;
double sales[regions][quarters]; // 一个变长数组(VLA)
变长数组有一些限制。变长数组必须是自动存储类别,这意味着无论在函数中声明还是作为函数形参声明,都不能使用static
或extern
存储类别说明符,而且不能再声明中初始化变长数组。最终C11把变长数组作为一个可选特性,而不是必须强制实现的特性。
注意:变长数组不能改变大小
变长数组中的“变”不是指可以修改已创建数组的大小。一旦创建了变长数组,它的大小则保持不变。这里的“变”指的是:在创建数组时,可以使用变量指定数组的维度。
下面我们来看一个简单的例子:如何编写一个函数,计算int
的二维数组所有元素之和。
首先,要声明一个带二维变长数组参数的函数,如下所示:
int sum2d(int rows, int cols, int ar[rows][cols]); // ar是一个变长数组(VLA)
注意前两个形参(
rows
和cols
)用作第3个形参二维数组ar
的两个维度。因为ar
的声明要使用rows
和cols
,所以在形参列表中必须在声明ar
之前先声明这两个形参。
C99/C11标准规定,可以省略原型中的形参名,但是在这种情况下,必须用星号来代替省略的维度:
int sum2d(int, int, int arr[*][*]);
其次,该函数的定义如下:
int sum2d(int rows, int cols, int arr[rows][cols]) {
int sum = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
sum += arr[i][j];
}
}
return sum;
}
下面程序演示了以变长数组作为形参的函数既可处理传统C数组,也可处理变长数组。
#include <stdio.h>
int sum2d(int, int, int arr[*][*]);
int main() {
int rows = 10;
int cols = 20;
int arr[rows][cols];
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
arr[i][j] = j;
}
}
int result = sum2d(rows, cols, arr);
printf("VLA %d\n", result);
int arr2[5][5] = {
{1,2,3,4},{1,2,3,4},{1,2,3,4}
};
int result2 = sum2d(5, 5, arr2);
printf("%d\n", result2);
return 0;
}
int sum2d(int rows, int cols, int arr[rows][cols]) {
int sum = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
sum += arr[i][j];
}
}
return sum;
}
输出如下:
需要注意的是,在函数定义的形参列表中声明的变长数组并未实际创建数组。和传统的语法类似,变长数组名实际上是一个指针。这说明带变长数组形参的函数实际上是在原始数组中处理数组,因此可以修改传入的数组。
C99/C11标准允许在声明变长数组时使用const
变量。所以该数组的定义必须是声明在块中的自动存储类别数组。
变长数组还允许动态内存分配,这说明可以在程序运行时指定数组的大小。普通C数组都是静态内存分配,即在编译时确定数组的大小。由于数组大小是常量,所以编译器在编译时就知道了。
标签:arr,rows,形参,VLA,cols,C语言,int,数组 From: https://www.cnblogs.com/wwjj4811/p/16647317.html