const 僅表示「透過此符號不可修改」,並非真正常數。編譯器將其置於唯讀區,但仍可透過指標繞過修改。
| 場景 | 語法範例 | 語意 |
|---|---|---|
| 基本變數 | const int n = 10; | n 唯讀,但 int a[n] 在 C89 非法(VLA 除外) |
| 指標修飾 | const int *p / int *const p | 前者限制 *p,後者限制 p 本身 |
| 函數參數 | void foo(const int *arr) | 模擬傳值呼叫,承諾不修改實參資料 |
| 返回值 | const char *get() | 回傳指標指向的內容唯讀,防止呼叫端修改 |
沿 * 劃線:const 在左修飾指向物件,在右修飾指標本身。
int const *p ≡ const int *p(指向常整數)
int *const p(常指標)
const int *const p(常指標指向常整數)
static int x; 隱藏符號。static void helper() 限制連結可見性,避免多檔案同名衝突,實現 C 語言層面的封裝。
extern int g_var; 僅宣告,不定義(不配置儲存空間)。定義需在某一 .c 檔出現 int g_var = 0;。
關鍵區別:宣告可重複,定義全程僅一次。
sizeof(i++) 不會遞增 i。void f(int a[10]) 內 sizeof(a) == sizeof(int*)。sizeof ≥ 成員大小總和,#pragma pack(1) 可強制緊湊。適用場景:
int square(volatile int *ptr) {
return *ptr * *ptr; // 若無 volatile,編譯器可能優化為讀一次、平方
}
// 正確寫法仍需 volatile,強制每次存取記憶體
| 程式碼片段 | 輸出/結果 | 考點 |
|---|---|---|
char *p = "abc"; sizeof(p) | 4/8 (指標大小) | 字串常值 vs 指標 |
char a[] = "abc"; sizeof(a) | 4 (含 \0) | 陣列初始化 |
void f(int a[10]); sizeof(a) in f | 指標大小 | 參數退化 |
struct {int a; char b;} s; sizeof(s) | 8 (對齊) | 結構體填充 |