---
# System prepended metadata

title: C語言學習筆記

---

# C語言學習筆記

## 結構化程式設計
1. 循序性結構 (sequence structure)
2. 選擇性結構 (selection structure)
3. 重複性結構 (iteration structure)

## 變數範圍
1. 區域變數 (local variable)
2. 全域變數 (global variable)
3. 靜態變數 (static variable)
> 靜態變數 : 編譯時就已配置固定的記憶體，因此主控權不在函數手上值也會保存起來，而再次宣告也不會更改值
> 用法 : static int a

## 資料型態

| Name      | Byte |
| --------- | ---- |
| char      | 1    |
| short int | 2    |
| int       | 4    |
| long int  | 4    |
| float     | 4    |
| double    | 8    |


## 跳脫序列

| Escape Sequence | Meaning            |
| --------------- | ------------------ |
| \a              | Alert              |
| \b              | Backspace          |
| \n              | New Line           |
| \r              | Carriage Return    |
| \0              | Null Character     |
| \t              | Tab                |
| \\              | Backslash          |
| \\'             | Single Quote       |
| \\"             | Double Quote       |
| \\/             | Slash              |
| \d              | ASCII (Octal)       |
| \x              | ASCII (Hexadecimal) |

## `printf()`函數的修飾子

| 修飾子 | 功能                                     | 舉例   |
| ------ |:---------------------------------------- | ------ |
| -      | 靠左對其                                 | %-3d   |
| +      | 將數值的正負顯示出來                     | %+3d   |
| 空白   | 數值為正時，留一格空白；為負時，顯示負號 | % 6f   |
| 0      | 將固定欄位長度的數值前空白處填上0        | %07.2f |

## 格式碼


| 格式碼 | 說明                |
| ------ | ------------------- |
| %c     | character           |
| %d     | decimal integer     |
| %ld    | long integer        |
| %e     | scientific notation |
| %f     | float               |
| %lf    | long double         |
| %o     | octal               |
| %s     | string              |
| %u     | unsigned decimal    |
| %x     | hexadecimal         |
| %p     | pointer             |
| %%     | percent sign        |

## 用指標宣告字串
將字串以指標宣告可以避免浪費記憶體
```clike
char *ptr="Hello World";

char *ptr2[2]={"Data1", "Data2"};
```

## 列舉型態 Enumeration
```clike
enum 列舉型態名稱{
    列舉常數1,
    列舉常數2,
    ...
    列舉常數n;
};
```
## 自訂型態 ---- typedef
使用`typedef`來簡化宣告複雜資料形態時的麻煩，給予他們一個新的名字
```c
typedef 資料型態 識別字
    
example : 

typeof struct data dt;
dt student={...};

```

## EOF簡介
EOF是C語言的關鍵詞，定義在stdio.h標頭檔中的一個整數值(其值為-1)，代表end of file，當讀取到檔案尾端時就會回傳EOF

## 檔案的觀念
### 文字檔(Text File) vs. 二進位檔(Binary File)
- 文字檔 : 所有的資料都以字元儲存(佔1位元組)，並將所有字元轉換為ASCII碼儲存
- 二進位檔 : 資料以二進位格式儲存，根據資料型態分配不同的位元組(int->4位元組)，因此檔案會比文字檔小

### 一般檔案 vs. 唯讀檔案(Read-Only)
- 一般檔案 : 可讀取資料、可寫入資料
- 唯讀檔案 : 可讀取資料、無法寫入資料

## 有緩衝區檔案存取的模式 (in `fopen()`)


| 存取模式       | 代碼 |
| -------------- | ---- |
| 讀取資料       | r    |
| 寫入資料       | w    |
| 附加於檔案之後 | a    |

## 有緩衝區的檔案處理函數


| 函數功能         | 格式及說明                                          |
| ---------------- | --------------------------------------------------- |
| 開啟檔案         | FILE *fopen(const char *filename, const char *mode) |
| 關閉檔案         | int fclose(FILE *fptr)                              |
| 讀取字元         | int getc(FILE *fptr)                                |
| 寫入字元         | int putc(int ch, FILE *fptr)                        |
| 讀取字串         | char *fgets(char *str, int maxchar, FILE *fptr) |
| 寫入字串         | int fputs(const char *str, FILE *fptr) |
| 檢查檔案是否結束 |  int feof(FILE *fptr) |
| 區塊輸入         | size_t fread(void *p, size_t s, size_t cnt, FILE *fptr)  |
| 區塊輸出         | size_t fwrite(const void *p, size_t s, size_t cnt, FILE *fptr) |

函數功能         | 格式及說明                                          |
| ---------------- | --------------------------------------------------- |
| 開啟檔案         |  開檔成功時傳回檔案指標，失敗時傳回NULL |
| 關閉檔案         | 開檔成功傳回0                          |
| 讀取字元         | 傳回被讀取的字元                          |
| 寫入字元         | 無                       |
| 讀取字串         | 讀取失敗或讀到檔尾，傳回NULL |
| 寫入字串         | 無 |
| 檢查檔案是否結束 |  尚未讀到檔尾傳回0，讀到檔尾傳回非0的值 |
| 區塊輸入         | 讀取cnt個位元組為s的資料，存放到p，傳回成功讀取的資料數  |
| 區塊輸出         | 無 |

## 無緩衝檔案標頭檔
#include <fcntl.h>
#include <io.h>
#include <sys/stat.h>

## 無緩衝區檔案的開啟模式 (in`open()`)
### 基本模式
| 檔案開啟模式 | 說明       |
| ------------ | ---------- |
| O_RDONLY     | 讀取       |
| O_WRONLY     | 寫入       |
| O_RDWR       | 讀取和寫入 |
### 修飾模式
| 檔案開啟模式 | 說明                 |
| ------------ | -------------------- |
| O_CREAT      | 若檔案不存在則開啟   |
| O_APPEND     | 寫入資料附加於當案後 |
| O_BINARY     | 開啟二進位檔案       |
| O_TEXT       | 開啟文字檔案         |

## 無緩衝區檔案的存取權限模式


| 存取屬性 | 說明 |
| -------- | ---- |
| S_IWRITE | 新資料可供寫入 |
| S_IREAD | 新資料只供讀取 |
| S_IWRITE \| S_IREAD | 可寫入可讀取 |

## 無緩衝區檔案的檔案處理函數

| 函數功能 | 格式                                                   |
| -------- | ------------------------------------------------------ |
| 開啟檔案 | int open(const char *filename, int oflag[, int pmode]) |
| 關閉檔案 | int close(int handle)                                  |
| 開新檔案 | int creat(const char *filename, int pmode)             |
| 讀取資料 | int read(int handle, char *buffer, unsigned count)     |
| 寫入資料 | int write(int handle, char *buffer, unsigned count)    |
| 檢查檔案是否結束         |  int eof(int handle)                                                      |


| 函數功能 | 備註                                                                              |
| -------- | --------------------------------------------------------------------------------- |
| 開啟檔案 | 成功時傳回檔案代號，失敗時傳回-1，oflag代表開檔模式，pmode代表存取屬性            |
| 關閉檔案 | 成功時傳回0，失敗時傳回1                                                          |
| 開新檔案 | 成功時傳回檔案代號，失敗時傳回-1                                                  |
| 讀取資料 | 最多一次讀取count位元組，存放到buffer變數中，傳回實際讀取資料的位元組，失敗傳回-1 |
| 寫入資料 | 無                                                                                |
| 檢查檔案是否結束         |  讀到檔尾傳回非0，否則傳回0                                                                               |

## 二進位檔案的存取模式 (in `fopen()`)

| 存取模式 | 代碼 |
| -------- | ---- |
| 讀取 | rb |
| 寫入 | wb |
| 附加 | ab |

## 條件式編譯

\#ifdef
\#findef
\#endif
\#else
\#elif

\#undef


## 函數整理

### `getchar()`, `getch()`, `getche()`
`int getchar(void) ...`
輸入一個字元，`getch()`直接存取不顯示, `getche()`直接存取並顯示(echo)

### `putchar()`
`int putchar(int ch)`
輸出字元

### `gets()`
`gets(字元陣列名稱);`
將輸入的字串賦值給字元陣列，當字串內有空格時也能處理，比`scanf()`更加方便

### `puts()`
`puts(字元陣列名稱/字串常數);`
輸出字串(自動換行)

### `sizeof()`
`sizeof(變數/常數);`
輸出所佔位元數

### `fflush(stdin)`
`fflush(stdin);`
清除緩衝區內資料 (如'\n')

### `rand()`, `srand()`
`int rand(void);`
回傳一個隨機正整數，若想設定範圍`[min, max]`，則可輸入`rand() % (max - min + 1) + min`

`void srand(unsigned int seed)`
將接下來`rand()`產生的亂數固定，例如 : `srand(time(NULL))`
ps. `time()`的定義在`<time.h>`ˊ中

### `pow()`
`double pow(double x, double y)`
回傳x的y次方

### `sqrt()`
`double sqrt(double x)`
回傳x的根號

### `sprintf()`
`int sprintf(char *str, const char *string, ...)`
將第二個參數的字串存入`str`，可用來將數字轉換成字串，回傳值為寫入的字元數

### `atoi()`
`int atoi(const char *strg)`
將字串(以數字組成)轉換為整數(可接受負數)