2. 解决函数参数传递错误
任务说明
本次案例聚焦于函数调用时参数个数或类型不匹配的调试。你将拿到一段包含三类典型错误的C语言代码:参数个数不足、参数类型不匹配、以及指针与值混用。目标是通过编译警告、运行时现象和代码审查定位问题,并修正调用方式使程序输出正确结果。
问题代码
#include <stdio.h>
#include <string.h>
// 计算矩形面积
double rect_area(double width, double height) {
return width * height;
}
// 将字符串重复拼接n次到dest(dest需足够大)
void repeat_str(char *dest, const char *src, int n) {
dest[0] = '\0';
for (int i = 0; i < n; i++) {
strcat(dest, src);
}
}
int main() {
// 错误1:参数个数不足(少传height)
double area = rect_area(3.5);
printf("矩形面积: %.2f\n", area);
// 错误2:参数类型不匹配(第二个参数应为double,却传了int)
double area2 = rect_area(2, 3);
printf("矩形面积2: %.2f\n", area2);
// 错误3:指针与值混用(repeat_str期望char*,却传了char类型)
char buf[64];
char ch = 'A';
repeat_str(buf, ch, 3);
printf("重复字符串: %s\n", buf);
return 0;
}
调试过程
第一步:编译观察警告
使用 gcc -Wall -o test test.c 编译上述代码,编译器会给出以下关键警告:
too few arguments to function 'rect_area'—— 对应错误1passing argument 2 of 'rect_area' makes double from integer without a cast—— 对应错误2passing argument 2 of 'repeat_str' makes pointer from integer without a cast—— 对应错误3
这些警告直接指出了参数个数和类型的问题。
第二步:分析运行时现象
即使忽略警告强制编译运行,错误1会因缺少参数导致函数读取栈上不确定值,面积结果随机;错误2中整数3被隐式转换为double后计算结果仍为6.00(碰巧正确,但属于隐患);错误3将字符'A'(ASCII码65)当作地址传入,程序会在访问非法内存时崩溃(Segmentation fault)。
第三步:逐一定位与修正
修正原则:确保调用时参数个数与函数定义一致,类型匹配或显式转换,指针参数必须传入地址。
修正后代码
#include <stdio.h>
#include <string.h>
double rect_area(double width, double height) {
return width * height;
}
void repeat_str(char *dest, const char *src, int n) {
dest[0] = '\0';
for (int i = 0; i < n; i++) {
strcat(dest, src);
}
}
int main() {
// 修正1:补全第二个参数
double area = rect_area(3.5, 2.0);
printf("矩形面积: %.2f\n", area);
// 修正2:将int参数显式转换为double
double area2 = rect_area(2.0, 3.0);
printf("矩形面积2: %.2f\n", area2);
// 修正3:传入字符串字面量(char*类型)
char buf[64];
repeat_str(buf, "A", 3);
printf("重复字符串: %s\n", buf);
return 0;
}
验证方法与判定标准
编译验证:执行 gcc -Wall -o test test.c,若无任何警告或错误,说明参数个数与类型已匹配。
运行验证:执行 ./test,观察输出。预期输出为:
矩形面积: 7.00
矩形面积2: 6.00
重复字符串: AAA
判定标准:程序正常退出(无崩溃),三行输出与上述预期完全一致,且编译过程无警告,即判定调试通过。