C语言基本笔记(10)—— 函数

函数定义与声明

  • 定义:实现函数功能的具体代码块
  • 声明:告知编译器函数签名(返回类型、参数列表)
// 声明(头文件中)
int add(int a, int b); 

// 定义(源文件中)
int add(int a, int b) {
    return a + b;
}

易错点:忘记声明导致编译错误(隐式声明警告)

参数传递方式

类型 行为 内存影响 典型场景
值传递 传递参数副本 不影响原数据 简单数据类型(int, char)
指针传递 传递内存地址 直接修改原数据 数组、结构体修改
数组传递 退化为指针(等价于指针传递) 可修改数组元素 数组处理函数

可变参数函数

#include <stdarg.h>
int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    int total = 0;
    for(int i=0; i<count; i++) {
        total += va_arg(args, int);
    }
    va_end(args);
    return total;
}

坚决杜绝可变参函数在开发中应用
易错点:类型安全缺失(错误类型访问导致未定义行为)

在嵌入式开发场景下需要主要的点

  1. 栈空间管理

    • 局部变量过大导致栈溢出(常见于递归或大型数组)
    • 解决方案:使用静态变量或堆内存(malloc需谨慎)
  2. 中断服务函数(ISR)

    • 不可重入性:避免在ISR和非ISR代码中共享非原子变量
    • 硬件约束:某些平台限制ISR的参数和返回值
  3. 函数可重入性

    • 问题:函数若使用静态变量,在多线程/中断环境下不安全
    • 解决方法:改用线程局部存储或避免静态变量
  4. 值传递 vs 指针传递

    • 问题:传递给函数的是原数据的副本还是原数据的地址、修改的是副本还是原数据
    • 解决方法:根据是否需要修改原数据来决定传入参数的类型是指针还是值。
  5. 返回栈内存指针

    • 问题:返回局部变量的地址,导致返回值错误
    • 解决方法:使用malloc()等函数分配内存。
  6. 函数指针类型不匹配

    • 问题:
    float add_float(float a, float b) { return a+b; }
    
    int main() {
        // 错误!类型不匹配但可能编译通过
        int (*wrong_ptr)(int, int) = (int (*)(int,int))add_float; 
        printf("%d", wrong_ptr(1, 2)); // 输出不可预测
    }
    
    • 解决方法:使用严格类型转换、坚决避免隐式类型转换。
posted @ 2025-04-28 10:48  故渊Y  阅读(33)  评论(0)    收藏  举报