C++二维数组声明时行列顺序不可颠倒,int arr3表示3行4列,内存行优先存储,索引arri中i为行、j为列;初始化、传参(形参须指定列数)、遍历均需严格匹配维度。

用 int arr[3][4] 定义二维数组时,行和列的顺序不能反
C++ 里二维数组是「行优先」存储的,arr[i][j] 的 i 是行索引、j 是列索引,内存里连续存放的是同一行的所有元素。写成 arr[4][3] 然后按「4 行 3 列」逻辑去用,实际访问会越界或错位。
- 声明时
int grid[2][5]表示 2 行、每行 5 个int,不是「5 行 2 列」 - 初始化列表必须匹配维度:
int a[2][3] = {{1,2,3}, {4,5,6}};合法;{{1,2}, {3,4}, {5,6}}编译失败 - 传参给函数时,形参必须写明列数:
void f(int mat[][4], int rows)——[4]不能省,否则编译不过
遍历二维数组别硬套 for (auto& row : arr) 就完事
范围 for 对 C 风格数组(如 int arr[3][4])推导出的 row 类型是 int[4],不是 std::vector 或可迭代容器,直接嵌套用 for (auto x : row) 没问题,但一旦想取下标、算长度或传给其他函数就容易卡住。
-
sizeof(row) / sizeof(row[0])在函数内失效:形参退化为指针,sizeof返回指针大小 - 想安全获取列数?要么传入固定尺寸模板参数,要么改用
std::array<:array>, 3></:array> - 最稳的遍历写法仍是传统双层 for:
for (int i = 0; i ,可控、无歧义
new int[3][4] 是非法的,动态二维数组得绕一下
C++ 不支持直接用 new 分配多维内置数组,new int[3][4] 会报错。常见替代方案有三种,各自适用场景不同:
- 一维模拟二维:
int* arr = new int[rows * cols];,访问用arr[i * cols + j];省内存、缓存友好,但语义不直观 - 指针数组(不推荐):
int** arr = new int*[rows]; for(...) arr[i] = new int[cols];—— 内存不连续、易漏删、有额外指针开销 - 更现代的选择:
std::vector<:vector>></:vector>或std::vector<int></int>配合封装访问函数;前者灵活但每行独立分配,后者接近一维模拟但带 RAII
用 std::array 定义二维数组时,注意模板参数顺序和类型推导
std::array 是栈上固定大小容器,定义二维时要嵌套:外层是行数,内层是列数,类型写法容易看反。
立即学习“C++免费学习笔记(深入)”;
- 正确:
std::array<:array>, 3> mat;</:array>→ 3 行 × 4 列 - 错误:
std::array<:array>, 4></:array>→ 实际是 4 行 × 3 列,和你想的维度对不上 - 用
auto推导时,auto mat = std::array<:array>, 3>{};</:array>没问题;但若从函数返回值推导,记得函数返回类型必须显式写出嵌套结构,否则可能退化为引用或指针 - 它支持范围 for、
.size()、data(),比原始数组安全,但尺寸必须在编译期确定
C++ 里「多维」从来不是语法糖,而是内存布局 + 类型系统共同约束的结果。维度顺序、内存连续性、类型退化这三点,随便漏掉一个,轻则结果错乱,重则 undefined behavior。











