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

static 局部變量濫用害人害己:從階乘函數反模式談低耦合設計

     編輯:關於C語言

教科書反模式:帶狀態的階乘函數

int fac(int n) {
    static int f = 1; // 靜態局部變量
    f = f * n;
    return f;
}
// 呼叫 fac(1)..fac(5) 輸出 1,2,6,24,120 看似正常
// 但再次呼叫 fac(3) → 360(錯誤!狀態已汙染)

本質剖析:變態閹割與強耦合

將緊密耦合的三要素——迭代變量 i、累積變量 f、運算邏輯 f*=i——強行拆分:

  • i 留在呼叫端迴圈
  • f 藏在 static 內部
  • 運算邏輯封在函數內

這是功能性閹割:原本有機整體被割裂,函數變成「一次性用品」,嚴重違反低耦合、高內聚原則。函數應無狀態、可重入、僅依賴參數——這才是「本分」。

正確設計:無狀態純函數

// 遞歸版
int fac(int n) { return n <= 1 ? 1 : n * fac(n - 1); }

// 迭代版(推薦)
int fac(int n) {
    int result = 1;
    for (int i = 2; i <= n; ++i) result *= i;
    return result;
}

static 局部變量的正當用途:唯讀查找表

const char* month(unsigned m) {
    static const char* const name[12] = {
        "Jan","Feb","Mar","Apr","May","Jun",
        "Jul","Aug","Sep","Oct","Nov","Dec"
    };
    return name[m - 1]; // 唯讀,無副作用,線程安全(C++11 起初始化原子)
}

特徵:

  • 資料不可變(const)
  • 生命週期需跨越函數調用(避免重複構造)
  • 無副作用、可重入、線程安全

判斷清單:何時用 static local?

場景是否適合理由
可變狀態累積(計數器、快取)❌破壞重入性、線程不安全、測試困難
單例模式⚠️C++11 推薦 static T& instance() { static T inst; return inst; }(Meyer 單例)
大型唯讀查找表/常量表✅避免重複構造,唯讀天然線程安全
函數內部一次性初始化✅配合 std::call_once 或 C++11 魔法靜態

總結

static 局部變量是把雙刃劍。默認拒絕可變 static local,除非是不可變資料或受控初始化。函數應像數學函數:同輸入必得同輸出,無副作用,無隱藏狀態——這是可維護、可測試、可併發代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved