# 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)`
將字串(以數字組成)轉換為整數(可接受負數)