函數是 C 程序的基本模塊單元,所有計算任務最終都由函數執行。本文系統梳理函數定義語法、三種參數傳遞機制(值傳遞/地址傳遞/引用傳遞)、遞歸思想、標準庫常用函數及實戰避坑指南,助你構建清晰、可復用、高性能的代碼架構。
// 完整函數定義
返回類型 函數名(參數列表) {
// 函數體
return 表達式; // 無返回值用 void
}
// 聲明(原型):通常放在頭文件 .h 中
返回類型 函數名(參數類型列表); // 參數名可省略
// 示例:計算兩數之和
int add(int x, int y) {
return x + y;
}
// 調用
int result = add(3, 5); // 實參 3, 5 傳遞給形參 x, y
關鍵規則:
inline/static inline) 可消除開銷,適合短小高頻函數。這是面試必考、Bug 高發核心區,必須徹底理解內存與語義差異。
void swap_val(int x, int y) {
int tmp = x; x = y; y = tmp; // 僅修改局部副本
}
int a=4, b=6;
swap_val(a, b); // a,b 不變!
int x = a;),函數內操作獨立內存。void swap_ptr(int *px, int *py) {
int tmp = *px; *px = *py; *py = tmp; // 解引用修改實參內存
}
int a=4, b=6;
swap_ptr(&a, &b); // a=6, b=4 成功交換!
int *px = &a;),通過解引用 *px 訪問實參內存。// 僅 C++ 有效
void swap_ref(int &x, int &y) { // 形參是實參的別名
int tmp = x; x = y; y = tmp;
}
int a=4, b=6;
swap_ref(a, b); // 調用語法同值傳遞,效果同地址傳遞
注意:C 語言沒有引用類型,請勿混淆。C 中模擬引用語義只能用指針。
// 階乘:n! = n * (n-1)!
unsigned long long factorial(int n) {
if (n <= 1) return 1; // 基線條件
return n * factorial(n - 1); // 遞歸步驟
}
// 斐波那契(教學用,實際用迭代/矩陣快速冪)
int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2); // 指數級複雜度,僅示意
}
遞歸三要素:基線條件、遞歸調用、問題規模遞減。棧溢出風險:深度遞歸耗盡棧空間,尾遞歸優化 (TCO) 依賴編譯器支持(GCC -O2 可優化)。
| 頭文件 | 函數 | 功能 | 關鍵點 |
|---|---|---|---|
string.h | strcpy(dst, src) | 字符串拷貝 | 目標空間需足夠,無長度檢查(不安全) |
strlen(str) | 字符串長度 | 不含 \0,O(n) 掃描 | |
strstr(haystack, needle) | 子串查找 | 返回首次出現地址,未找到返回 NULL | |
stdlib.h | atoi(str) | 字符串轉整數 | 無錯誤檢測,推薦 strtol |
stdio.h | scanf/fscanf/sscanf | 格式化輸入 | 返回成功匹配項數,需檢查返回值 |
printf/fprintf/sprintf | 格式化輸出 | 格式字符串漏洞風險,用戶輸入不可作格式串 |
void f(int arr[]) 等價 void f(int *arr),sizeof(arr) 失效,必須額外傳長度。void print(const int *arr, int n) 承諾不修改內容,編譯器強制檢查,提升接口安全性。stdarg.h (va_list, va_start, va_arg, va_end) 實現 printf 風格函數,類型安全由程序員保證。static inline int max(int a, int b) { return a>b?a:b; } 放頭文件,消除調用開銷,避免函數體過大導致指令緩存失效。總結:函數是管理複雜度的利器。掌握值/地址傳遞語義差異、善用const、理解棧幀生命週期、熟練標準庫,編寫出「高內聚、低耦合、無副作用」的純函數風格代碼,是 C 語言工程化的關鍵一步。