C语言传空指针作为函数参数时解引用星号报错问题排查
问题背景
任务要求:接收用户输入数值填充二维数组,调用自定义stats()函数计算数组指定行的最大值、最小值、平均值统计指标。
函数声明如下:
int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg)
参数定义:
ptr:指向二维矩阵的指针width、height:矩阵的宽、高尺寸row_id:待统计分析的行索引max、min、avg:指向存储统计结果变量的指针,用于回写计算得到的最大值、最小值、平均值
使用如下语句调用函数时:
stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL);
触发编译错误:
error: invalid type argument of unary '*' (have 'int')
附原始出错完整代码:
#include <stdio.h> int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg) { int j, vmax,vmin; int max = &vmax; int min = &vmin; int i = row_id; int m = *ptr; for(j = 0; j<5; j++){ if(m[i][j]>max) { max = m[i][j] ; j++; else j++; } } printf("%d", max); return 0; } int main(void){ int n, i, j, vmin, vmax; // vmax - value of the maximum int min = &vmin; // min - pointer to the minimum int max = &vmax; float vavg; int avg = &vavg; int m[5][5]; for(i = 0; i<5; i++) { for(j = 0; j<5; j++) { printf("ENTER A NUMBER: "); scanf("%d", &n); m[i][j] = n; } } int ptr = &m; stats(*ptr, 5,5,2, *max = NULL, *min = NULL, *avg=NULL); return 0; }
错误根因
原始代码存在多处指针使用、语法、逻辑错误,直接触发编译报错的核心原因是指针类型定义错误:
- main函数中将所有指针变量(
max/min/avg/ptr)定义为普通int类型,对非指针类型的int值做解引用*操作,就会抛出invalid type argument of unary '*'错误。例如int max = &vmax写法错误,&vmax是int类型指针,必须定义为int *max = &vmax才能存储地址。 - 其余连锁错误包括:
- 函数传参类型不匹配:
stats第一个参数要求传入指向长度为5的int数组的指针,传入*ptr是解引用后的一维数组,类型不符;后三个参数要求传入指针,代码中写*max = NULL是给max指向的int值赋值为NULL,并非传递指针本身。 stats函数内部变量重定义:参数列表已经定义了int* max、int* min形参,函数内部又重新定义同名int类型变量,类型不匹配且会覆盖形参。- 语法错误:
if-else结构书写错误,else被错误写在if代码块内部;循环中多余的j++会导致跳过数组元素,遍历不完整。 - 逻辑缺失:没有实现最小值、平均值计算逻辑,也未通过传入的指针将计算结果回写到主函数。
- 函数传参类型不匹配:
修复后可运行代码
#include <stdio.h> int stats(int (*ptr)[5], int width, int height, int row_id, int* max, int* min, float *avg) { // 参数合法性校验 if (row_id < 0 || row_id >= height || max == NULL || min == NULL || avg == NULL) { return -1; } int j; int sum = 0; // 初始化最大最小值为当前行第一个元素 *max = ptr[row_id][0]; *min = ptr[row_id][0]; sum = ptr[row_id][0]; for(j = 1; j < width; j++){ int cur_val = ptr[row_id][j]; if (cur_val > *max) { *max = cur_val; } if (cur_val < *min) { *min = cur_val; } sum += cur_val; } *avg = (float)sum / width; return 0; } int main(void){ int n, i, j, vmin, vmax; int *min = &vmin; // 正确定义int类型指针 int *max = &vmax; float vavg; float *avg = &vavg; // 正确定义float类型指针 int m[5][5]; for(i = 0; i < 5; i++) { for(j = 0; j < 5; j++) { printf("ENTER A NUMBER: "); scanf("%d", &n); m[i][j] = n; } } // 正确传参:二维数组名自动退化为指向第一行的指针,匹配形参类型;指针参数直接传变量名即可 int res = stats(m, 5, 5, 2, max, min, avg); if (res == 0) { printf("第2行统计结果:最大值=%d,最小值=%d,平均值=%.2f\n", vmax, vmin, vavg); } else { printf("参数非法,计算失败\n"); } return 0; }
关键修改说明
- 所有指针变量定义时补充
*标识,匹配对应类型:存储int变量地址的指针定义为int*,存储float变量地址的指针定义为float*,无需额外定义中转ptr变量,直接传入二维数组名m即可匹配stats函数第一个形参的类型要求。 - 函数调用时,指针类型参数直接传入指针变量名,不要做解引用操作。
- 修正
stats函数内部的if-else语法错误,补全最大值、最小值、平均值的计算逻辑,通过解引用传入的指针将结果回写到主函数的变量中。 - 增加参数合法性校验,避免数组越界、空指针访问等问题。
内容的提问来源于stack exchange,提问作者kazimierz___tetmajer
相关产品推荐
相关产品推荐

