814 字
2 分钟
【C】函数
2026-05-19

函数基础#

声明与定义#

// 声明(原型)
int add(int a, int b);
// 定义
int add(int a, int b) {
return a + b;
}
// 调用
int sum = add(3, 5);
  • 函数须先声明再调用(或定义写在调用之前)
  • void func(void) 表示无参数void func() 在 C 中表示参数未声明(旧式,不推荐)

参数传递#

C 语言只有传值调用:形参是实参的副本。若需修改实参,须传指针

void swap_wrong(int a, int b) { /* 无法交换调用者的变量 */ }
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}

返回值#

  • return 返回;void 函数无返回值
  • 不要返回指向局部非静态变量的指针(函数返回后栈帧销毁,成为悬空指针)

栈帧的创建与销毁(概念)#

函数每次被调用时,通常在上分配一帧(stack frame),存放:

  • 返回地址
  • 保存的寄存器(如帧指针 EBP/RBP、栈顶 ESP/RSP,具体名称依架构而定)
  • 局部变量、临时空间
  • 参数(调用约定决定参数在栈上还是寄存器)

调用过程(简化):

  1. 调用方把参数入栈(或放寄存器)
  2. 跳转到被调函数,保存旧帧指针,建立新帧指针
  3. 为局部变量分配栈空间
  4. 执行函数体
  5. 恢复寄存器与栈指针,返回到调用方

函数返回后,该帧内存可被下一次调用覆盖,故局部变量地址不可长期持有。

静态函数#

static int helper(void) { return 0; }

static 函数仅在当前翻译单元(.c 文件)内可见,避免与其他文件的同名函数链接冲突。

递归#

  • 函数直接或间接调用自身
  • 必须有终止条件,否则无限递归导致栈溢出
  • 适合问题可分解为同结构子问题(如阶乘、遍历树)
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}

函数指针#

int add(int a, int b) { return a + b; }
int (*fp)(int, int); // 声明:fp 是指向函数的指针
fp = add; // 或 fp = &add;
int r = fp(3, 5); // 通过指针调用

声明格式:*返回类型 (指针名)(参数类型列表)

指针函数#

函数的返回值是指针类型:

int *make_array(int n); // 返回 int*

返回值不能指向已销毁的局部变量;可返回静态存储、堆内存或调用者提供的缓冲区。

回调函数#

将函数指针作为参数传入,在特定时机由被调方调用,实现「机制与策略」分离。

typedef int (*callback_t)(int);
int process(int x, callback_t cb) {
return cb(x);
}

常用于事件驱动、库扩展点;执行顺序由事件触发决定,而非写死的调用顺序。

相关概念#

  • 事件驱动:程序等待事件(输入、定时器等)再响应,而非纯顺序执行
  • 异步:发起操作后不阻塞等待完成,完成后通过回调等通知(C 中常配合线程或 I/O 多路复用)

内联函数 inline#

static inline int max(int a, int b) {
return a > b ? a : b;
}

建议将 inline 函数放在头文件中并配合 static,避免多重定义。

  • 编译器可能把函数体展开到调用处,减少调用开销
  • 适合短小、频繁调用的函数;函数体过大、含复杂循环或递归时不宜内联
  • inline 只是建议,编译器可忽略

可变参数函数#

#include <stdarg.h>
int sum(int count, ...) {
va_list ap;
va_start(ap, count);
int total = 0;
for (int i = 0; i < count; i++)
total += va_arg(ap, int);
va_end(ap);
return total;
}
  • 至少有一个固定命名参数,用于 va_start 定位可变部分
  • 典型例子:printf;类型与个数须由固定参数或约定推断,否则未定义
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【C】函数
https://lysj.work/posts/studynotes/c/c函数/
作者
Sekiro
发布于
2026-05-19
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录