1. 主页 > 大智慧

C程序函数调用常见错误排查:快速掌握正确写法


哎,你是不是经常遇到这种情况?明明照着教程写的代码,一运行就报错,控制台蹦出来一堆看不懂的英文提示?别慌!今天咱们就来扒一扒函数调用时那些"坑爹"的常见错误,保证你看完就能化身"捉虫小能手"。


为啥我的函数死活不执行?可能是没打招呼就叫人干活

老铁们注意啦,C语言讲究"先声明后使用",这就好比你要找同事帮忙,得先跟人家打个招呼对吧?来看这段典型翻车代码:

c复制
int main() {
    say_hello();  // 这里会报错!
    return 0;
}

void say_hello() {
    printf("你好呀!");
}

??重点来了??:编译器是从上往下读代码的,看到say_hello()的时候根本不认识这函数。正确姿势有两种:

  1. 把函数定义挪到main()前面
  2. 在文件开头加个声明:void say_hello();

就像你去别人家串门得先敲门,不打招呼直接推门进去,人家当然要报警啦!


参数对不上号怎么办?类型匹配要较真

上周有个小伙伴问我:"哥,我这计算器程序怎么算1+1等于-32876啊?"我一看代码差点笑喷:

c复制
int add(int a, int b) {
    return a + b;
}

int main() {
    float result = add(3.14, 2.71);  // 这里埋雷了
    printf("%f", result);
}

??问题出在哪???函数参数是int类型,结果传了浮点数进去。编译器会偷偷做类型转换,3.14变成3,2.71变成2,结果输出5.00——这和预期完全不符啊!
??正确操作??:

  • 要么改函数参数为float类型
  • 要么调用时强制转换:add((int)3.14, (int)2.71)
    记住:C语言是死心眼,说好要整数就别给小数,跟女朋友说要吃火锅最后带她去喝粥能行吗?

数组传参怎么老丢数据?其实你传了个"替身"

新手最容易栽的坑就是数组传递。来看这段经典错误:

c复制
void change_array(int arr[]) {
    arr[0] = 100;
}

int main() {
    int nums[3] = {1,2,3};
    change_array(nums);
    printf("%d", nums[0]);  // 输出100没问题啊?
}

等等!这里好像没问题?别急,把代码改一下:

c复制
void change_size(int arr[]) {
    printf("数组大小:%d\n", sizeof(arr));  // 输出8(指针大小)
}

??发现问题没???在函数里数组会退化成指针,根本拿不到真实长度。下次要处理数组,记得把长度当参数传进去:

c复制
void safe_change(int arr[], int length) {
    // 现在知道操作范围了
}

这就好比你去快递站取件,单说"我要拿快递"人家肯定懵,得告诉人家取件码对不对?


递归调用卡死怎么办?先检查有没有"逃生出口"

去年我帮学弟调试代码到凌晨3点,就栽在这个坑里。他写的阶乘函数长这样:

c复制
int factorial(int n) {
    return n * factorial(n-1);  // 无限循环警告!
}

??缺了啥???终止条件啊!就像坐电梯得有个顶层,不然就冲上天了。正确写法:

c复制
int factorial(int n) {
    if(n <= 1) return 1;  // 紧急出口
    else return n * factorial(n-1);
}

建议每个递归函数都先写终止条件,就像开车先系安全带,可能一辈子用不上,但用上一次就救命。


多文件调用出问题?可能是"接头暗号"对不上

最近有个做智能家居的哥们找我,说他的温控程序编译通过但运行异常。最后发现问题出在这:

c复制
// sensor.c
float get_temperature() { ... }

// main.c
extern int get_temperature();  // 这里类型错了!

??后果多严重???温度25.5℃被解释成整型,直接变成25℃!正确做法是保持声明一致:

c复制
// 统一在头文件声明
extern float get_temperature(void);

这就好比外卖小哥打电话说"到楼下了",你说"放电梯里",结果他放货梯你等客梯,能拿到外卖才见鬼了。


我在深圳搞物联网开发那会儿,有个项目因为函数返回值没处理,导致智能灯半夜自动亮起,客户差点以为是闹鬼。现在养成了条件反射般的习惯:写函数前先画流程图,声明后马上写单元测试。建议新手准备个"错题本",把遇到的每个报错信息都记下来,三个月后你会回来感谢我的——真的,这比死记硬背管用多了!

本文由嘻道妙招独家原创,未经允许,严禁转载