基本數據類型本質
- 定義:固定內存大小的別名,創建變量的「模具」。
- 本質:
char 1B、short 2B、int 4B(視平台)。
- sizeof 是編譯期運算符,非函數,值在編譯期確定。
變量存儲屬性
| 關鍵字 | 存儲區 | 生命週期 | 備註 |
auto | 棧 | 塊作用域內 | 局部變量默認,可省略 |
static | 靜態區 | 程序全周期 | 局部靜態保持值;全局靜態限制文件作用域 |
register | CPU 寄存器 | 塊作用域內 | 請求寄存器,不可取地址,不一定滿足 |
控制流語句精要
分支
if-else:else 匹配最近 if;浮點數比較需設精度 eps;0 值寫左邊防誤賦值。
switch-case:整型/字符型標籤;break 防貫穿;default 善用;case 按正常/異常順序排列。
循環
while:先判後執,可零次。
do-while:先執後判,至少一次。
for:初始化、條件、迭代三段式,語義同 while 但更緊湊。
break 退出整層循環;continue 結束本次進入下次;switch 中不可用 continue。
特殊關鍵字
goto:棄用,破壞結構化,質量反比於出現次數。
void:無類型,無變量,用於函數無返回/無參數、通用指針 void* 接收任意指針(賦值需強轉)。
extern:聲明外部符號,指示 C 編譯器按 C 鏈接規則處理(防 C++ Name Mangling)。
sizeof:編譯期計算類型/表達式佔用字節數。
const 與 volatile
const:編譯期只讀檢查,運行期仍佔內存,可被指針間接修改(未定義行為)。指針語境:const int* p / int* const p / const int* const p ——「左讀右指」口訣。
volatile:告知編譯器「每次必從內存讀取」,用於多線程共享變量、硬件寄存器映射、信號處理器修改的變量。
結構體與聯合體
struct:各成員獨立佔用內存,支持柔性數組(C99 最後一個成員為未知大小數組)。
union:所有成員共享同一塊內存(大小 = 最大成員),受大小端影響,同一時刻僅一個成員有效。
枚舉與 typedef
enum:離散常量集合,可調試、有類型、作用域限制,優於 #define。
typedef:為現有類型起別名,不創建新類型,不可 unsigned/signed 擴展,語義清晰優於宏替換。
註釋、轉義、引號細節
- 註釋被空格替換,
/* */ 不可嵌套,字符串內 // 不啟動註釋。
\ 為行續符(行尾無空格)或轉義符(字符/字符串內)。
'a' 為字符常量(int 型,1B);"a" 為字符串常量(char*,2B 含 \0)。
運算符陷阱
- 邏輯運算
&& || 短路求值;! 只識別 0(非 0→0,0→1)。
- 位運算
& | ^ ~ << >>:優先級低於算術/關係運算,混用必加括號;左移≈乘2ⁿ,右移≈除2ⁿ(有符號算術移位)。
++/--:貪婪解析 a+++b → a++ + b;前置返回新值,後置返回舊值。
- 隱式轉換:算術提升至高類型,賦值向左類型轉換,函數調用實參→形參類型。
宏與條件編譯
#define:預處理文本替換,無類型檢查、無調用開銷、參數不求值直接展開、不可遞歸。
- 條件編譯
#if/#ifdef/#endif:預處理期裁剪代碼,用於多產品線、Debug/Release 區分、防重複包含頭文件。
#include 本質是文件內容嵌入。
經典案例:break / continue / 雙重循環
// break: 輸入0退出
for (;;) { int x; scanf("%d",&x); if(x==0) break; printf("%d\n",x); }
// continue: 輸出0-100偶數
for (int i=0;i<=100;i++) if(i%2) continue; else printf("%d ",i);
// 雙重循環打印三角形
for (int i=0;i<5;i++) {
for (int j=0;j<=i;j++) putchar('*');
putchar('\n');
}
// 等腰三角形
for (int i=0;i<5;i++) {
for (int j=0;j<=i*2;j++) putchar('*');
putchar('\n');
}