二维数组与变长数组
概念说明
二维数组可以看成“数组的数组”。 它常用于矩阵、表格、成绩单、棋盘和坐标网格这类同时需要行列两个维度的数据。
虽然我们会把二维数组想象成表格,但它在内存里仍然是连续存放的。 C 语言采用按行存储的方式,也就是先存完第 0 行,再存第 1 行,依此类推。
变长数组(VLA)则允许使用运行时变量指定数组长度。 它是 C99 引入的能力,可以让某些“长度运行时才知道”的场景更简洁,但要注意编译器支持情况和栈空间大小。
语法/规则
- 二维数组定义形式通常是
类型 数组名[行数][列数];。 - 二维数组在内存里按行连续存放,因此遍历时通常也按行访问更自然。
- 将二维数组传给函数时,除了最左侧维度,后续维度通常需要已知,例如
int sum(int arr[][3], int rows)。 int a[2][3]可以理解为“包含 2 个元素的一维数组,而每个元素又是int[3]”。- 变长数组写法例如
int n = 5; int nums[n];,长度在运行时确定。 - VLA 通常分配在自动存储区,过大的 VLA 可能导致栈空间压力过大。
- C11 以后 VLA 变成可选特性,写可移植代码时要确认目标编译器是否支持。
示例
二维数组
| |
输出结果:
| |
变长数组
| |
输出结果:
| |
常见错误
- 以为二维数组在内存中真的是“分散的多行对象”,忽略了它实际上按行连续存放。
- 把二维数组传给函数时省略列数,结果函数形参类型不完整。
- 把
int **当成int[行][列]的通用替代类型,它们在内存模型上并不等价。 - 创建过大的变长数组,导致栈空间压力过大甚至程序崩溃。
- 在依赖较强可移植性的项目里使用 VLA,却没有确认编译器和标准支持情况。