代码之家  ›  专栏  ›  技术社区  ›  AstralHex

矩阵乘法代码工作不正常

  •  0
  • AstralHex  · 技术社区  · 2 月前

    为什么我的C++代码在使用指针算术时会给出不正确的矩阵乘法结果?

    我正在尝试:

    我试图在C++中实现矩阵乘法,并使用指针算法访问矩阵元素。然而,我的程序产生了不正确的结果。以下是我迄今为止编写的代码:

    #include <iostream>
    #include <vector>
    
    void multiply_matrices(int* A, int* B, int* C, int n) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                *(C + i * n + j) = 0; // Clear the element in C
                for (int k = 0; k < n; ++k) {
                    *(C + i * n) += *(A + i * n + k) * *(B + k * n + j);
                }
            }
        }
    }
    
    int main() {
        int n = 3;
        int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        int B[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
        int C[9] = {0};  // Resultant matrix
    
        multiply_matrices(A, B, C, n);
    
        std::cout << "Matrix C (result):\n";
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                std::cout << *(C + i * n + j) << " ";
            }
            std::cout << std::endl;
        }
    
        return 0;
    }
    

    问题:

    我使用指针算术来访问矩阵的元素,但乘法结果不正确。结果是错误的,而不是产生正确的矩阵乘积。

    输出不正确:

    Matrix C (result):
    72 0 0 
    207 0 0
    342 0 0
    

    预期产量:

    矩阵相乘的预期输出:

    Matrix A:
    1 2 3
    4 5 6
    7 8 9
    
    Matrix B:
    9 8 7
    6 5 4
    3 2 1
    

    应该是:

    Matrix C (result):
    30 24 18
    84 69 54
    138 114 90
    

    问题:

    有人能解释一下我做错了什么,为什么乘法结果不正确吗?我怀疑使用指针访问矩阵元素的方式可能存在问题。

    1 回复  |  直到 2 月前
        1
  •  4
  •   wohlstad    2 月前

    在累积输出值时,您遇到了与矩阵索引计算相关的错误。

    这条线:

    *(C + i * n) += *(A + i * n + k) * *(B + k * n + j);
    

    应改为:

    //----------vvv-----------------------------------------
    *(C + i * n + j) += *(A + i * n + k) * *(B + k * n + j);
    

    也就是说,你需要添加第二个索引( j ),就像在最内层循环之前将输出元素清零一样( *(C + i * n + j) = 0; ).

    Live demo 1

    关于风格的说明:
    对于数组 a 和索引 i , *(a+i) 相当于 a[i] ,但许多人认为后者更具可读性(@catnip也是如此 commented below ).
    因此,你可以改变 *(C + i * n + j) C[i * n + j] (并对其他数组访问应用类似的更改)。
    这在下面的第二个现场演示中得到了演示:
    Live demo 2

    附注:
    为了“捕获”此类错误,建议使用调试器。
    请参阅: What is a debugger and how can it help me diagnose problems? .