C 程式由語句構成,理解各類語句的語法、語意與作用域規則,是閱讀寫代碼的基石。
| 類別 | 關鍵字/形式 | 核心作用 | 備註 |
|---|---|---|---|
| 表達式語句 | `expr;` | 計算副作用(賦值、函式呼叫、遞增) | 最常見,如 `a=b+3;` `printf(...);` |
| 流程控制語句 | `if` `switch` `for` `while` `do-while` | 改變執行順序 | 分支與迴圈 |
| 跳轉語句 | `break` `continue` `goto` `return` | 無條件轉移控制流 | `break/continue` 限用於迴圈/switch |
| 復合語句 | `{ ... }` | 將多語句合為一塊,引入新作用域 | 又稱區塊 |
| 空語句 | `;` | 佔位、無操作 | 常用於 `for(;;)` 或空循環體 |
| 宣告語句 | `int a;` `float f=3.14;` | 引入變數、分配儲存空間 | C99 允許混雜在代碼中 |
大括號 `{}` 不僅分組語句,**更創建區塊作用域**:內部宣告的變數遮蔽外部同名變數,離開區塊即銷毀。
int a=11, b=21, c=31;
printf("a=%d b=%d c=%d\n", a, b, c); // 11 21 31
{
int b=22; // 新變數 b,遮蔽外層 b
float c=3.3; // 新變數 c,型別不同
printf("a=%d b=%d c=%f\n", a, b, c); // 11 22 3.3
a = b; // 修改外層 a = 22
}
printf("a=%d b=%d c=%d\n", a, b, c); // 22 21 31 (內層 b,c 已銷毀)
對比:若內層也宣告 `int a=1;`,則 `a=b` 只改內層 `a`,外層 `a` 保持 11。
#include // 標準輸入輸出
#include // 數學函式
#include // 動態記憶體、轉換、隨機數
printf("格式控制字串", 輸出項1, 輸出項2, ...);
| 符號 | 輸出型別 | 範例輸出 |
|---|---|---|
| `%d` / `%i` | 有號十進位整數 | `42` `-7` |
| `%u` | 無號十進位整數 | `42` |
| `%o` | 八進位無號整數 | `52` |
| `%x` / `%X` | 十六進位(小寫/大寫) | `2a` / `2A` |
| `%f` | 浮點數(預設 6 位小數) | `3.141593` |
| `%e` / `%E` | 科學記號 | `3.141593e+00` |
| `%g` / `%G` | 自動選 `%f` 或 `%e`(較短者) | `3.14159` |
| `%c` | 單一字元 | `A` |
| `%s` | 字串(以 `\0` 結尾) | `Hello` |
| `%p` | 指標位址 | `0x7ffe...` |
| `%%` | 輸出 `%` 字元本身 | `%` |
printf("%10d", 42); // 右對齊,寬度 10
printf("%-10d", 42); // 左對齊
printf("%010d", 42); // 前導 0 填充
printf("%.2f", 3.14159); // 保留 2 位小數
printf("%10.2f", 3.14); // 寬度 10,2 位小數
printf("%+d", 42); // 強制顯示正負號 +42
printf("% d", 42); // 正數前留空格
printf("%#x", 42); // 顯示 0x 前綴 0x2a
putchar('A'); // 輸出單一字元
putchar('\n'); // 換行
putchar('\101'); // 八進位 ASCII 碼輸出 'A'
putchar('B'); putchar('c'); // 連續呼叫
只能輸出**單一字元**,無法直接輸出字串。
scanf("格式控制字串", &變數1, &變數2, ...);
**必須傳址**(`&var`),否則無法寫回變數。
scanf("%[^\n]", str); // 讀整行(含空格)直到換行
scanf("%*d %d", &b); // `%*d` 讀取並丟棄第一個整數,只存第二個到 b
int a; char c;
scanf("%d", &a); // 輸入 10 並按 Enter,緩衝區剩 '\n'
scanf("%c", &c); // 直接讀到 '\n',非預期字元!
解法:`scanf(" %c", &c)`(格式字串前加空格跳過空白字元),或 `getchar()` 吃掉換行。
| 函式 | 標頭檔 | 回顯 | 緩衝 | 備註 |
|---|---|---|---|---|
| `getchar()` | `stdio.h` | 是 | 行緩衝 | 標準 C,讀取含空白/換行 |
| `getch()` | `conio.h` | 否 | 無緩衝 | 非標準,Windows 常用,即時響應 |
| `getche()` | `conio.h` | 是 | 無緩衝 | 即時回顯,常用於選單輸入 |
char pwd[20], ch; int i = 0;
printf("Password: ");
while ((ch = getch()) != '\r' && i < 19) { // Enter 為 '\r'
if (ch == '\b') { if (i) { i--; printf("\b \b"); } } // 處理退格
else { pwd[i++] = ch; putchar('*'); }
}
pwd[i] = '\0';
double a, b, c, x1, x2, disc;
scanf("%lf%lf%lf", &a, &b, &c);
disc = b*b - 4*a*c;
if (disc >= 0) {
x1 = (-b + sqrt(disc)) / (2*a);
x2 = (-b - sqrt(disc)) / (2*a);
printf("x1=%.2f, x2=%.2f\n", x1, x2);
} else {
printf("No real roots\n");
}
int m, n;
scanf("%d", &m); // 10-99
n = m % 10; // 個位
m = n * 10 + m / 10; // 個位*10 + 十位
printf("Reversed: %d\n", m);
語句是程式的骨架,I/O 是血液。掌握六大語句類別的語法與作用域規則,熟練運用 `printf`/`scanf` 格式控制與字元級 I/O 函式,並警惕緩衝區殘留與格式字串安全問題,能讓你寫出健壯、可移植的 C 程式。下一步建議深入學習運算子優先級與求值順序,徹底搞懂複雜表達式的真實行為。