如何在C语言中实现支持静态变量与任意矩阵尺寸的矩阵乘法函数并修复现有代码错误
修复矩阵乘法代码并实现任意尺寸支持 + 静态变量功能
首先,咱们先拆解原代码里的几个关键错误:
1. 类型不匹配问题
原mat_mul函数的参数是double** A,但主函数里传递的是二维栈数组(比如double A[3][3]),这两种类型在C里是不兼容的:
- 二维数组在内存里是连续存储的,它的类型本质是
double (*)[3](指向3个double的指针),而不是double**(指向指针的指针)。直接传递会导致编译错误,甚至运行时内存访问错误。
2. 结果矩阵初始化隐患
原代码里主函数的C虽然初始化了{0},但如果是任意尺寸的动态矩阵,这个初始化逻辑无法复用,会导致累加计算得到错误结果。
3. 硬编码固定尺寸
原代码的矩阵都是写死的3×3,无法处理任意M×K与K×N的矩阵相乘场景。
接下来,咱们一步步改造代码,实现任意尺寸矩阵乘法+静态变量(这里以统计函数调用次数为例,你也可以根据需求改成其他用途,比如缓存最近计算的矩阵尺寸等):
方案说明
- 用动态内存分配创建任意尺寸的矩阵,摆脱栈数组的尺寸限制
- 修正函数参数类型,让动态矩阵与函数参数完全匹配
- 添加静态变量,实现跨调用的状态保存
- 完善结果矩阵初始化、内存释放、矩阵打印等辅助逻辑,让代码更健壮
完整修复改造后的代码
#include <stdio.h> #include <stdlib.h> // 带有静态变量的任意尺寸矩阵乘法函数 void mat_mul(double** A, double** B, double** C, int M, int N, int K) { // 静态变量:统计矩阵乘法的调用次数,程序运行期间只会初始化一次 static int mul_count = 0; mul_count++; printf("这是第 %d 次调用矩阵乘法函数\n", mul_count); // 初始化结果矩阵C为0,确保累加计算正确 for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { C[i][j] = 0.0; } } // 矩阵乘法核心逻辑:M×K 的A 乘 K×N 的B,得到 M×N 的C for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { for (int k = 0; k < K; k++) { C[i][j] += A[i][k] * B[k][j]; } } } } // 辅助函数:创建M×N的动态矩阵 double** create_matrix(int M, int N) { double** mat = (double**)malloc(M * sizeof(double*)); if (!mat) { perror("malloc failed for matrix rows"); exit(EXIT_FAILURE); } for (int i = 0; i < M; i++) { mat[i] = (double*)malloc(N * sizeof(double)); if (!mat[i]) { perror("malloc failed for matrix columns"); // 内存泄漏处理:释放已分配的行 for (int j = 0; j < i; j++) { free(mat[j]); } free(mat); exit(EXIT_FAILURE); } } return mat; } // 辅助函数:打印M×N的矩阵 void print_matrix(double** mat, int M, int N, const char* name) { printf("矩阵 %s:\n", name); for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { printf(" %.2lf", mat[i][j]); } printf("\n"); } } // 辅助函数:释放M×N的动态矩阵 void free_matrix(double** mat, int M) { for (int i = 0; i < M; i++) { free(mat[i]); } free(mat); } int main() { // 可以任意修改矩阵尺寸,只要满足A的列数=B的行数即可 int M = 2, K = 3, N = 4; // 创建动态矩阵 double** A = create_matrix(M, K); double** B = create_matrix(K, N); double** C = create_matrix(M, N); // 初始化矩阵A for (int i = 0; i < M; i++) { for (int j = 0; j < K; j++) { A[i][j] = i * K + j + 1.0; } } // 初始化矩阵B for (int i = 0; i < K; i++) { for (int j = 0; j < N; j++) { B[i][j] = i * N + j + 1.0; } } // 打印输入矩阵 print_matrix(A, M, K, "A"); print_matrix(B, K, N, "B"); // 调用矩阵乘法 mat_mul(A, B, C, M, N, K); // 打印结果矩阵 print_matrix(C, M, N, "C"); // 释放内存,避免泄漏 free_matrix(A, M); free_matrix(B, K); free_matrix(C, M); return 0; }
关键改造点解释
- 类型匹配修正:改用
double**类型的动态矩阵,和函数参数完全兼容,解决了原代码的类型不匹配问题。 - 静态变量的使用:
static int mul_count在函数第一次调用时初始化,之后每次调用都会保留之前的值,实现了跨调用的状态记录。 - 任意尺寸支持:通过
create_matrix函数动态创建任意M×N的矩阵,主函数里可以自由修改M、K、N的值,只要符合矩阵乘法规则即可。 - 内存安全:添加了
free_matrix函数释放动态内存,create_matrix里还做了内存分配失败的错误处理,避免内存泄漏。 - 结果可靠性:在
mat_mul里先将C的所有元素置0,确保累加计算的正确性,不会因为内存垃圾值导致错误结果。
内容的提问来源于stack exchange,提问作者Song
相关产品推荐
相关产品推荐

