首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言函數設計精要:返回值、參數傳遞與可重入編程指南

     編輯:關於C語言

一、返回值與 return 的核心規則

  • void 函數:可省略 return;若寫上 return; 僅用於提前退出。
  • 非 void 函數:return 後必須跟表達式;return 之後不可有其他語句(死代碼)。
  • 多重返回:允許在不同分支多次 return,但邏輯需清晰。
  • 隱式 int 陷阱:未聲明返回類型時預設為 int(C89),現代標準強制要求顯式聲明。
  • 主函數返回值約定:0 表示正常退出,非零表示異常,具體碼由項目規範定義。

二、函數定義與聲明的硬性約束

規則說明
不可嵌套定義C 不支持函數內部定義函數(GCC 擴展除外)
避免無限遞歸直接/間接自我調用需有明確終止條件
不可重複定義同一符號只能有一個定義,但可多次聲明(extern)
參數類型檢查調用時實參類型必須與形參兼容,否則未定義行為

三、參數傳遞機制深度解析

1. 值傳遞(C 唯一機制)

void modify(int a) { a++; }  // 修改副本
int main() { int b = 1; modify(b); printf("%d", b); // 輸出 1 }

形參是實參的拷貝,內存地址不同,函數內操作不影響外部變量。

2. 指針傳遞(模擬引用)

void modify(int *a) { *a = 1989; }
int main() { int b = 1; modify(&b); printf("%d", b); // 輸出 1989 }

傳遞的是地址的拷貝,通過解引用修改原對象內存。本質仍是值傳遞。

3. C++ 引用傳遞(僅供對比)

void modify(int &a) { a = 1989; }  // a 是 b 的別名,共享內存

C 語言無此機制,勿混淆。

四、函數設計最佳實踐

  1. 命名自述性:函數名應清晰表達意圖,如 calculate_total_price() 而非 calc()。
  2. 參數極簡化:單一職責原則,參數超過 3-4 個考慮封裝為結構體。
  3. 註釋為維護者寫:說明為什麼而非做什麼,特別是前置條件、副作用、錯誤碼含義。
  4. 函數體短小:理想情況 < 20 行,超過 50 行必須拆分。單一層級抽象原則(SLAP)。

五、可重入函數編寫規範

可重入函數可被中斷後安全再次進入(如信號處理、多線程)。核心原則:

  • 不使用靜態/全域非 const 數據:所有狀態通過參數傳入或局部變量(棧上)維持。
  • 不調用非可重入函數:如 malloc、printf、strtok 等標準庫函數多數不可重入。
  • 不修改共享硬體資源:無鎖操作或原子操作保護。
  • 參數傳遞指針時:確保指向的內存由調用者獨佔或已加鎖。
詳細規範請參考《函數可重入性及編寫規範》(CSDN 專欄)。

六、常見陷阱速查表

/* 錯誤:void 函數返回值被使用 */
void foo(); 
int x = foo();  // 編譯錯誤

/* 錯誤:返回局部指針 */
int* bad() { int a=1; return &a; }  // a 生命週期結束,野指針

/* 正確:動態分配或靜態存儲 */
int* good() { static int a=1; return &a; }  // 或 malloc 由調用者 free
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved