聲明:原創作品,轉載時請注明文章來自SAP師太博客,並以超鏈接形式標明文章原始出處,否則將追究法律責任!
多級間接訪問允許修改不同層級的變量:
int i, *pi = &i, **ppi = π
**ppi = 10; // 修改 i
*ppi = &other; // 修改 pi
函數修改調用者指針時需傳遞指針地址(二級指針)。
int *f, g; → f 是指針,g 是 intint (*f)(); → f 是函數指針int (*f())(); → f 是返回函數指針的函數函數指針聲明:int (*comp)(void*, void*); 括號不可省。賦值時函數名隱式轉換為地址,&func 與 func 等價。調用可用 (*pf)(arg) 或 pf(arg)。
聲明:void (*f[3])(int) = {fn1, fn2, fn3}; 調用:(*f[i])(arg)。最大用途是回調,如 qsort 比較函數、冒泡排序動態選擇升/降序:
void bubble(int *a, int n, int (*cmp)(int,int)) {
if ((*cmp)(a[j], a[j+1])) swap(&a[j], &a[j+1]);
}
int main(int argc, char **argv):argv[0] 為程序名,argv[argc] == NULL。遍歷參數:while (*++argv) puts(*argv);
字符串常量在表達式中為指針常量。"xyz"[2] 取字符 'z',*"xyz" 取 'x'。十六進制輸出妙用字符串索引:
putchar("0123456789ABCDEF"[value % 16]);
__FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__, __STDC__。宏名慣用全大寫。
#define NAME stuff 替換文本可為任意符號序列。長定義用反斜槓換行。帶參宏:#define SQUARE(x) ((x)*(x)) —— 參數與整體均需括號防止優先級錯誤。
#param → 將參數轉為字符串字面量:#define PRINT(x) printf(#x "=%d", x)## → 連接符號:#define VAR(n) var##n → VAR(5) 展開為 var5區別:# 加引號,## 直接連接符號。
參數多次求值導致副作用:MAX(x++, y++) 可能使 x、y 各增兩次。複雜表達式首選內聯函數。
#if/#elif/#else/#endif 配合 defined(MACRO) 或 #ifdef/#ifndef。可嵌套。防止頭文件重複包含標準模式:
#ifndef _HEADER_H
#define _HEADER_H 1
// 內容
#endif
#include <sys.h> 搜索系統路徑,#include "local.h" 先搜當前目錄。頭文件慣用 .h 後綴,不應定義全局變量(多次包含導致重定義)。
I/O 函數失敗設置 errno,perror(msg) 輸出 msg: 錯誤描述。僅在函數失敗後檢查 errno 有意義。
FILE 結構體管理緩衝區與狀態。文本流自動轉換換行符(Windows: \n↔\r\n),二進制流不轉換。fopen 模式:r/w/a + 可選 b/+。freopen 實現標準流重定向。
| 類型 | 輸入 | 輸出 |
|---|---|---|
| 字符 | getc/fgetc/getchar | putc/fputc/putchar |
| 文本行 | fgets/gets | fputs/puts |
| 格式化 | fscanf/scanf/sscanf | fprintf/printf/sprintf |
| 二進制 | fread | fwrite |
fgets 保留 \n,gets 丟棄 \n(不安全,已棄用)。fputs 不加 \n,puts 自動加 \n。
scanf 格式:%[*][width][修飾]類型。% 抑制賦值,width 限制最大字符數。修飾符:h(short), l(long), L(long double)。
printf 格式:%[標誌][寬度][.精度][修飾]類型。標誌:-左對齊, 0零填充, +強制符號, 空格正數前加空格, #替代形式(0x前綴等)。精度對整數指最小位數,對浮點指小數位數,對字符串指最大字符數。* 可由參數動態指定寬度/精度。
fread(ptr, size, count, fp) / fwrite(ptr, size, count, fp) 直接讀寫內存位模式,高效且保持結構體佈局。返回實際項數。結構體寫入文件後可直接讀回,但涉及指針成員時需序列化處理。
fwrite(&struct_var, sizeof(struct_var), 1, fp); // 整體寫入
fflush(fp):強制刷新輸出緩衝區ftell/fseek:基於 long 偏移定位(SEEK_SET/CUR/END)fgetpos/fsetpos:使用 fpos_t 支持大文件rewind(fp):等價 fseek(fp,0,SEEK_SET) 並清除錯誤標誌文本流定位受換行轉換影響,不可移植地計算偏移;二進制流無此問題。fseek 會清除 ungetc 退回的字符。
setbuf(fp, buf) / setvbuf(fp, buf, mode, size)。mode:_IOFBF全緩衝, _IOLBF行緩衝, _IONBF無緩衝。必須在操作前調用。
tmpfile():創建臨時二進制更新文件 (wb+),關閉自動刪除tmpnam(buf):生成唯一文件名remove(name) / rename(old, new):刪除/重命名