编译报错:下标值非数组/指针/向量问题原因及解决方法咨询
报错原因与解决方法
为什么会出现这个错误?
这个报错我太熟了,核心问题出在两个地方:
参数类型不匹配,二维下标使用错误
你的getMax函数接收的是int *diam——这是一个一维整数指针,但你在函数里直接用了diam[r][c]这种二维数组的下标写法。在C语言里,只有当变量是二维数组、或者指向一维数组的指针(比如int (*diam)[n])时,才能用[r][c]的方式访问元素。一维指针没有第二维的长度信息,编译器根本不知道怎么解析diam[r][c],所以直接抛出了这个错误。调用函数时传参错误
你在main里调用getMax(&diam[m][n], m, n),这里的&diam[m][n]是数组越界的地址!假设diam是m行n列的二维数组,它的有效下标范围是diam[0..m-1][0..n-1],diam[m][n]已经超出了数组的内存范围,传递这个地址给函数后,后续的内存访问全是非法的,还会引发更多未知问题。
两种解决方法,任选其一即可
方法一:修改函数参数为二维数组(推荐,代码更直观)
如果你的编译器支持C99及以上(现在大部分编译器都支持),可以直接用变长数组(VLA)作为参数,这样就能直接用[r][c]访问元素:
// 调整参数顺序,把m、n放在前面,方便编译器推导数组维度 int getMax(int m, int n, int diam[m][n]) { ... for(int c=n-1; c>=0; c--) { for (int r=0; r<m; r++) { // 现在可以正常使用diam[r][c]了 diamTable[r][c] = diam[r][c] + max(right, max(rightup, rightdown)); } } } // 驱动代码里的调用改成这样: int main(int argc, char* v[]) { ... printf("%d\n", getMax(m, n, diam)); // 直接传递数组名,它会退化为指向首元素的指针 return 0; }
如果编译器不支持变长数组,也可以用指向一维数组的指针作为参数(需要n是编译期常量):
// 假设n是已知的常量,比如#define N 10 int getMax(int m, int (*diam)[N]) { ... // 同样可以用diam[r][c]访问 }
方法二:用一维指针手动计算内存偏移
如果必须保留int *diam的参数类型,那你需要把二维下标转换成一维的内存偏移量——因为二维数组在内存里是连续存储的,diam[r][c]等价于*(diam + r*n + c):
int getMax(int *diam, int m, int n) { ... for(int c=n-1; c>=0; c--) { for (int r=0; r<m; r++) { // 替换diam[r][c]为手动计算的偏移 diamTable[r][c] = *(diam + r*n + c) + max(right, max(rightup, rightdown)); } } } // 驱动代码里的调用要传递正确的数组首地址: int main(int argc, char* v[]) { ... printf("%d\n", getMax(&diam[0][0], m, n)); // 或者直接传diam,效果一样 return 0; }
内容的提问来源于stack exchange,提问作者user12092018
相关产品推荐
相关产品推荐

