调用含多维数组的函数报错:无法转换int (*)[n2]至int (*)[100]
问题分析与修复
错误原因
你这代码碰到的类型不匹配错误,说白了就是函数参数的二维数组类型和main里定义的数组根本不兼容:
- 函数
compute_minor_sums声明的参数是int a[][MAX],在C++里这会被解析成int (*a)[MAX]——也就是指向包含100个int的数组的指针,要求传入的二维数组第二维必须是100。 - 但你在main里用
int a[n1][n2]定义的是变长数组(VLA),这本身就不是C++标准里的东西(只有GCC这类编译器作为扩展支持),而且它的第二维是运行时才确定的n2,和函数要求的固定100对不上,所以编译器直接报错说转不了类型。
另外代码还有俩隐藏坑:
row[n2]和col[n1]没初始化,直接累加的话会读内存里的垃圾值,算出来的结果肯定不对。- main里调用完计算函数后没输出B数组的逻辑,就算算对了你也看不到结果。
修复方案
给你三个可行的修复思路,按需选:
方案1:用动态分配数组(符合C++标准)
放弃变长数组,用new手动分配二维数组,同时把函数参数改成指针的指针,这样就能支持任意大小的矩阵了:
#include <iostream> #define MAX 100 using namespace std; void compute_minor_sums(int** a, int** B, int n1, int n2) { int sum = 0; // 初始化行和、列和数组,()代表把所有元素设为0 int* row = new int[n1](); int* col = new int[n2](); // 读矩阵a的元素,顺便算总和 for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cin >> a[i][j]; sum += a[i][j]; } } // 算每行、每列的和 for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { row[i] += a[i][j]; col[j] += a[i][j]; } } // 计算余子式矩阵B for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { B[i][j] = sum - row[i] - col[j] + a[i][j]; } } // 用完临时数组记得释放内存,避免泄漏 delete[] row; delete[] col; } int main() { int n1, n2; cin >> n1 >> n2; // 动态分配二维数组a和B int** a = new int*[n1]; int** B = new int*[n1]; for (int i = 0; i < n1; i++) { a[i] = new int[n2](); B[i] = new int[n2](); } compute_minor_sums(a, B, n1, n2); // 输出计算好的余子式矩阵 cout << "余子式矩阵:" << endl; for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cout << B[i][j] << " "; } cout << endl; } // 释放动态分配的内存,别忘 for (int i = 0; i < n1; i++) { delete[] a[i]; delete[] B[i]; } delete[] a; delete[] B; return 0; }
方案2:用vector容器(更省心)
如果允许用STL的话,vector会自动帮你管理内存,不用手动new和delete,代码更简洁:
#include <iostream> #include <vector> using namespace std; void compute_minor_sums(vector<vector<int>>& a, vector<vector<int>>& B, int n1, int n2) { int sum = 0; // 直接初始化行和、列和数组为0 vector<int> row(n1, 0); vector<int> col(n2, 0); for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cin >> a[i][j]; sum += a[i][j]; } } for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { row[i] += a[i][j]; col[j] += a[i][j]; } } for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { B[i][j] = sum - row[i] - col[j] + a[i][j]; } } } int main() { int n1, n2; cin >> n1 >> n2; // 直接创建n1行n2列的vector,默认初始化为0 vector<vector<int>> a(n1, vector<int>(n2)); vector<vector<int>> B(n1, vector<int>(n2)); compute_minor_sums(a, B, n1, n2); // 输出结果 cout << "余子式矩阵:" << endl; for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cout << B[i][j] << " "; } cout << endl; } return 0; }
方案3:固定第二维大小(只适合n2≤100的场景)
如果你的使用场景里n2永远不会超过100,可以修改main里的数组定义,把第二维固定成MAX,同时加个判断防止输入超过范围:
#include <iostream> #define MAX 100 using namespace std; void compute_minor_sums(int a[][MAX], int B[][MAX], int n1, int n2) { int sum = 0; // 初始化行和、列和数组为0 int row[n1] = {0}; int col[n2] = {0}; for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cin >> a[i][j]; sum += a[i][j]; } } for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { row[i] += a[i][j]; col[j] += a[i][j]; } } for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { B[i][j] = sum - row[i] - col[j] + a[i][j]; } } } int main() { int n1, n2; cin >> n1 >> n2; // 加个判断,防止n2超过MAX导致数组越界 if (n2 > MAX) { cout << "n2不能超过" << MAX << endl; return 1; } // 第二维固定为MAX int a[n1][MAX], B[n1][MAX]; compute_minor_sums(a, B, n1, n2); // 输出结果 cout << "余子式矩阵:" << endl; for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { cout << B[i][j] << " "; } cout << endl; } return 0; }
重点提醒
- C++标准里根本没有变长数组(VLA),虽然有些编译器支持,但跨平台容易出问题,尽量别用。
- 二维数组作为函数参数时,第二维必须是编译期就能确定的常量,要是想支持动态大小,就用指针的指针或者vector。
- 局部数组如果不初始化,里面都是内存里的垃圾值,必须显式初始化,不然计算结果全错。
内容的提问来源于stack exchange,提问作者Sarala .D
相关产品推荐
相关产品推荐

