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

C語言核心筆記(五):語句體系與輸入輸出全解析——從表達式語句到格式化I/O

     編輯:關於C

C 語句分類全景

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 允許混雜在代碼中

1. 復合語句與作用域規則

大括號 `{}` 不僅分組語句,**更創建區塊作用域**:內部宣告的變數遮蔽外部同名變數,離開區塊即銷毀。

範例:變數遮蔽演示


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。

2. 函式庫與標頭檔機制

  • 標準庫函式(`printf`、`scanf`、`sin`、`malloc` 等)編譯成目標檔存放於函式庫。
  • 使用前需**宣告**,透過 `#include <頭檔.h>` 引入宣告。
  • 連結階段由連結器解析符號地址。

#include   // 標準輸入輸出
#include    // 數學函式
#include  // 動態記憶體、轉換、隨機數

3. 格式化輸出:printf 家族

3.1 基本語法


printf("格式控制字串", 輸出項1, 輸出項2, ...);

3.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...`
`%%`輸出 `%` 字元本身`%`

3.3 寬度、精度、旗標進階


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

4. 字元輸出:putchar / putc


putchar('A');           // 輸出單一字元
putchar('\n');          // 換行
putchar('\101');        // 八進位 ASCII 碼輸出 'A'
putchar('B'); putchar('c'); // 連續呼叫

只能輸出**單一字元**,無法直接輸出字串。

5. 格式化輸入:scanf 家族

5.1 基本語法


scanf("格式控制字串", &變數1, &變數2, ...);

**必須傳址**(`&var`),否則無法寫回變數。

5.2 掃描集合與抑制賦值


scanf("%[^\n]", str);   // 讀整行(含空格)直到換行
scanf("%*d %d", &b);    // `%*d` 讀取並丟棄第一個整數,只存第二個到 b

5.3 常見坑:緩衝區殘留換行符


int a; char c;
scanf("%d", &a); // 輸入 10 並按 Enter,緩衝區剩 '\n'
scanf("%c", &c); // 直接讀到 '\n',非預期字元!

解法:`scanf(" %c", &c)`(格式字串前加空格跳過空白字元),或 `getchar()` 吃掉換行。

6. 字元輸入三劍客:getchar、getch、getche

函式標頭檔回顯緩衝備註
`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';

7. 順序程式設計經典範例

7.1 一元二次方程求根


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");
}

7.2 兩位數倒序(數學法)


int m, n;
scanf("%d", &m); // 10-99
n = m % 10;      // 個位
m = n * 10 + m / 10; // 個位*10 + 十位
printf("Reversed: %d\n", m);

8. 關鍵知識點速查卡

  • 語句 vs 表達式:語句無值(`if`、`for`),表達式有值(`a+b`、`func()`)。表達式加 `;` 變語句。
  • 副作用:修改狀態(賦值、I/O、遞增)。`printf` 有副作用(輸出),也有回傳值(輸出字元數)。
  • 復合語句作用域:`{ int x; }` 內的 `x` 外部不可見,生命週期結束於 `}`。
  • scanf 回傳值:成功匹配賦值的項目數;EOF 表示輸入結束。務必檢查!
  • 格式字串漏洞:`printf(user_input)` 若含 `%s` 會讀取棧內容 → 永遠用 `printf("%s", user_input)`。

總結

語句是程式的骨架,I/O 是血液。掌握六大語句類別的語法與作用域規則,熟練運用 `printf`/`scanf` 格式控制與字元級 I/O 函式,並警惕緩衝區殘留與格式字串安全問題,能讓你寫出健壯、可移植的 C 程式。下一步建議深入學習運算子優先級與求值順序,徹底搞懂複雜表達式的真實行為。

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