最直接方法是用嵌套for循环遍历二维数组求和:外层i从0到m-1遍历行,内层j从0到n-1遍历列,累加arri;需明确维度m、n,避免越界或索引错位。

用嵌套 for 循环遍历二维数组求和最直接
C++ 没有内置的 sum() 函数处理原生二维数组,必须手动遍历。关键在于搞清数组维度:如果是 int arr[3][4] 这种栈上声明的固定大小数组,行数列数编译期已知;如果是动态分配(如 int**),得额外传入尺寸参数。
常见错误是越界访问——比如把列数写成 sizeof(arr)/sizeof(arr[0])(这实际得到的是总元素数,不是列数);或者混淆行优先存储导致索引错位。
- 对
int arr[M][N],用for (int i = 0; i 套 <code>for (int j = 0; j - 避免用
sizeof(arr)/sizeof(int)算总长再除——容易在指针传参时失效 - 若用
std::vector<:vector>></:vector>,外层 size() 是行数,每行v[i].size()是列数,注意每行长度可能不等
用 std::accumulate 处理一维视图更简洁
二维数组在内存中是连续的,可以把它当一维看待。配合 std::accumulate 能少写循环,但前提是确认内存布局没被破坏(比如非连续的 std::vector<:vector>></:vector> 不适用)。
典型误用:对 int** ptr 直接取 &ptr[0][0]——这是未定义行为,因为各行内存不一定相邻。
- 对
int arr[5][6],可写:std::accumulate(&arr[0][0], &arr[0][0] + 5*6, 0) - 必须确保起始地址和结束地址构成合法连续区间,否则崩溃或算错
- 比手写循环略快(编译器易优化),但可读性稍弱,调试时不易定位具体行列
用范围 for 遍历 vector> 更安全但要注意性能
如果数据来自文件或运行时输入,大概率用 std::vector<:vector>></:vector> 存储。这时用范围 for 最直观,且自动适配不规则形状(如三角矩阵)。
陷阱在于:每次 auto row 默认按值拷贝整行,若元素多会拖慢速度;而 auto& row 又要求后续不修改原数据结构。
- 推荐写法:
for (const auto& row : matrix) { for (int val : row) sum += val; } - 避免
for (auto row : matrix)—— 多余拷贝 - 若需修改,用
for (auto& row : matrix),但内层仍建议for (int& val : row)明确意图
遇到 const 或 constexpr 数组时,编译期求和可行但限制多
如果数组内容和尺寸全为编译期常量(constexpr int arr[2][3] = {{1,2,3},{4,5,6}};),可以用模板递归或 C++17 的折叠表达式在编译期算出结果,生成纯常量。
但实际中几乎没人这么干:一旦数组从输入读取、或含非字面量值,就退化成运行时计算;而且代码复杂度陡增,调试困难。
- 仅适用于极少数嵌入式场景(ROM 中固化数据,且必须零运行时开销)
- 折叠表达式示例:
((sum += row), ...)需配合初始化列表展开,对二维要两层嵌套 - 日常开发里,老老实实跑一遍循环更可靠
真正容易被忽略的是边界检查——尤其当二维数组作为函数参数传入时,int arr[][4] 这种声明只保留列数,行数完全丢失,必须靠额外参数或容器封装来保全信息。别指望编译器替你记尺寸。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











