---
# System prepended metadata

title: C語言筆記

---

# C語言筆記 
## 2022/8/3
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("Hello world!\n");
    return 0;
}
```
**{}**：一個大括號表示一個區塊的開始與結束
**printf("要輸出的文字")**
**\n**　**跳脫字元** =>用來換行：每輸出一個\n就會換行一次
**用（）包起來的是字串** =>要跟程式碼中的其他指令做區別
**用""包起來的是字元**
<font color="#f00">＊printf為一段已經寫好的程式碼，若憑空使用它，編譯器無法辨識，則須於開頭使用<font color="#00f">#include</font>，使編譯器去找到<font color="#00f">stdio.h</font>這個檔案</font>
<font color="#00f">stdio.h</font> 為c語言內建的檔案，裡面有關於**printf**這個函數的用法；<font color="#00f">include</font>則會把這個檔案的內容加進程式碼
**return**：回傳一個結果=>return 0：回傳０這個值，表示程式成功執行完畢
**；分號**：C語言中的結束語句，表示當前語句已終止，其後的其他語句是新語句

<font color="#f00">***常見的跳脫字元：***</font>\n：用來換行
　　　　　　　　\t：用來縮排（<font color="#00f">等同於輸出一個 tab</font>）
　　　　　　　　\’：用來輸出一個單引號
　　　　　　　　\”：用來輸出一個雙引號
　　　　　　　　\\\：用來輸出一個反斜線
### 練習 文字圖形
![](https://i.imgur.com/v2ZecX6.png)
**寫法一**
![](https://i.imgur.com/YPzRibQ.png) 
**寫法二**
![](https://i.imgur.com/tKtauwl.png)
<font color="#f00">*</font>**寫法三**
![](https://i.imgur.com/vRB4fii.png)
## 2022/8/5

```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int integer1;
    int integer2;
    int sum;
    printf("Please enter the first integer ");
    scanf("%d", &integer1);
    printf("Please enter the second integer ");
    scanf("%d", &integer2);
    sum=integer1+integer2;
    printf("sum is %d.\n",sum);
    return 0;
}
```

**int 變數**：一個整數的變數，於此程式碼為一個名稱叫integer1（integer２／ｓｕｍ）的整數(名稱可自取)
**scanf**：表示從鍵盤讀入資料
**%d**：表是一個十進位的整數
**&取址運算子**：取址，取得位址，於此程式碼中取得名稱叫integer1（integer２／ｓｕｍ）的位址
**scanf函式：<font color="#f00">scanf("%d", &integer1)</font>**
　　　　　從鍵盤讀入一個十進位的整數， 將它儲存在變數integer1裡面
**＝指定運算子**：將右邊的結果算出來後，存入左邊的變數裡面
**printf("sum is %d.\n",sum)**：
此段程式碼運用類似跳脫的概念![](https://i.imgur.com/d8KZHAl.png)
**％d**類似一個替代品，替代逗號後的參數**sum**
### 練習 三個數字的和
![](https://i.imgur.com/NFHzHrh.png)
**寫法一**
![](https://i.imgur.com/5weHkc1.png)
**寫法二**
![](https://i.imgur.com/16Ds6Bt.png)
## 2022/8/8
### 數值交換
![](https://i.imgur.com/pAt45I2.png)
**我的寫法**
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int integer1, integer2,integer3;
    printf("Please enter the first integer ");
    scanf("%d", &integer1);
    printf("Please enter the second integer ");
    scanf("%d", &integer2);
    integer3=integer1;
    integer1=integer2;
    integer2=integer3;
    printf("integer1: %d.\n",integer1);
    printf("integer2: %d.\n",integer2);
    return 0;
}
```
![](https://i.imgur.com/Xf4hjz6.png)
**其他寫法**
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int integer1, integer2;
    printf("Please enter the first integer ");
    scanf("%d", &integer1);
    printf("Please enter the second integer ");
    scanf("%d", &integer2);
    integer1=integer1+integer2;
    integer2=integer1-integer2;
    integer1=integer1-integer2;
    printf("integer1: %d.\n",integer1);
    printf("integer2: %d.\n",integer2);
    return 0;
}
```
==integer1=integer1+integer2;==
==integer2=integer1-integer2;==
==integer1=integer1-integer2;==
<font color="#f00">此寫法使用限制：變數須為可加減之變數</font>
### 資料型別 ( Data type )
資料的型別會決定一個資料要怎麼儲存和計算
### 資料的儲存
* 電腦的記憶儲存空間是以位元組 ( byte ) 為單位組成
<font color="#f00">
    | byte | byte | byte | ...... | byte |
    | ---- | ---- | ---- | ---- | ---- |
</font>

* 每個位元組 ( byte ) 由多個位元組成 ( bit )
    * 一個位元組一般由8個位元構成 ( 實際個數為實作定義 ) 
    * 每個位元 ( bit ) 可表示0或1種值
* 任何資料型別的資料都可以轉匯成一串由0跟1組成的的序列來表示
### C語言常見的內建資料型別


|                     資料型別                     |   名稱    | 大小 ( 位元組 ) | 例子 |
|:------------------------------------------------:|:---------:|:---------------:|:----:|
|             短整數（short integer）              | short int |        2*        |  32  |
|                 整數（inteter）                  |    int    |        4*        |  32  |
|             長整數 ( long integer )              | long int  |        4*        |  32  |
|                字元 ( character )                |   char    |        1        |   ‵3′   |
| 單精福點數度 ( single-precision fioating point ) |   float   |        4*        | 3.2  |
| 倍精福點數度 ( double-precision fioating point ) |  double   |        8*        | 3.2  |
|                      無名稱                      |   void    |        ?        |      |

**==<font color="#f00">*</font>表示該大小為實作定義==**
### 使用 sizeof 看所占記憶空間的大小
* 許多型別占用的記憶體空間大小皆由「實作定義」決定，隨使用的編譯器或設定不同而可能有異
    * eg：long int大小不一定為4 ( byte ) ;在某些64bit的編譯器中，long int大小不一定為8 ( byte ) 或其他大小
* sizeof運算子可以去求使用的編譯器的某個值或型別所佔的記憶體大小 ( 單位為byte )
    使用方式：**printf("long int： %d.\n",sizeof(long int))**
### 定義變數
* 變數名稱使用前，需先宣告或定義
* 變數定義時需要指定名稱與型別：
    * <font color="#00f">資料型別</font> <font color="#0f0">變數名稱</font>;
        * <font color="#00f">int</font> <font color="#0f0">num</font>;      
        ==(讀取未指定值的變數在大部分情形下是｢未定義行為」)==
    * 在定義時也可以直接指定初始值，稱為初始化
        * <font color="#00f">int</font> <font color="#0f0">num</font> = 0;
#### 命名限制
* 名稱須由英文大小寫字母、數字與底線組成
* 數字不能開頭
* 字母大小寫不同則代表不同的名稱
* **以下字詞不可作為命名名稱使用**
auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while
### 不同資料型別間的差異
* 表示的資料意涵不同：**整數**（int）與**字元**（char）
* 表示的原理不同：**整數**（int）與**浮點數**（float）
* 可表示的值範圍不同：**短整數**（short int）與**長整數**（long int）
* 可表示的精確度不同：**單精度浮整數**（float）與**倍精度浮整數**（double）
* 有無正負數（有號與無號）的不同：**有號整數**（int）與**無號整數**（unsigned int）
## 2022/8/16
### 浮點數型別
* 浮點數（floating point）是可用來表示實數的一種方法
    * 浮點數可表示帶小數的數值
    * 浮點數所表示的可能只是一個約略值
* 在佔用一樣大記憶體空間的情況下，浮點數可表示的範圍可以大於整數表示法
    * 一樣占用4個位元組，整數二進位表示法的範圍約為10位數，但浮點數可以到將近40位數
* 浮點數可以想成是一種科學記號表示法
### 有效數字
* 圓周率：3.14159265.....
    * 取三位有效數字：3.14
    * 取四位有效數字：3.141或3.142
* 有效數字位數越多，值越精確，需要記憶的資訊也越多（**需占用更多記憶體空間**）
* 使用整數表示法儲存的整數，只要在可表示的範圍內都屬於有效數字（無誤差）
### 科學記號表示法
  123.45
 →1.2345　x　10²
 →<mark>1.23</mark>　　x　10<font color="#00f">²</font>　　→　　１２３　　２
 取三位有效數字　　　　　(有效數字)　(指數)
 <font color="#f00">此為將儲存一個實數的問題變成兩個實數的問題</font>
 
   12345000000　　　　←<font color="#00f">用4個位元儲存的整數無法表示這個數字(溢位)</font>  
 →1.2345　x　10¹⁰
 →<mark>1.23</mark>　　x　10<font color="#00f">¹⁰</font>　　→　　１２３　　10
 取三位有效數字　　　　　(有效數字)　(指數)

0.0078901　　　　 
 →7.89　x　10⁻³
 →<mark>7.89</mark>　x　10<font color="#00f">⁻³</font>　　→　 　　789　　    　 -3
 取三位有效數字　　　　　(有效數字)　(指數)

### C語言常見的內建浮點數型別 
|                     資料型別                     |    名稱     | 大小(位元組) | 有效數字大小(位元) | 指數大小(位元) |
|:------------------------------------------------:|:-----------:|:------------:|:------------------:|:--------------:|
| 單精福點數度 ( single-precision fioating point ) |    float    |      4*      |   23*(約6位位數)   |       8*       |
| 倍精福點數度 ( double-precision fioating point ) |   double    |      8*      |   52*(約15位數)    |      11*       |
|                                                  | long double |      8*      |         ?*         |       ?*       |
* 浮點數依然可能會溢位→造成未定義行為
<font color="#f00">其中一個位元通常用來表示正負數</font>
<font color="#00f">* 表示大小為實作定義</font>

### 浮點數使用的優缺點
* 優點
    * 相較占用同大小的整數格式，浮點數可以表示的數值範圍較廣，比較不容易溢位
    * 可以自然的表現小數
* 缺點
    * 浮點數表示的可能只是約略值，在做精確計算或比較時可能發生不預期的結果
    * 格式較整數格式複雜，做運算時可能效率較差 
        * 現代電腦內部通常會有專門為浮點數運算設計的硬體

## 2022/08/23
### printf 的使用
* printf是做標準輸出的一個內建函式
    * 通常'<font color="#00f">標準輸出</font>'意思就是把輸出的文字印到螢幕上
* printf使用時要給予想要輸出的字串 → printf("<font color="#f00">要輸出的字串</font>");
  eg： printf("<font color="#f00">hello!</font>");
### printf 的格式字串
* printf輸出的字串可以用類似字元跳脫的方法，放置一些<font color="#f00">格式符</font>來輸出特定格式的資料
eg：　　int sum=<font color="#f00">10</font>;
　　　　printf(<font color="#00f">"sum is %d"</font>,sum);
　　　　 →printf(<font color="#00f">"sum is %d"</font>,<font color="#f00">10</font>);
   　　　　 →printf(<font color="#00f">"sum is 10"</font>);
### 用printf 輸出整數時常見的格式符
* 在格式字串中，以%為跳脫記號，後面可加下表中的格式符代表要輸出的格式


| 格式符 |        輸出格式        | 以輸出十進位的123為例 |
|:------:|:----------------------:|:---------------------:|
|  d或i  |     十進位有號整數     |          123          |
|   u    |     十進位無號整數     |          123          |
|   o    |     八進位無號整數     |          173          |
|   x    | 十六進位無號整數(小寫) |          7b           |
|   X    | 十六進位無號整數(小寫) |          7B           |
## 2022/08/26
### 用printf輸出不同格式的整數
```c=
int a =123456789;
unsigned int b =3000000000;
printf("%d\n",a);    //123456789 →(o)
printf("%d\n",b);    //-1294961296 →(x)

printf("%u\n",b);    //3000000000 →(o)
```
<mark>理由：%d 為有號整數格式，無號整數格式應為%u</mark>
### 用printf輸出浮點數時常見的格式符
| 格式符 |             輸出格式             |     範例     |
|:------:|:--------------------------------:|:------------:|
|   %f   |           十進位浮點數           |    123.45    |
|   %e   |       科學記號表示法(小寫)       | 1.234500e+02 |
|   %E   | 科學記號表示法(大寫)1.234500E+02 | 1.234500E+02 |
### scanf的使用
scanf為一個做標準輸入的內建函式
格式scanf(<font color="#00f">"要讀入的資料格式"</font>,<font color="#00f">變數位址</font>);
　　→scanf(<font color="#00f">"%d"</font>,<font color="#00f">&a</font>);
### 用scanf輸出浮點數時常見的格式符
| 格式符 |    輸出格式    |  範例  |
|:------:|:--------------:|:------:|
|   %i   | 任何格式的整數 |  123   |
|   %d   | 十進位有號整數 |  123   |
|   %u   | 十進位無號整數 |  123   |
|   %f   |  十進位浮點數  | 123.45 |
### 計算平均
如何將三個十進位數值計算至小數位
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a,b,c;
    printf("輸入數字一:");
    scanf("%d",&a);
    printf("輸入數字二:");
    scanf("%d",&b);
    printf("輸入數字三:");
    scanf("%d",&c);
    double average = (a+b+c) / 3.;  //將int改成double
                                    //將3後面加上.
    printf("average:%f",average);   //將%d改成%f
    return 0;
}
```
#### 整數或浮點數做算術運算的結果
當兩個同為整數浮點數的值做算術運算時，其結果為同樣的型別
eg：(int)+(int)→(int)
　　(float)+(float)→(float)
#### 思考
<font color="#00f">double average = (a+b+c) <mark>/ 3</mark>;</font>→/3未被定義型別，預設為十進位整數(int)，為**字面常數**
→<font color="#00f">(a+b+c)/ 3</font>→ (int)/(int)得到(int) → 做整數除法並捨取餘數
**常見字面常數**
| 常見字面常數 |     型別     |
|:------------:|:------------:|
|     123      | int,long int |
|    123.45    |    double    |
|   123.45f    |    float     |

**double 　average = 　　3　;**　→轉型→　**double 　average = 　3.0000 　;**
 　　　　 (double)　　　(int)　　　　 　　　　　　(double)　　(double)
此稱為<font color="#f00">隱性轉型</font>：當整數轉型成浮點數時，如果在可表示的範圍裡，會轉型成最接近的浮點數值
<font color="#00f">double average = (a+b+c)　　 <mark>/ 3. </mark> ;</font>　→　<font color="#f00">/3.</font>為浮點數型別(double)
　　　　　　　　　(int)　　　(double)
***當兩個不一樣整數或浮點數型別的值做算術運算時，如果可以算，會隱性轉型成範圍較大的型別並算出該型別的值**
#### 隱性轉型與顯性轉型
* 隱性轉型
  double average = (a+b+c) /<font color="#f00"> 3.</font>;
* 顯性轉型
  double average = (a+b+c) / <font color="#f00">(double) 3　　</font>;
  　　　　　　　　　　 　　　　　　(int)
### 字元型別
* C語言主要有兩種字元型別
    * **char**
    * **wchar_t**
* 一般我們使用的是char型別，wchar_t型別使用在**寬字元**
    * char型別占用的記憶體大小為一個位元組
    * 中文字有幾種可能?
        * 使用<font color="#00f">多個char</font>或<font color="#00f">wchar_t</font>表示
#### char型別
* 特色
    * 常見的是使用ASCII編碼
    * 型別占用一個位元組
    * 是一種**整數**的型別
* 字面常數
    * 用一組單引號括住：<font color="#f00">'A'　'a'　'0'　'\n'</font>　<mark><font color="#f00">*</font>用雙引號""括住的是字串</mark>
* printf與scanf的字元格式符：**%c**
#### 使用char
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char ch = 'A';       //宣告定義一個叫做ch的字元變數，並初始化為'A'
    printf("%c\n",ch);   //用字元的格式印出ch字元變數的內容
    return 0;
}
```
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char ch = 'A' + 1;     //→變為B
    printf("%c\n",ch);    
    return 0;
}
```
#### char 型別的算數運算
* 'A' + 1 得 'B'
* 'a' + 1 得 'b'
* 'A' - 1 得 '@'
* 'A' + '1' 得 'r'
如何得知？→ <font color="#f00">ASCII碼對照表</font>
![](https://i.imgur.com/gLJ0NNN.png)
### 練習 字元大小寫的轉換
寫一程式，讓使用者輸入一個大寫字母後，將其轉換成對應的小寫英文字母後輸出
**寫法一**
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char A;
    printf("請輸入一個大寫字母: ");
    scanf("%c",&A);
    char a = A+32;
    printf("%C",a);
    return 0;

}
```
![](https://i.imgur.com/lIknPJf.png)
**寫法二**
```c=
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char A;
    printf("請輸入一個大寫字母: ");
    scanf("%c",&A);
    char a = A+('a'-'A');
    printf("%C",a);
    return 0;

}
```
## 2022/09/11
### 型別選擇


|            用途            |  型別  |        注意        | printf 格式符 | scanf 格式符 |
|:--------------------------:|:------:|:------------------:|:-------------:|:------------:|
|      整數（一般情況）      |  int   | 不要算到超過九位數 |      %d       |      %d      |
| 浮點數（帶小數or為數過多） | double |  可能與真實質有差  |      %f       |     %lf      |
|      字元（可讀文字）      |  char  |                    |      %c       |      %c      |

### 運算元、運算子、表示式
<mark>3<font color="#f00">+</font>5<font color="#f00">*</font>2</mark>　→　此為表示式，紅色部分為運算子，其餘部分為運算元
**運算元**：資料，具有型別跟值　　　**運算子**：對資料做運算　　　
**表示式**：表示一筆資料，具有型別跟值
<font color="#f00">＊</font>運算子間有先後順序，一次執行一個運算，遵循一般的數學概念

![](https://i.imgur.com/jFbObCo.png)
![](https://i.imgur.com/aGuxCrk.png)
![](https://i.imgur.com/FWFZAeX.png)
![](https://i.imgur.com/qzRDpKP.png)
![](https://i.imgur.com/IADAmN3.png)
![](https://i.imgur.com/9k31qYV.png)
![](https://i.imgur.com/JVec8lI.png)
