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