// 定義函數指針類型 PFUN,指向無參無返回值函數 typedef int (*PFUN)(); PFUN pfun; // 聲明變量 // 帶參數版本 typedef unsigned short (*pTaskEventHandlerFn)(unsigned char task_id, unsigned short event); pTaskEventHandlerFn tasksArr[10]; // 函數指針陣列
技巧:在聲明中用類型名替換變量名,前加 typedef 即得新類型。
int a[] = {2,4,6,8,10}; // 編譯器自動推導大小為 5
static int a1[5] = {1,2,3,4,5};
static int a2[] = {1,2,3,4,5}; // 等價
C 語言調用約定(cdecl):參數從右向左壓棧,調用者清棧。棧頂通常為低地址。
for (a; b; c) { e; }
// 順序:a → b(判斷) → e → c → b → e → c ... 直到 b 為假
typedef union {
uint32_t time32;
uint16_t time16[2];
uint8_t time8[4];
} osalTime_t;
// 所有成員共享同一塊內存,修改任一成員影響其他
// 適用於不同視圖訪問同一數據(如協議解析)
static inline 限制文件內可見,避免多文件重複展開表示地址為 0 的整型指針,通常用於硬件寄存器映射或標記無效指針。不可解引用寫入,讀取可能觸發硬件故障。
extern:聲明外部定義,跨文件共享(默認函數/全局變量為 extern)static:限制本文件可見,函數/全局變量內部鏈接extern 聲明,定義放在單一 .c 文件#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER) // 利用空指針解引用計算成員偏移,編譯期常量,無運行開銷
讀取:加載 4 字節 → 移位屏蔽取目標字節。寫入:讀取 4 字節 → 修改目標字節 → 寫回 4 字節。編譯器自動生成指令序列,32位對齊訪問最高效。
switch (cmd) {
case 1: do_a(); break;
case 2: do_b(); // 缺少 break!
case 3: do_c(); // case 2 會穿透執行 do_c()
default: do_d();
}
// 利用穿透實現多值同邏輯:
case 1: case 2: case 3: handle_123(); break;
!1 == 0; !0 == 1; !5 == 0; // 非零變 0,零變 1 ~1 == -2 (0xFFFFFFFE); // 逐位翻轉
#define VAL 0x00000001u // u: unsigned int #define VAL 0x00000001UL // UL: unsigned long (32位) #define VAL 0x00000001ULL // ULL: unsigned long long (64位)
int (*a)[10]; // 陣列指針:指向 10 個 int 的陣列 int *a[10]; // 指針陣列:10 個 int* 指針
"C:\\Users\\Name\\file.txt" // 雙反斜杠或單正斜杠 "C:/Users/Name/file.txt"
%#x → 0x前綴; %#o → 0前綴; %#d → 無變化
靜態/全局變量初始值必須為編譯期常量(常數、宏常量、const 常量),不可用變量初始化。運行時可賦值變量。
assert(ptr != NULL); // 條件為假時終止程序,輸出文件行號,Debug 模式生效
aligned = (bytes + 3) & ~3; // (bytes+3) & 0xFFFFFFFC // 或 aligned = ((bytes + 3) >> 2) << 2;
break 直接跳出循環體,i++ 不執行。
int *p; sizeof(p) = 4/8 (指針大小)
int a[10]; sizeof(a) = 40 (陣列總大小)
void func(char p[]) { sizeof(p) = 4/8; } // 參數退化為指針
a *= b; a += b; a |= b; a &= b; a ^= b; // 等價 a = a op b // 注意:a = ~a 是按位取反,非取負
typedef union {
unsigned char value;
struct {
unsigned int bit0:1; ... bit7:1;
} bit_field;
} PORT;
// 每位獨立訪問,節省空間,硬件寄存器操作常用
fstat(fd, &st); // 獲取文件大小 st.st_size ftruncate(fd, new_len); // 截斷/擴展文件