構成 C 程式的函數劃分為兩類:
1. 庫函數 — 由實現提供,標頭文件聲明,鏈接時自動解析。
2. 用戶自定義函數 — 程式設計師編寫,滿足特定業務邏輯。
C 標準庫 (ISO/IEC 9899) 按頭文件組織,現代開發建議優先使用 C 版頭文件 (`
| 頭文件 | 核心功能域 | 常用函數/宏/型別示例 |
|---|---|---|
<stdio.h> | 輸入輸出 (流/檔案/標準流) | `printf` `scanf` `fopen` `fclose` `fread` `fwrite` `fprintf` `fscanf` `fgets` `fputs` `getchar` `putchar` `sprintf` `sscanf` `perror` `tmpfile` `setvbuf` `FILE` `stdin` `stdout` `stderr` |
<stdlib.h> | 通用工具 (記憶體/轉換/程式控制/排序查找/隨機數/環境) | `malloc` `free` `realloc` `calloc` `aligned_alloc` `exit` `atexit` `abort` `system` `getenv` `atoi` `atol` `strtod` `strtol` `strtoul` `rand` `srand` `abs` `labs` `llabs` `div` `ldiv` `qsort` `bsearch` `NULL` `size_t` `RAND_MAX` |
<string.h> | 字符串/記憶體操作 | `strlen` `strcpy` `strncpy` `strcat` `strncat` `strcmp` `strncmp` `strchr` `strrchr` `strstr` `strtok` `strerror` `memcpy` `memmove` `memcmp` `memset` `memchr` |
<math.h> | 數學函數 (浮點/三角/指數/對數/冪/雙曲/分類/操作) | `sin` `cos` `tan` `asin` `acos` `atan` `atan2` `exp` `log` `log10` `pow` `sqrt` `ceil` `floor` `fabs` `fmod` `hypot` `cbrt` `erf` `tgamma` `lgamma` `round` `trunc` `nearbyint` `FP_INFINITE` `FP_NAN` `FP_NORMAL` `FP_SUBNORMAL` `FP_ZERO` `INFINITY` `NAN` `M_PI` (常見擴展) |
<ctype.h> | 字符分類/映射 | `isalpha` `isdigit` `isalnum` `isspace` `islower` `isupper` `isxdigit` `isprint` `iscntrl` `isgraph` `ispunct` `tolower` `toupper` (參數為 `int`,值為 `unsigned char` 或 `EOF`) |
<stdint.h> (C99) | 精確寬度/最小寬度/最快/指針/最大整數型別 | `int8_t` `uint32_t` `int_least16_t` `int_fast32_t` `intptr_t` `uintptr_t` `intmax_t` `uintmax_t` `INT32_MIN` `UINT64_MAX` `PRId32` `PRIu64` (配合 ` |
<stdbool.h> (C99) | 布爾型別 | `bool` `_Bool` `true` `false` `__bool_true_false_are_defined` |
<stddef.h> | 通用定義 | `size_t` `ptrdiff_t` `NULL` `offsetof` `max_align_t` |
<time.h> | 日期時間 | `time` `clock` `difftime` `mktime` `localtime` `gmtime` `asctime` `ctime` `strftime` `struct tm` `clock_t` `time_t` `CLOCKS_PER_SEC` `timespec` (C11) `timespec_get` |
<assert.h> | 斷言 (僅 Debug 生效) | `assert(expr)` `NDEBUG` 宏控制 |
<errno.h> | 錯誤碼 | `errno` (執行緒局部) `EDOM` `ERANGE` `EILSEQ` `errno_t` (C11 附錄 K) |
<setjmp.h> | 非局部跳轉 | `setjmp` `longjmp` `jmp_buf` (慎用,破壞 RAII/棧展開) |
<signal.h> | 信號處理 | `signal` `raise` `SIGINT` `SIGTERM` `SIGSEGV` `SIGFPE` `SIGABRT` `SIG_DFL` `SIG_IGN` `SIG_ERR` `sig_atomic_t` |
<locale.h> | 本地化 | `setlocale` `localeconv` `struct lconv` `LC_ALL` `LC_CTYPE` `LC_NUMERIC` `LC_TIME` `LC_COLLATE` `LC_MONETARY` `LC_MESSAGES` |
<stdarg.h> | 可變參數 | `va_list` `va_start` `va_arg` `va_end` `va_copy` (C99) |
<iso646.h> (C99) | 替代運算符拼寫 | `and` `or` `not` `bitand` `bitor` `xor` `compl` `and_eq` `or_eq` `xor_eq` `not_eq` |
<wchar.h> / <wctype.h> | 寬字符/多位元組字符 | `wchar_t` `wint_t` `btowc` `wctob` `mbrtowc` `wcrtomb` `mbsrtowcs` `wcsrtombs` `wcscpy` `wcslen` `wprintf` `fwprintf` `iswalpha` `iswdigit` `towlower` `towupper` |
<complex.h> (C99) | 複數數學 | `complex` `_Complex_I` `cabs` `carg` `cacos` `ccos` `cexp` `clog` `cpow` `csin` `csqrt` `creal` `cimag` `conj` `cproj` |
<tgmath.h> (C99) | 類型泛型數學宏 | `sin` `cos` `exp` `log` `pow` `sqrt` `fabs` 等自動選擇 `float`/`double`/`long double`/`complex` 版本 |
<fenv.h> (C99) | 浮點環境 | `feclearexcept` `fegetexceptflag` `feraiseexcept` `fegetround` `fesetround` `fegetenv` `fesetenv` `feholdexcept` `feupdateenv` `FE_DIVBYZERO` `FE_INEXACT` `FE_INVALID` `FE_OVERFLOW` `FE_UNDERFLOW` `FE_ALL_EXCEPT` `FE_TONEAREST` `FE_DOWNWARD` `FE_UPWARD` `FE_TOWARDZERO` |
<inttypes.h> (C99) | 整數格式轉換 | `PRId8` `PRIu64` `SCNd32` `SCNx16` `intmax_t` `uintmax_t` `imaxabs` `imaxdiv` `strtoimax` `strtoumax` `wcstoimax` `wcstoumax` |
<stdalign.h> (C11) | 對齊控制 | `alignas` `alignof` `alignof` `max_align_t` `aligned_alloc` |
<stdnoreturn.h> (C11) | 無返回函數屬性 | `noreturn` (C23 為關鍵字 `[[noreturn]]`) |
<threads.h> (C11) | 執行緒 (可選實現) | `thrd_t` `thrd_create` `thrd_join` `thrd_detach` `thrd_exit` `thrd_sleep` `mtx_t` `mtx_init` `mtx_lock` `mtx_unlock` `cnd_t` `cnd_init` `cnd_signal` `cnd_broadcast` `cnd_wait` `cnd_timedwait` `tss_t` `tss_create` `tss_set` `tss_get` `tss_delete` `call_once` `ONCE_FLAG_INIT` |
<uchar.h> (C11) | Unicode 工具 | `char16_t` `char32_t` `mbrtoc16` `c16rtomb` `mbrtoc32` `c32rtomb` |
一個函數只做一件事,做好一件事。過長函數 (>50 行) 必須拆分。
/* 良好介面範例 */
int read_config(const char *path, Config *out_cfg); // 返回錯誤碼,輸出參數用指針
size_t str_copy(char *dst, size_t dst_sz, const char *src); // 返回寫入長度,防止溢出
void *aligned_alloc_custom(size_t alignment, size_t size); // 返回分配地址,失敗返回 NULL
/* 文件內部輔助函數,不對外暴露 */
static void internal_cleanup(Context *ctx) { ... }
static int validate_input(const Input *in) { ... }
`static` 限制鏈接可見性,減少符號汙染,編譯器可更激進優化 (內聯/消除)。
typedef int (*CompareFunc)(const void *a, const void *b);
void my_qsort(void *base, size_t nmemb, size_t size, CompareFunc cmp);
實現泛型演算法/事件驅動/插件架構的核心機制。
| 類別 | 風格 | 例子 |
|---|---|---|
| 庫函數 (標準) | 小寫 + 下劃線 | `memcpy` `strtoul` `qsort` |
| 用戶函數 (專案統一) | 小寫 + 下劃線 (snake_case) 推薦 | `parse_config` `calculate_crc32` `http_request_send` |
| 模組前綴 (避免衝突) | `module_action` | `json_parse` `net_connect` `db_query` |
| 布爾查詢 | `is_` `has_` `can_` `should_` | `is_valid` `has_permission` `can_allocate` |
| 轉換/獲取 | `to_` `from_` `get_` `make_` `create_` `destroy_` | `to_upper` `get_user_by_id` `create_context` |