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' —— 对应错误1
  • passing argument 2 of 'rect_area' makes double from integer without a cast —— 对应错误2
  • passing 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

判定标准:程序正常退出(无崩溃),三行输出与上述预期完全一致,且编译过程无警告,即判定调试通过。

函数参数错误定位与修正流程 错误1:参数个数不足 调用:rect_area(3.5) 定义:rect_area(double, double) ✗ 缺少第2个参数 ✓ 改为 rect_area(3.5, 2.0) 错误2:参数类型不匹配 调用:rect_area(2, 3) 定义:rect_area(double, double) ✗ int→double 隐式转换 ✓ 改为 rect_area(2.0, 3.0) 错误3:指针与值混用 调用:repeat_str(buf, ch, 3) 定义:repeat_str(char*, const char*, int) ✗ ch是char,非char* ✓ 改为 repeat_str(buf, "A", 3) 验证流程 步骤1 gcc -Wall 编译 步骤2 确认无警告 步骤3 运行 ./test 判定 输出匹配预期