c++中如何实现矩阵乘法_c++二维数组矩阵相乘逻辑

12次阅读

矩阵乘法必须首先检查左矩阵列数等于右矩阵行数,否则应抛出std::invalid_argument异常;使用std::vector时需确保非空且每行长度一致,推荐一维vector模拟二维以提升缓存友好性。

c++中如何实现矩阵乘法_c++二维数组矩阵相乘逻辑

矩阵乘法的维度合法性检查必须放在最前面

两个矩阵能相乘的前提是:左矩阵的列数等于右矩阵的行数。不检查就直接计算,轻则结果全错,重则访问越界崩溃。std::vector 或裸 int** 都不会自动做这个判断,得自己写。

  • 假设左矩阵 Am x k,右矩阵 Bk x n,结果 C 应为 m x n
  • A 列数 ≠ B 行数,应立刻返回错误或抛异常(比如 std::invalid_argument
  • 用裸数组时,这个信息通常靠传参显式带入,例如:multiply(A, m, k, B, k, n, C)

std::vector<:vector>> 实现更安全但要注意性能陷阱

动态二维 vector 写起来直观,但默认初始化和内存布局可能拖慢乘法——尤其是大矩阵。每行是独立分配的,缓存不友好。

std::vector> multiply(const std::vector>& A,                                         const std::vector>& B) {     int m = A.size(), k = A[0].size();     int n = B[0].size();     if (k != (int)B.size()) throw std::invalid_argument("Dimension mismatch"); 
std::vector> C(m, std::vector(n, 0)); for (int i = 0; i < m; ++i)     for (int j = 0; j < n; ++j)         for (int p = 0; p < k; ++p)             C[i][j] += A[i][p] * B[p][j]; return C;

}

  • 注意:A[0].size() 前要确保 A 非空且每行长度一致,否则行为未定义
  • 三层循环顺序固定为 i→j→p(不是 i→p→j),这对现代 CPU 缓存更友好
  • 如果矩阵很大,建议改用一维 std::vector 模拟二维(行优先),避免指针跳转开销

裸二维数组(/)需手动管理尺寸,容易越界

int A[100][100]int** A 时,编译器不检查 A[i][j] 是否合法。下标错一位,可能读到相邻变量甚至段错误。

立即学习C++免费学习笔记(深入)”;

  • 数组如 int A[3][4], B[4][5]; 可直接用,但尺寸必须编译期确定
  • 堆分配 int** A = new int*[m]; for(...) A[i] = new int[k]; 要配对 delete[],否则泄漏
  • 推荐用 std::unique_ptr 管理: auto A = std::make_unique<:unique_ptr>[]>(m);

常见错误:混淆行列索引或累加逻辑

最容易写错的是内层累加没清零,或者把 A[i][p] * B[p][j] 错写成 A[i][j] * B[i][j]——那根本不是矩阵乘法,而是逐元素乘。

  • 结果矩阵 C[i][j] 必须初始化为 0,否则含垃圾值
  • 中间求和变量不能复用上一轮的残留值(尤其用单个 sum 变量时)
  • 调试时可先用 2×2 小矩阵手算验证:比如 A={{1,2},{3,4}}, B={{0,1},{1,0}},结果应为 {{2,1},{4,3}}

实际工程中,小矩阵用 vector 足够;高频/大矩阵务必考虑内存连续性、SIMD 指令或 Eigen 等库。手写时,维度检查和索引边界永远比优化循环更重要。

text=ZqhQzanResources