# C語言教學 —— 輸入及輸出
::: info
本教學由 @watermelon1024 ||和 @ChatGPT 共同||製作。
:::
# 前言
我們都知道,不管是遊戲還是工具,程式就是要和螢幕前的使用者互動,與使用者進行交流以及從使用者那裡獲取資訊是一項重要的任務,那麼,我們要怎麼和使用者溝通呢?
這就是我們今天要學習的內容 —— <font color="#61afef">**輸入與輸出**</font>。
### 輸入與輸出
要在C語言中輸入與輸出,我們需要先知道該怎麼讓程式「學會」輸入與輸出,就像人從小也要學習怎麼說話一樣。
要讓程式學會怎麼輸入與輸出,我們就需要派出一個工具 —— <font color="#c678dd">**標頭檔**(Header File)</font>。
## 標頭檔
在C程式設計中,**標頭檔**是一種包含了 {==預定義函式==|functions} 、 {==變數==|variables} 和 {==常數==|constants} 聲明的檔案。它們允許你在程式中使用這些預定義的元素,而無需從頭開始重新編寫它們。
### 使用標頭檔
標頭檔通過前置處理器的 `#include` 指令==包含==(可以理解成==匯入==)到您的程式中。
例如:
```c
#include <stdio.h>
```
### *<stdio.h>*
名詞解釋:
- *std*:是"Standard"的縮寫,中文譯為「標準」。
- *io* :是"Input/Output"的縮寫,中文譯為「輸入/輸出」。
- *.h* :是標頭檔(++H++eader File)的副檔名。
`<stdio.h>` 就是包含了用於**標準==輸入==和==輸出==操作**的函數和常量聲明的標頭檔,而我們這次要使用的`scanf`和`printf`就是其內的函式。
# 輸出 —— `printf()`
`printf` 函數是以{==格式化==|++f++ormatted}的方式將資料輸出到螢幕。通過構建==格式控制字串==,可以將各種型態的資料插入到輸出文本中。
以下是一些常見的格式預留位置:
- `%d`:用於輸出{==整數==|integer},`d` 為 `digit`(數字)的縮寫。
- `%f`:用於輸出{==浮點數==(小數)|++f++loat / double}。
- `%c`:用於輸出{==字元==|++c++haracter}。
- `%s`:用於輸出{==字串==(字元陣列)|++s++tring}。
讓我們看一個範例:
```c=
#include <stdio.h>
int main() {
int num = 16;
float pi = 3.14159;
char letter = 'A';
char name[] = "Apple";
printf("Integer: %d\n", num);
printf("Float: %f\n", pi);
printf("Character: %c\n", letter);
printf("String: %s\n", name);
return 0;
}
```
這段程式碼會輸出:
```
Integer: 16
Float: 3.141590 // *註: %f 預設輸出是小數點後6位,詳見下方的進階學習。
Character: A
String: Apple
```
---
::: spoiler 進階學習 —— 進階版格式化字串
### 格式化字串中的特殊格式控制符
使用 `printf` 函數時,我們可以在上方學到的基礎格式控制符中,再加入一些特殊的格式控制符,以達到控制浮點數的==小數點位元數==和==整數的最小欄位寬度==:
- `%f`:用於輸出==浮點數==,預設情況下會顯示{==6位元小數==|小數後6位}。
例如:`printf("%f", 3.14159);` 將會輸出 `3.141590`。
- `%.nf`:透過 `.n` ( `n` 為一整數),可以控制輸出的==小數點後的位數==。
例如:`printf("%.2f", 3.14159);` 將會輸出 `3.14`,只顯示2位小數。
- `%m.nf`:結合 `m` 與 `n` ( `m`、`n` 皆為一整數),可以控制輸出的==整個數位的最小欄位寬度==和==小數點後的位數==。
::: info
位數的欄位寬度:==整數\+小數點1格\+小數==的總長度。當這三個加起來長度不足設定值的最小欄寬度,則預設在前方補==空白==直到符合最小欄位寬度;若長度超過設定值,則照常輸出,不會刪減數字。
:::
例如:`printf("%6.2f", 3.14159);` 將會輸出 ` 3.14`,總寬度為6,前方2格空白,小數點後2位。
例如:`printf("%4.2f", 123.456);` 將會輸出 `123.46`,由於數字位數(共6位)超過最小欄位寬度(4位),因此全部輸出,而小數點後則輸出2位。
- `%md`:通過 `m` 可以控制輸出的==整數的最小欄位寬度==。
例如:`printf("%5d", 42);` 將會輸出 ` 42`,總寬度為5,前方3格空白。
下方是一些範例,展示了如何使用這些特殊的格式控制符:
```c=
#include <stdio.h>
int main() {
float pi = 3.14159;
int num = 42;
printf("Float with default precision: %f\n", pi);
printf("Float with 2 decimal places: %.2f\n", pi);
printf("Float with width and 2 decimal places: %8.2f\n", pi);
printf("Integer: %d\n", num);
printf("Integer with width: %5d\n", num);
return 0;
}
```
結果:
```
Float with default precision: 3.141590
Float with 2 decimal places: 3.14
Float with width and 2 decimal places: 3.14
Integer: 42
Integer with width: 42
```
||<small>感謝 @ChatGPT 協助撰寫</small>||
:::
# 輸入 —— `scanf()`
`scanf` 函數是以{==格式化==|++f++ormatted}的方式從使用者輸入中讀取資料。與 `printf` 類似(除了double,詳見下方說明),需要構建==格式控制字串==,並使用格式預留位置來指定要讀取的資料類型。
需要注意的是, `scanf` 需要使用「==取址運算子 `&`==」來傳遞變數的記憶體位址,以便將輸入的值存儲到變數中。(這裡要講清楚會有點複雜,所以先記起來要用 `&` 就好)
- `%lf`:用於輸入{==雙精度浮點數==|double / long double}。
::: info
在C語言中,`%f` 可以用於==輸入和輸出 float== 以及==輸出 double==;`%lf` 則是專門用於==輸入 double / long double==。
在C++中,`%lf` 和 `%f` 都可以用於==輸入和輸出 double==。
:::
看下方例子:
```c=
#include <stdio.h>
int main() {
int num;
double f;
printf("Enter an integer: ");
scanf("%d", &num);
printf("Enter a double: ");
scanf("%lf", &f);
printf("Entered integer: %d\n", num);
printf("Entered double: %lf\n", f); // 這裡用 %f 也可以正常輸出
return 0;
}
```
結果:
```
Enter an integer: 314
Enter a double: 2.71828182846
Entered integer: 314
Entered double: 2.718282 // %f, %lf 預設輸出皆是小數後6位
```
# 總結
`printf` 和 `scanf` 函數是C語言中處理==輸入和輸出的關鍵==。通過瞭解這兩個函數的使用方法,可以更加輕鬆地處理格式化的輸入和輸出,為你的程式增添更多的功能和交互性。希望這次的教學能夠幫助你更好地掌握這些重要的C語言概念!
||<small>我懶著寫結語了,所以這段是ChatGPT寫的</small>||
---
{%hackmd Wd1xvc_AQuSzWZPcQXSn3Q %}
<!-- the theme made by Luminous-Coder -->