首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言語句與流程控制完整教學:從順序、選擇到迴圈的最佳實踐

     編輯:關於C語言

核心概念速覽

結構類型關鍵字適用場景
順序表達式語句、`{}` 區塊單一路徑、線性邏輯
選擇`if`/`else`/`switch`條件分支、多路分派
迴圈`for`/`while`/`do-while`重複執行、已知/未知次數
跳轉`break`/`continue`/`return`/`goto`流程中斷/提前結束

一、語句與區塊

  • 簡單語句以 `;` 結尾:`x = 1;`、`printf("hi");`、`return 0;`
  • 複合語句(區塊)用 `{}` 包裹零或多條語句,引入新作用域。
  • 區塊可嵌套,內層同名變數遮蔽外層(生命週期至區塊結束)。

二、變數作用域與儲存期

類別宣告位置作用域儲存期預設初值
區域自動區塊內宣告處 → 區塊結尾區塊執行期間不定值
區域靜態區塊內 `static`宣告處 → 區塊結尾程式全程0
全域外部函式外整個專案 (需 `extern`)程式全程0
全域內部函式外 `static`僅本轉譯單元程式全程0

鐵律:先宣告後使用;區塊內同名遮蔽外層;`static` 區域變數僅初始化一次。

三、順序結構與基本 I/O

printf 格式化輸出

printf("整數:%d 八進位:%o 十六進位:%x 浮點:%f 字串:%s 字元:%c\n", 42, 42, 42, 3.14, "hi", 'A');
/* 寬度/精度/對齊 */
printf("%10d | %-10s | %05d | %.2f\n", 1, "left", 42, 3.14159);

scanf 格式化輸入

int a; double b; char c;
scanf("%d %lf %c", &a, &b, &c);  /* 必須傳址 & */
scanf("%d,%lf", &a, &b);        /* 格式字串可含非格式字元匹配輸入分隔符 */

陷阱:`scanf("%d", &a)` 忘記 `&` → 未定義行為;`%f` 對應 `float*`,`%lf` 對應 `double*`。

四、選擇結構

if-else 鏈

if (score >= 90) grade = 'A';
else if (score >= 80) grade = 'B';
else if (score >= 60) grade = 'C';
else grade = 'F';
  • 條件為標量,非零即真,零為假。
  • 單語句可省略 `{}`,但建議保留以防維護錯誤。
  • `==` (比較) vs `=` (指派) —— 編譯器 `-Wparentheses` 可捕獲 `if (x = 0)`。

switch 多路分派

switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        days = 31; break;
    case 4: case 6: case 9: case 11:
        days = 30; break;
    case 2:
        days = is_leap(year) ? 29 : 28; break;
    default:
        days = -1;  // 錯誤月份
}
  • 表達式必須為整數型別 (`int`、`char`、`enum`),不可為浮點數。
  • 貫穿特性:無 `break` 會落入下一 `case`,可用於合併情況(如上例)。
  • `default` 可選,建議保留做防禦性程式設計。

五、迴圈結構

for 迴圈(已知次數/計數器)

for (int i = 1, sum = 0; i <= 100; ++i) {
    sum += i;
}
printf("1+...+100 = %d\n", sum);  // i 在此不可見 (C99 區塊作用域)
  • 三表達式皆可省略:`for (;;)` 等價 `while (1)`。
  • C99 允許 `for (int i=0; ...)` 變數宣告在初始化區,作用域限於迴圈。
  • 陷阱:`for (i=0; i<10; i++);` 分號導致空迴圈體,後接 `{}` 為獨立區塊。

while 迴圈(未知次數/條件驅動)

int sum = 0, i = 1;
while (sum <= 1000) {
    sum += i++;
}
printf("首個使和>1000的 n = %d\n", i-1);
  • 條件先檢查,可能零次執行。
  • 等價 `for (; cond;)`。

do-while 迴圈(至少一次)

int input;
do {
    printf("輸入 1-10: ");
    scanf("%d", &input);
} while (input < 1 || input > 10);
  • 主體先執行,再檢查條件。
  • 適用選單驅動、輸入驗證等必須先執行一次的場景。

六、跳轉控制

關鍵字效果典型用法
`break`跳出最內層 `switch`/`for`/`while`/`do-while`找到目標提前結束搜尋
`continue`跳過本次迴圈剩餘,直接進入下一次迭代 (執行 `for` 的第三表達式)跳過無效資料繼續處理
`return`離開當前函式,回傳值給呼叫者提前結束函式、錯誤處理
`goto`無條件跳轉到同函式內標籤極少用:多層迴圈同時跳出、錯誤清理集中化
/* goto 多層跳出範例 */
for (int i=0; i<10; ++i)
    for (int j=0; j<10; ++j)
        if (found(i,j)) goto DONE;
DONE:
printf("Found at (%d,%d)\n", i, j);

七、迴圈嵌套與實戰:發牌模擬

void dealCards(int playerId) { printf("發牌給玩家 %d\n", playerId); }

int main(void) {
    for (int round = 1; round <= 27; ++round) {
        printf("第 %d 輪\n", round);
        for (int id = 1; id <= 4; ++id)
            dealCards(id);
    }
    return 0;
}
  • 外層控制輪次,內層遍歷玩家,語義清晰、易維護。
  • 嵌套層數 > 3 時建議抽取函式降低認知負荷。

八、常見錯誤與除錯技巧

  1. 整數除法截斷:`score = voice / 40 + 2.5` → `voice` 為 `int` 導致整除。修正:`(float)voice / 40` 或 `voice / 40.0`。
  2. 邊界條件:`<=` vs `<`、陣列下標 `0 ~ n-1`。
  3. 未初始化變數:啟用 `-Wuninitialized`,靜態分析工具 (Cppcheck/Clang Static Analyzer)。
  4. 無限迴圈:條件變數未在迴圈內更新、`while (1)` 缺 `break`。

流程控制是程式的骨架。熟練掌握「順序、選擇、迴圈、跳轉」四大基本結構,並養成「邊界優先、型別正確、作用域最小」的編碼習慣,能寫出既正確又易維護的 C 程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved