全局變量定義在所有函數之外,具有全局生存期和全局作用域。程序啟動時分配內存,程序結束時釋放。未顯式初始化的全局變量會被編譯器自動初始化為 0,這與局部變量「垃圾值」形成鮮明對比。
main() 執行之前在局部變量前加 static 關鍵字,使其具備全局生存期但保持局部作用域。首次進入函數時初始化,後續調用保持上次離開時的值。本質上屬於特殊的全局變量,存放在全局/靜態存儲區。
| 返回類型 | 安全性 | 說明 |
|---|---|---|
| 局部變量地址 | 危險 | 函數返回後棧幀銷毀,指針懸空 |
| 全局/靜態變量地址 | 安全 | 內存持續有效 |
| malloc 分配的內存 | 條件安全 | 需調用者負責 free,易造成內存洩漏 |
| 傳入的指針參數 | 最佳實踐 | 所有權清晰,由調用者管理生命周期 |
#define 是文本替換,發生在編譯器語法分析之前。注意:
\ 換行// 錯誤示範:運算符優先級導致邏輯錯誤 #define RADTODEG2(x) (x) * 57.3 // 正確寫法:全包圍括號 #define RADTODEG(x) ((x) * 57.3) #define CUBE(x) ((x) * (x) * (x)) #define MIN(a,b) ((a) > (b) ? (b) : (a))
鐵律:整體加括號、每個參數出現處加括號、參數本身加括號。
#ifndef _HEADER_H_ / #define _HEADER_H_ / #endif 防止頭文件重複包含#pragma once 現代編譯器支持的簡潔替代方案__LINE__、__FILE__、__DATE__、__TIME__、__STDC__每個 .c 文件獨立編譯為目標文件(.o/.obj),再由鏈接器合併生成可執行文件。這意味著:
.c 的內部細節// 正確:頭文件只放聲明
// max.h
#ifndef _MAX_H_
#define _MAX_H_
int max(int a, int b); // 函數原型聲明
extern int global_var; // 外部變量聲明
#endif
// 正確:實現文件包含頭文件
// max.c
#include "max.h"
int max(int a, int b) { return a > b ? a : b; }
// main.c
#include "max.h"
int main() { max(1,2); }
static 修飾函數 → 僅在本編譯單元可見,不參與外部鏈接static 修飾全局變量 → 僅在本編譯單元可見| 類別 | 聲明(不產生代碼/數據) | 定義(產生代碼/分配內存) |
|---|---|---|
| 變量 | extern int x; | int x; / int x = 10; |
| 函數 | int foo(void); | 函數體實現 |
| 結構體 | struct Node; | struct Node { int x; }; |