C语言数组传参报错:double实参与double*形参不兼容问题
错误原因
- 直接触发编译报错的是传参类型不匹配:你调用
ask函数时传入的第三个实参是prices[index],这是数组里单个double类型的元素;而C语言中函数形参写为数组形式时,会被自动调整为对应类型的指针,也就是形参double prices[index]的实际类型是double*,double类型的值无法传给double*类型的形参,因此编译器报错。 - 代码还存在多处会导致运行崩溃的逻辑问题:
- 变长数组定义非法:
main里定义double prices[index]时index值为-1,C语言要求数组长度必须为正整数,负长度属于未定义行为;且栈上数组长度在定义时就固定,根本无法实现“动态扩展”的需求,后续写入prices[index+1]属于典型的越界访问内存。 - 值传递导致输入逻辑失效:
ask的形参ques、price、index都是值传递,函数内scanf读取的值只会写入局部副本,不会修改main里的原始变量,等于白读。 - 分支逻辑错误:switch的
case 'y'分支没有写break,执行完赋值后会直接穿透到case 'n'分支,无论输入y还是n都会调用main();而C标准禁止程序主动递归调用main函数,且该递归没有终止条件,最终必然触发栈溢出。 - 输入处理有漏洞:
scanf("%c")会读取输入缓冲区残留的换行符,导致选项读取完全不符合预期。
- 变长数组定义非法:
修复方法
- 不要用栈上固定长度数组实现可变长度列表,改用
malloc/realloc在堆上分配可动态调整大小的内存。 - 传数组时直接传数组名(即首元素地址)匹配指针类型形参,需要在函数内修改外部变量时传入对应变量的指针。
- 用循环替代递归
main的写法实现重复交互,switch每个分支末尾加break避免穿透。 - 每次读入字符前清空输入缓冲区的残留换行,避免读入无效字符。
修正后的可运行代码如下:
#include <stdio.h> #include <stdlib.h> int main() { int capacity = 2; // 初始分配的数组容量 int count = 0; // 已存储的商品数量 // 初始分配堆内存 double* prices = (double*)malloc(capacity * sizeof(double)); if (prices == NULL) { printf("内存分配失败\n"); return 1; } char ques; double price; while (1) { printf("请输入商品价格:"); scanf("%lf", &price); // 容量不足时扩展内存 if (count >= capacity) { capacity *= 2; double* temp = (double*)realloc(prices, capacity * sizeof(double)); if (temp == NULL) { printf("内存扩展失败\n"); free(prices); return 1; } prices = temp; } prices[count++] = price; // 清空输入缓冲区残留 while (getchar() != '\n'); printf("是否继续添加商品(y/n):"); scanf("%c", &ques); if (ques == 'n') break; while (getchar() != '\n'); } // 输出结果 printf("已录入的商品价格:\n"); for (int i = 0; i < count; i++) { printf("第%d件:%.2lf\n", i+1, prices[i]); } free(prices); // 释放堆内存避免泄漏 return 0; }
内容的提问来源于stack exchange,提问作者alahmar alrafik
相关产品推荐
相关产品推荐

