###### tags:`C語言`、`重點筆記`
# <font color = "#f00"> 參考資源 </font>
## 書籍
:::success
* C語言教學手冊 第四版
:::
# <font color="#f00">第一章節 認識C語言</font>
## <font color="#AC19C9">C語言概述</font>
* **創造者:** **Dennis Ritchie**
* **前身:B語言**
>1. 原先用於撰寫DEC PDP-11電腦的系統程式(此程式與Unix系統密不可分)
>2. 現已成功植入個人電腦
>ex:Turbo C、Microsoft C ……

---
## <font color="#AC19C9">C語言特色</font>
### 1. 高效率的編譯式語言
原始程式碼編輯完成後,需轉換成機器碼(machine code)後,才能正確執行。
ps:所有程式語言度附有這種轉換程式。(直譯器、編譯器)
* **直譯器(interpreter)**
1. 先檢查該行敘述,有錯誤立即中斷,直至修正後才繼續執行。
2. 優點:占用記憶體較少
缺點:執行速度慢、效率低
| 示意圖 (直譯器) |
| -------- |
|  |
* **編譯器(compiler)**
1. 先檢查所有程式碼,然後編譯成可執行檔;當程式每修改一次,就須重新編譯。
2. 執行效率高於直譯器(interpreter)
| 示意圖 (編譯器) |
| -------- |
| |
### 2. 介於高階與低階之語言
程式語言可依其特性分為「高階語言」、「低階語言」
1. C語言兼顧了低階優點(硬體控制)和高階(易於撰寫、除錯),故人稱「中階語言」。
2. C語言可容易的連結「組合語言」,提高執行效率。
* **低階語言(ex:組合語言):**
1. 優點:執行效率高、對硬體控制程度相當好
缺點:艱澀難懂、維護不易
* **高階語言:**
1. 敘述性語言
2. 優點:易於撰寫、除錯
缺點:執行效率低、對硬體控制程度差
### 3. 靈活的程式控制流程
可容易設計出具有結構化及模組化的程式語言

### 4. 可攜性佳
1. 可攜性(portability)就像是硬體的相容性(compatibility)一樣
2. 可攜性意味著某一系統所撰寫的程式語言,可在少量修改或不修改的情況下,即可在另一作業系統執行。
ex:在Unix的C程式碼拿到Windows的環境裡執行,僅需修改少量程式碼,再重新編譯即可執行。
### 5. 為程式設計師所做的語言
1. 可直接依記憶體位址來存取變數,以提高程式執行的效率。
2. C語言也提供了豐富的運算子(operator),使語法更為簡潔有力。
3. 大多數C語言環境都提供了已撰寫好的程式庫(library),內含許多C語言函數供使用者無需重新撰寫程式碼。
---
## <font color="#AC19C9">程式的規劃與實作</font>
程式撰寫需經歷6個步驟
### 1. 規劃程式:
* 撰寫這個程式的目的為何?
* 使用者是誰?
* 需求在哪?
| 流程圖
|-------- |
| |
||

### 2. 撰寫程式碼及註解:
加上註解可增加維護程式的容易度、可讀性。
### 3. 編譯與連結程式:
程式藉編譯器 → 電腦看得懂,在轉換後透過連結器與函數模組連結 → 可執行之程式。
### 4. 執行程式:
通常編譯完程式,沒有錯誤後,編譯程式會製作一個可執行檔。
### 5. 除錯與測試:
* **語意錯誤 (semantic error):**
> 邏輯錯了。
* **語法錯誤 (syntax error):**
> 語法錯了。
### 6. 程式碼的修飾與儲存:
執行結果沒問題;可將程式增加可讀性或簡化程式。
---
## <font color="#AC19C9">基本流程</font>
| 示意圖 |
| -------- |
| |
---
## <font color="#AC19C9">編譯與執行過程</font>
1. compiler除了檢查語法是否正確,還會讀取標頭檔(header file),根據其記載的函數原型(prototype),檢查函數用法是否合乎規則;皆無錯誤後產生一個目的檔。
ps:目的檔:已編譯且沒錯的程式
2. 目的檔(object file)產生後,則由連結器(linker)連結object file和函數庫(library),成為一個「.exe」的可執行檔案。
ps:執行檔:成為一個獨立個體,無須環境即可執行。
> 函數是C語言的基本單位,C語言由函數組成。
> * 若要使用函數,使用對應的標頭檔即可。
> * 不同的函數集合再一起,統稱"函數庫"。
| 示意圖 |
| -------- |
| |
---
# <font color="#f00">第二章節 C語言基本概述</font>
## <font color="#AC19C9">簡單的例子</font>
```c=
/* prog 2-1 , C語言 */
#include <stdio.h>
#include <stdlib.h>
int main(void){
int num;
num = 2;
printf("I have %d cats.\n",num);
printf("You have %d cats, too.\n",num);
system("pause");
return 0;
}
```
* **註解**
* 「//」 、「/* */」
* **#include <stdio.h>**
1. 告訴computer 把stdio.h,包括(include)進來。
2. 凡定義「输入」、「输出」函數的格式。
> stdio ⇒ standard input/output的縮寫。
> .h ⇒ header 的字首。
* **#include <stdlib.h>**
* 標準函數庫
> stdlib ⇒ standard library的縮寫。
* **int main(void)**
1. 定義 main 函數(範圍從左大括號到右大括號)。
2. main 為主函數(程式開始執行的起點)。
3. 每個獨立C程式一定要有 main()函數。
> int ⇒ integer的縮寫(整數之意)。
> void ⇒ main()函數不須傳入任何引數。
* **int num;**
* 宣告num為一個整數型態的變數。
* **num = 2;**
* 設定敘述。
* **printf("I have %d cats.\n",num);**
1. 「%d」以num值來取代(十進位格式)。
2. 「/n」為換行的控制字元。
* **system("pause");**
1. 使程式執行到這便先暫停。
2. 不會自動關閉DOS視窗,可不用撰寫此敘述。
* **return 0;**
1. 由main()函數傳回整數 0 ,此數值由系統接收。
2. 已傳回 0 代表程式順利執行,傳回其他整數表示程式出錯。
> 因傳回值為整數,所以main()函數必須指明傳回值的型態為int。
## <font color="#AC19C9">標頭檔 (header file)</font>
* #include為C語言前置處理器(pre_processor directive),因為是在編譯前執行,故稱「前置」處理器。
* 一些以「#」開頭的指令都屬於前置處理器。
1. 不含括stdio.h或stdlib.h標頭檔也可以編譯?
Ans: * 某些編譯器會將常用的標頭檔自動載入。
* 有些編譯器發現沒含括標頭檔之後,會出現警告訊息,並自動含括該有的標頭檔。
ps:建議都仍打上標頭檔避免程式出錯。
2. 含括了不必要的標頭檔是否會增加編譯後程式大小?
Ans:不會;沒使用到的資訊不屬於程式範圍,故不會增加程式大小。
## <font color="#AC19C9">主函數main()與函數的本體</font>
1. main()是一個不可或缺的函數,他是程式執行的開端,沒他程式無法動。
2. 每一個C程式必須有一個main()函數,而且只能有一個。
3. 從左大括號開始到右大括號結束,此區間程式碼稱為main()函數的本體(body)。
4. 用來完成特定工做的程式片段稱為「區塊(block)」。
ps:本體內的每個指令敘述結束後,必須以分號「;」做結尾。

## <font color="#AC19C9">變數與常數</font>
1. 變數可用來存放資料。
2. 在同一個敘述中,每個變數皆須以逗號分開。
3. 可依個人喜好決定變數名稱,但不可使用「關鍵字(keyword)」。
4. 不管變數的值如何改變,其值永遠占用相同記憶空間。
* **宣告變數的好處**
* 方便編譯器找到錯誤的變數名稱。
* 避免變數名稱打錯。
* 除錯容易。
* 增加程式的可讀性。
* 便於程式碼的維護。
* **常數(constant)不同於變數,其值固定。**
---
## <font color="#AC19C9">識別字及關鍵字</font>
### 識別字(identifier)
使用者自訂;只要能代表變數意義即可。
### 關鍵字(keyword)
用來命名變數或函數的文字(C語言預先定義的識別字)。

### 提高程式的可讀性
1. 建議採用固定字距(fixed spaced)的字體。
2. 將程式碼縮排(indent)。
3. 加上註解。
---
# <font color="#f00">第三章節 基本資料型態</font>

## <font color="#AC19C9">無號整數</font>
1. 當資料絕對不會出現負數的時候使用。
2. 其正數的表示範圍變為原先2倍。

## <font color="#AC19C9">溢位(overflow)</font>
數值大小超過變數可表示範圍。

```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
short sum,s = 32767;
sum = s + 1;
printf("s + 1 = %d\n",sum);
sum = s + 2;
printf("s + 2 = %d\n",sum);
return 0;
}
```
## <font color="#AC19C9">字元型態 char</font>
1. 字元常數必須放在單引號「''」,而非雙引號「""」。
2. 字元格式碼為「%c」。
ps:字元常數與字串常數是有區別的!!!
前者用單引號「''」包圍字元,後者則用雙引號「""」包圍。
```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
char ch ='a';
printf("ch = %c\n",ch);
printf("ASCII of ch = %d\n",ch);
return 0;
}
```
```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i = 298;
printf("ASCII(%d) = %c",i,i);
return 0;
}
```
## <font color="#AC19C9">跳脫字元與跳脫序列
</font>
對於某些無法直接用鍵盤輸入的字元,C語言是以反斜線字元「\」,加上一個控制碼作為一個完整的特殊字元。
* 反斜線「\」稱為跳脫字元(escape character)。
* 反斜線「\」加上控制碼,稱為跳脫序列(escape sequence)。

## <font color="#AC19C9">浮點數型態 float</font>
小數型態的數值;浮點數(floating point)
* 要印出浮點數,可用「%f」格式碼。
* 要以指數的型式列印浮點數,可用「%e」格式碼。
```c=
/* floating point example*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
float num1 = 123.45f;
float num2 = 4.65e-3f;
printf("num1 = %e\n", num1);
printf("num2 = %f\n", num2);
system("pause");
return 0;
}
```
## <font color="#AC19C9">倍精度浮點數 double</font>
1. 表示範圍需要更大時,可使用倍精度浮點數double。
2. 也是用「%f」格式碼。
ex:「%16.12f」代表共16個字元,其中有12個字元是小數點之後的位數。

## <font color="#AC19C9">查詢常數、變數或資料型態所佔位元組</font>
* **sizeof 指令 (1)**
* 查詢變數佔了多少個位元組的語法:

* **sizeof 指令 (2)**
* 查詢資料型態所佔的位元組:

```c=
/* 列印出各種資料的長度 */
#include <stdio.h>
#include <stdlib.h>
int main(void){
char ch;
float num;
printf ("sizeof(2L) = %d\n", sizeof (2L));
printf ("sizeof(ch) = %d\n", sizeof(ch));
printf ("sizeof(num) = %d\n", sizeof(num));
printf ("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(long) = %d\n", sizeof(long));
printf("sizeof(short) = %d\n", sizeof(short));
system("pause");
return 0;
}
```
## <font color="#AC19C9">資料型態的轉換</font>
* **將資料型態轉換成另一種型態的語法:**

```c=
/* 浮點數轉換成整數的範例: */
#include <stdio.h>
#include <stdlib.h>
int main(void){
int n1,n2;
float num1=3.002F, num2=3.988F;
n1 = (int) num1;
n2 = (int) num2;
printf ("numl=%f, num2=%f\n", num1, num2);
printf("nl = %d, n2 = %d\n", n1, n2);
system("pause");
return 0;
}
```
```c=
/* 整數轉換成浮點數的範例: */
#include <stdio.h>
#include <stdlib.h>
int main(void){
int num = 5;
printf ("numl / 2 = %d\n",num/2);
printf("(float)num/2 = %f\n",(float)num/2);
system("pause");
return 0;
}
```
---
# <font color="#f00">第四章節 格式化的輸出與輸入</font>
## 輸出函數printf()
可表達文字、意念、資訊…
由print(列印)和format(格式)所組成,也就是「格式化列印」。
* printf()函數使用格式:

* 格式字串必須以雙引號包圍,裡面填入欲輸出的字串與項目格式。
* 而項目1、項目2等可以是常數、變數或是運算式。
* 格式字串裡有幾個格式碼,後面就應該有相同數目的項目。
* 每個引數需用逗號隔開。
```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
int a = 2, b = 3;
printf("I have %d dogs and %d cats.\n",a,b);
return 0;
}
```
## 用於printf()函數的格式碼
不同型態的資料內容必須配合不同的列印格式碼。
ps:若要列印出百分符號「%」,格式碼需用「%%」。

## 控制輸出欄位的寬度
若想讓資料在輸出時,能有固定的欄位寬度,可以在「%」後面加上寬度的數值。
ex:「%6.2f」表示包含小數點總共6個位數,小數點右邊只要顯示2位數。
```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
int num1 = 32, num2 = 1024;
float num3 = 12.3478f;
printf("num1 = %6d\n",num1);
printf("num2 = %-6d\n",num2);
printf("num3 = %6.2f\n",num3);
return 0;
}
```
## printf()函數的修飾子
格式碼「%-6d」裡的負號與數字6便是printf()函數的修飾子(modifiers)。

```c=
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i = 1234;
printf("i = %+08d\n",i);
return 0;
}
```