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

C 語言基礎教程(二):變數三大類型——區域、形式參數、全域

     編輯:C 語言基礎

變數宣告位置決定生命週期與作用域

Turbo C 2.0 依宣告位置將變數分為三類,掌握其差異是模組化程式設計的基礎。

1. 區域變數 — 函數內部自動管理

void demo(void)
{
    int i;              /* 隱式 auto */
    auto int j;         /* 顯式 auto (極少使用) */
    /* ... */
}
  • 生命週期:函數被呼叫時自動建立 (在堆疊上),返回時自動銷毀。
  • 初始化:不自動初始化,內容為隨機垃圾值,必須賦值後再用。
  • 作用域:僅限定義它的區塊 (大括號內)。
  • 遞迴/重入安全:每次呼叫擁有獨立副本,天然執行緒安全 (單執行緒環境下)。

2. 形式參數 — 函數介面契約


/* 宣告 */
void puthz(int x, int y, int color, char *p);

/* 定義 */
void puthz(int x, int y, int color, char *p)
{
    int i, j, k;        /* 區域變數 */
    /* 函數本體 */
}
  • 本質上屬於區域變數,但由呼叫端透過傳值初始化。
  • 在函數內可像普通區域變數一樣讀寫 (修改不影響呼叫端實參)。
  • 陣列/結構體參數退化為指標,若需保護請加 const。

3. 全域變數 — 程式級共享狀態


#include <stdio.h>

int test = 0;           /* 定義於所有函數外部 */

void f1(int x, float y);
void f2(void);

int main(void)
{
    test = 5;
    f1(20, 5.5f);       /* test 變 115 */
    f2();               /* test 變 1150 */
    return 0;
}

void f1(int x, float y)
{
    float z = x * y;
    test += (int)z;     /* 直接讀寫全域 */
}

void f2(void)
{
    int count = 10;
    test *= count;
}
  • 生命週期:程式啟動時配置 (BSS/資料段),結束時釋放。
  • 預設初始化:自動歸零 (未顯式初始化者)。
  • 作用域:整個轉譯單元 (源檔) 從定義處往後;配合 extern 可跨檔案存取。
  • 慣例位置:置於 #include 之後、main 之前。

三類變數快速對照

特性區域形式參數全域
儲存區堆疊堆疊靜態區 (.data/.bss)
預設初值不定 (垃圾值)由呼叫端傳入0
可見範圍定義區塊內函數本體內全程 (含跨檔)
存活期函數執行期間函數執行期間程式全程
執行緒安全是 (各呼叫獨立)是否 (需鎖/原子操作)

全域變數作參數傳遞的代價

雖可「免傳參」共享資料,但缺點明顯:

  1. 耦合度高:函數隱性依賴全域狀態,難以獨立測試與複用。
  2. 名稱衝突:大型專案易發生同名覆蓋。
  3. 記憶體常駐:長期佔用靜態空間,嵌入式系統尤忌。
  4. 並發風險:多執行緒/中斷環境下需額外同步機制。

最佳實務

  • 優先使用區域變數 + 參數傳遞,明確資料流向。
  • 全域變數最小化:僅用於真正的全域狀態 (硬體暫存器映射、系統設定旗標、單例模組狀態)。
  • 加 static 限制連結:檔案內全域變數預設加 static,避免汙染全域命名空間。
  • 封裝存取函數:提供 get_xxx()/set_xxx(),集中加入斷言、日誌、鎖。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved