数组"/>
5 变长数组
变长数组(VLA):
double sales[regions][quarters];
一:限制:
1 变长数组必须是自动存储类别,这意味着无论在函数声明还是作为函数形参声明,都不可以使用 statis和extern存储类别
2 不能在声明中初始化它们
3 变长数组不能改变大小
注意:变长数组的“变”不是可以改变数组的大小,一旦创建了变长数组,它的大小则保持不变,这里的“变”是指:在创建数组时,可以使用变量指定数组维度。
二:声明:
int sum2d(int rows, int cols, int ar[rows][cols]); //ar是一个变长的二维数组
前两个参数 rows 和 cols 用作第三个形参二维数组ar的两个维度,因为数组ar的声明要用到rows和cols,所以这两个形参必须要在数组ar之前声明。 以下声明是无效的:
int sum2d(int ar[rows][cols], int rows, int cols); // 无效的声明
如果要省略形参名,则数组的长度必须要用 * 号代替
int sum2d(int, int, int ar[*][*]); //ar是一个变长数组(VLA),省略了维度形参名
三:例子:
例1:二维数组求和
int sum2d(int rows, int cols, int ar[rows][cols])
{int r,c;int total;for (r = 0; i < rows; ++i)for(c = 0; i < cols; ++i)total += ar[r][c];return total;
}
用变量代替了行数和列数,现在sum2d() 可以处理任意大小的二维int数组了。
例2:变长数组延伸
#include <stdio.h>#define ROWS 3
#define COLS 4int sum2d(int rows, int cols, int ar[rows][cols])
{int i, j;int r,c;int total = 0;for (i = 0; i < rows; ++i)for(j = 0; j < cols; ++j)total += ar[i][j];return total;
}int main(int argc, char const *argv[])
{int i, j;int r = 3;int c = 5;int junk[ROWS][COLS] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};int morejunk[ROWS-1][COLS+2] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};int arr[r][c]; //变长数组for (i = 0; i < r; ++i){for (j = 0; j < c; ++j){arr[i][j] = i * j + j;}}printf("%d\n", sum2d(ROWS, COLS, junk));printf("%d\n", sum2d(ROWS-1, COLS+2, morejunk));printf("%d\n", sum2d(r, c, arr));return 0;
}
运行结果:
78
55
60
注意:
在函数定义的形参列表中声明的变长数组并未实际创建数组,变长数组实际上是一个指针,这说明带变长数组形参的函数实际上是在处理原数组,因此可以修改传入的数组,可以参考下面例子加以理解。
例3:变长数组的实现原理
void twoset(int n, int m, int a[n][n])
{int temp[n][m]; //temp是一个n * m的int数组temp[0][0] = 2; //设置temp的第一个元素为2a[0][0] = 2; //设置 thing[0][0]=2
}int int main(int argc, char const *argv[])
{int thing[10][6];twoset(10, 6, thing);return 0;
}
在调用 twoset() 时,a 成为指向 thing[0] 的指针(并非创建a这个数组),因为 a 和 thing 都是指向 thing[0] 的指针,a[0][0]和thing[0][0] 访问的位置相同
四:const和数组大小
是否可以在声明数组的时候用 const 变量?
const int S = 5;int a[S]; //是否允许
C90规定是不允许的(也可能允许),数组大小必须是给定的整型常量表达式,可以是整型常量的组合,如10、sizeof表达式或其他不是const的内容, 由于c可以实现扩大整型常量表达式的范围,所以可能会允许使用const,但尽量规避。
C99/C11 标准允许在声明变长数组时使用 const 变量。所以该数组的定义必须是声明在块中的自动存储类别数组。
变长数组还允许动态内存分配,这说明可以在程序运行时指定数组的大小。普通 C数组都是静态内存分配,即在编译时确定数组的大小。由于数组大小是常量,所以编译器在编译时就知道了
更多推荐
5 变长数组
发布评论