程式設計師對話:
A:「老兄,最近手頭緊,借點錢?」
B:「成啊,要多少?」
A:「一千行不行?」
B:「咱倆誰跟誰!給你湊個整——1024,拿去花。」
C 語言允許直接操作實體位址,適合核心與驅動程式開發。有句業界名言:「普通人學 C 三年不入門,五年不熟悉,十年不敢說精通。」學習關鍵在於:多寫碼、多除錯(必要時用「小黃鴨除錯法」)、多思考、遇到問題先自行深入研究解決。以下筆記整理自《C 語言深度解剖》。
auto、extern、register、static——定義變數時只能指定其一。
| 區段 | 內容 | 特性 |
|---|---|---|
| 程式碼區 | CPU 執行的機器指令 | 可共享、唯讀 |
| BSS 區 | 未初始化的全域/靜態變數 | 程式啟動時清零 |
| 資料區 | 已初始化的全域/靜態變數、常數資料 | 程式載入時由映像檔初始化 |
| 堆疊區 | 函式參數、返回值、區域變數 | 編譯器自動管理、即時分配釋放 |
| 堆積區 | malloc() 分配的記憶體塊 | 程式設計師手動管理、易發生記憶體洩漏 |
register 變數可能存於 CPU 暫存器,無法取址(不能用 & 運算子)。
static 的雙重角色extern 也不可見限制函式作用域於本檔(內部函式),避免多檔協作時發生同名衝突。
sizeof 關鍵字細節int i = 0; sizeof(int); // 型別需加括號 sizeof i; // 變數括號可省略 sizeof(i); // 變數加括號也合法 sizeof int; // ❌ 錯誤:型別不可省略括號
sizeof 僅計算型別大小,不存取記憶體,故不會觸發位址越界。
signed / unsigned 隱含轉換陷阱unsigned int a = 6;
int b = -20;
(a + b > 6) ? puts(">6") : puts("<=6"); // 輸出 ">6"
原因:b 隱性轉為 unsigned,-20 變成極大正數,導致 a+b 遠大於 6。
char 有號性與 strlenchar a[1000];
for (int i = 0; i < 1000; i++) a[i] = -1 - i;
printf("%d", strlen(a)); // 輸出 255(視實作而定)
原因:char 是否有號由實作定義;若為 signed char,-1-i 會在 i=255 時產生 \0,提前結束字串。
void 與泛型指標void:空型別,用於無回傳值函式void*:泛型指標,可指向任意型別資料void*,無需強制轉型case 標籤限制只能是整數或字元常數/常數運算式。
const 唯讀變數volatile:防止編譯器過度優化int i = 10; int j = i; // (1) int k = i; // (2) 編譯器可能優化:直接用暫存器值,不重讀記憶體
加上 volatile:
volatile int i = 10; int j = i; // (3) 強制從記憶體讀取 int k = i; // (4) 再次從記憶體讀取
int checkSystem() {
union { int i; char ch; } c;
c.i = 1;
return (c.ch == 1); // 1=Little-endian, 0=Big-endian
}
// 版本 1:12 位元組
struct TestStruct1 { char c1; short s; char c2; int i; };
// 版本 2:8 位元組(重新排序減少填充)
struct TestStruct2 { char c1; char c2; short s; int i; };
處理器存取對齊記憶體僅需一次總線週期,未對齊需兩次。可用 #pragma pack(n) 改變預設對齊(n=1,2,4,8,16…)。
enumenum Color { GREEN = 1, RED, BLUE, GREEN_RED = 10, GREEN_BLUE } ColorVal;
// 值:GREEN=1, RED=2, BLUE=3, GREEN_RED=10, GREEN_BLUE=11
// 功能: 改變緩衝區大小 // 參數: nNewSize 緩衝區新長度 // 返回值: 緩衝區目前長度 // 說明: 保持原資料內容不變
/************************************************************************* * Function Name : nucFindThread * Create Date : 2000/01/07 * Author : your name/your company * Description : Find a proper thread in thread array. * Param : ThreadNo : ... * Return Code : ERROR_Fail / ERROR_SUCCEED * Global Var : DISP_wuiSegmentAppID * Revision History * V0.5 2008/01/07 your name ... ************************************************************************/
// end "for(...)"assert(NULL != p);