| 場景 | 效果 | 範例 |
|---|---|---|
| 函數內區域變數 | 靜態儲存期,保持值跨呼叫,僅初始化一次 | `static int count = 0;` |
| 檔案域變數/函數 | 內部連結,**僅本編譯單元可見** | `static int file_var; static void helper();` |
| 類別成員 | C++ 專屬,全類別共用一份 | `static int shared;` |
const int *p1; // 指向常數整數,p1 可變,*p1 不可變
int const *p2; // 同上
int *const p3; // 常數指標,p3 不可變,*p3 可變
const int *const p4; // 指標與所指皆不可變
**閱讀技巧**:從右向左讀,`const` 修飾左側最近的實體。
| 區域 | 內容 | 管理方式 | 生命週期 |
|---|---|---|---|
| 程式碼區 | 函數機器碼、常數字面值 | 連結器/載入器 | 程式執行期間 |
| 全域/靜態區 | 全域變數、`static` 變數、常數 | 編譯期配置 | 程式執行期間 |
| 堆疊 | 區域變數、函數參數、返回位址、暫存器保存 | 編譯器自動 (幀指標) | 函數呼叫/返回 |
| 堆 | `malloc`/`free` 動態記憶體 | 程式設計師手動 | 分配到釋放 |
void crash() {
int huge[1000000]; // 4MB,超過預設 8MB 堆疊限制
}
int main() { crash(); } // Stack Overflow
**解法**:改 `static` (移至靜態區)、動態分配 `malloc`、或增大堆疊 (`ulimit -s` / 鏈接器選項)。
int a[10];
int *p = a;
p + 1 // 位址 + sizeof(int) = +4 bytes
&a + 1 // 位址 + sizeof(int[10]) = +40 bytes (整個陣列跨越)
/* 回傳 int,接受 (int, double) 的函數指標型別 */
typedef int (*FuncPtr)(int, double);
int add(int a, double b) { return a + (int)b; }
int main() {
FuncPtr f = add;
printf("%d\n", f(3, 4.5)); // 7
}
int (*p)[10]; // 指向含 10 個 int 陣列的指標
int *q[10]; // 10 個 int 指標的陣列
#define EPS 1e-6
if (fabs(x) < EPS) { /* 視為零 */ }
sequenceDiagram
Client->>Server: SYN (seq=x)
Server->>Client: SYN+ACK (seq=y, ack=x+1)
Client->>Server: ACK (ack=y+1)
IP 位址 → MAC 位址,同一區域網路內廣播請求、單播回應。
網路號 + 主機號,需配合**子網遮罩**按位 AND 區分。
**概要設計** 階段 (High-Level Design) 完成:系統分解為模組、定義模組介面 (API)、資料流、資料庫 schema。
| 類型 | 焦點 | 手法 |
|---|---|---|
| 黑盒測試 | 功能規格 | 等價類劃分、邊界值、狀態轉移 |
| 白盒測試 | 內部邏輯 | 語句覆蓋、分支覆蓋、路徑覆蓋 |
| 灰盒測試 | 介面+內部 | 資料流測試、介面契約測試 |
bool is_pow2(unsigned x) { return x && !(x & (x - 1)); }
a ^= b; b ^= a; a ^= b; // 僅限整數,浮點不可
int popcnt(unsigned x) {
int c = 0;
while (x) { x &= x - 1; ++c; } // Brian Kernighan 演算法
return c;
}
C 語言面試核心在於 **記憶體模型、指標運算、未定義行為邊界、演算法複雜度、系統基礎** 五大支柱。逐題搞懂「為什麼」、「編譯器怎麼做」、「硬體怎麼跑」,才能在白板寫代碼時游刃有餘。建議配合《CSAPP》、《C專家編程》、《Linux核心設計》三大經典深度鑽研。