C語言雖是面向過程語言,但其靈活的指針與結構體機制足以實現封裝、繼承、多態等OOP核心特性。本文從數據建模、內存佈局、I/O底層、格式化進階四個維度,帶你透視C語言的深層威力。
struct聚合數據struct Person {
char name[20];
char gender; // 'b'/'g'
int age, height, weight;
};
// 實例化與賦值
struct Person p;
p.name = "whc"; // 錯誤:數組不可整體賦值,需strcpy
strcpy(p.name, "whc");
p.gender = 'b'; p.age = 25; p.height = 175; p.weight = 65;
注意:C結構體不支持直接字符串賦值,需用strcpy/memcpy。
struct Student {
struct Person p; // 繼承Person
char number[20];
int score;
};
struct Student s;
s.p.name = "whc"; // 訪問父層成員
s.number = "20150618";
s.score = 90;
內存佈局:Student首地址即Person首地址,實現零開銷繼承。
struct Person {
void (*print)(void *self);
};
void printPerson(void *self) { printf("run in Person\n"); }
void printStudent(void *self) { printf("run in Student\n"); }
void callPrint(void *obj) {
struct Person *p = (struct Person*)obj;
p->print(obj); // 動態綁定
}
int main() {
struct Person per; per.print = printPerson;
struct Student stu; stu.p.print = printStudent;
callPrint(&per); // 輸出:run in Person
callPrint(&stu); // 輸出:run in Student
return 0;
}
本質:void*擦除類型,強轉回Person*調用其函數指針,實現運行時多態。
int*讀4字節作有符號整數,float*作IEEE754浮點)。union演示此特性)。| 區域 | 內容 | 管理方式 | 增長方向 |
|---|---|---|---|
| 代碼區 | 指令、字面常量 | 只讀,系統管理 | — |
| 全局/靜態區 | 全局變量、static變量 | 程序啟動分配,退出釋放 | — |
| 字符常量區 | 字符串字面量 | 只讀,系統管理 | — |
| 棧區 | 局部變量、函數參數、返回地址 | 編譯器自動管理 | 高地址→低地址 |
| 堆區 | malloc/calloc/realloc分配 | 程序員手動管理 | 低地址→高地址 |
int main() {
char *str0 = "Hello"; // 字符串在常量區,str0在棧
char str1[] = "Hello"; // 數組在棧,內容由常量區拷貝而來
int *p = malloc(100*sizeof(int)); // 堆分配
free(p); p = NULL; // 釋放後置NULL防野指針
}
free,否則內存洩漏。C標準庫封裝系統調用(read/write/open/close),提供緩衝I/O:
| 函數 | 作用 | 類別 |
|---|---|---|
putchar/getchar | 單字符輸出/輸入 | 標準I/O |
printf/scanf | 格式化輸出/輸入 | 標準I/O |
puts/gets | 字符串輸出/輸入(gets不安全,禁用) | 標準I/O |
fputc/fgetc | 文件單字符讀寫 | 文件I/O |
fprintf/fscanf | 文件格式化讀寫 | 文件I/O |
sprintf/sscanf | 字符串格式化寫入/解析 | 字符串I/O |
文件描述符:標準輸入(0)、標準輸出(1)、標準錯誤(2)。
sprintf/sscanf實現類型轉換(替代itoa/atoi)int num = 10; char str[10];
sprintf(str, "%d", num); // int → string
sscanf(str, "%d", &num); // string → int
支持%f、%x、%u等所有格式,標準、可移植。
%[...]%[abc]:只匹配a/b/c。%[a-z]:匹配小寫字母。%[^abc]:匹配非a/b/c的字符。%[^a-z]:匹配非小寫字母。經典用例:讀取含空格的整行
char line[100];
scanf("%[^\n]", line); // 遇換行才停止,包含空格
只讀小寫字母
scanf("%[a-z]", str); // 遇非小寫停止
所有格式化函數(scanf/sscanf/fscanf)均支持掃描集。
版權聲明:歡迎轉載,請註明出處。