# C語言入門 * C語言可寫出相比其他高階語言,較具有效率的程式,可產生彷彿直接撰寫機器語言所寫出來的程式。 ![](https://i.imgur.com/H4y3TkZ.png) * ![](https://i.imgur.com/drkvher.png) * ![](https://i.imgur.com/2okBhDP.png) (跳位: 往後跳8個字元) * printf("" "" "")相當於printf(""),編譯器在編譯的時候會把這幾個雙引號的內容合起來。 如: printf("aa\n" "bb" "cc"); 會印出: ![](https://i.imgur.com/tSGgruF.png) * 寫C程式時須兼顧可讀性與效率 * ![](https://i.imgur.com/NGU0smY.png) * 撰寫程式碼時考慮的要點: 程式行數與複雜度決定中央處理器效率;變數宣告多寡決定記憶體的用量。現今以CPU效率為優先考量。 * ![](https://i.imgur.com/eHwRCPj.png) * printf("輸入為奇數?%c\n", input & 1 ? 'Y' : 'N'); (所有非零值都是True) ![](https://i.imgur.com/f9G0WLj.png) * 浮點數 = 有效數字 + 指數 優點: 可表示範圍較整數廣且較不易overflow 缺點: 約略值較不精確、運算效率較整數差 * ![](https://i.imgur.com/EKxrHxU.png) ![](https://i.imgur.com/30doINE.png) * double資料型態較float表示範圍大且精確度準;將double轉成float可能造成誤差且溢位 * Why does scanf() need "%lf" for doubles, when printf() is okay with just "%f"? --> Because C will promote floats to doubles for functions that take variable arguments. Pointers aren't promoted to anything, %f for float %lf for double %Lf for long double * ![](https://i.imgur.com/X4GE59V.png) * C語言一次僅能執行一個運算子,ex: ![](https://i.imgur.com/o7O2x2f.png) 所以此表示式會得出0的結果 * ![](https://i.imgur.com/WEaBinP.png) * Why does scanf require &? ![](https://i.imgur.com/kvHioWS.png) * 為何使用switch時,每個case後面要加上break --> 不同case之間,可共用同一段程式碼 ![](https://i.imgur.com/WXS99Ks.png) * do-while與while唯一差異僅在於do-while忽略第一次條件判斷,無論如何皆會執行第一次程式動作 * do-while格式為: do{...} while(...); --> while後須加分號以和一般while做區分 * ![](https://i.imgur.com/Yt0D6eZ.png) * 假設在同一行程式給同一個變數兩次以上的值,稱為未定義行為(產生不被預期之結果) ![](https://i.imgur.com/vI4fifE.png) * ![](https://i.imgur.com/gwJL84c.png) * ![](https://i.imgur.com/a8p2Zi7.png) * ![](https://i.imgur.com/uJgU6Gm.png) * ![](https://i.imgur.com/0Ok3Fyh.png) * ![](https://i.imgur.com/e669GSk.png) * 倘若函式回傳值型態為void,不需要有return值,當執行至函式末尾,將自動執行return * ![](https://i.imgur.com/P3THzRj.png) * 使用%c說明是輸入一個字符此時可以scanf可以接受空格,但其他控制符都以空格為結束,如%d、%s都是以空格為結束 * 區域變數假設未初始化為未定義行為,全域變數倘若未初始化亦會自動設成0 * 全域變數在呼叫main()之前(編譯前)即完成初始化;不能以函式呼叫or其他全域變數來初始化全域變數;只可用簡易數字做初始化 * 有號整數的溢位為未定義行為。而 ![](https://i.imgur.com/MsqfApz.png) * 一個程式碼可以被切割成眾多檔案,使用static命名的全域變數,只有在該檔案內可被使用;若在函式內宣告static區域變數,則只會初始化一次。 * -靜態變數的生命週期由第一次宣告開始,直到程式結束而一起消失。 -宣告靜態變數時,只要在變數宣告最前面加上static。 -由於靜態變數由第一次宣告就一直存在,所以若初始化變數於宣告的同時,數值便不會再次初始化,而是保持變化後的數值。 -當區域變數沒有特別宣告為靜態變數時會為自動變數,會自動決定生命週期。 * ![](https://i.imgur.com/mwXAUq1.png) //陣列作為參數傳遞至函式時,本身不是陣列; 因此sizeof運算子無法求得函式間傳遞之陣列的實際大小 * ![](https://i.imgur.com/7YkVx7j.jpg) * ![](https://i.imgur.com/WgCXXGh.png) * 字元陣列初始化大小不得小於字串長度;可大於字串長度,後面多餘部分會自動填補'\0'; #特殊狀況(等於字串長度),則需額外記住字串長度並適時傳入: ![](https://i.imgur.com/txr9xoM.png) * 從鍵盤輸入讀入一列字串 ![](https://i.imgur.com/Cu954DU.png) * 假設scanf讀入之資料型態有誤,其stdin中的錯誤資料並不會因此被清除,而是持續留下錯誤 ![](https://i.imgur.com/ZOH6cXR.png) --> 可在"Error: invalid input\n"後加上 fflush(stdin); //在include<stdlib.h>中利用fflush清空stdin標準輸入的資料 * ![](https://i.imgur.com/V3nBTIH.png) * ![](https://i.imgur.com/Lp8FQvD.png) * 整數與浮點數之間存在隱性轉型,但整數指標及浮點數指標之間不存在轉型 * //第三行與 result = count; 等價 ![](https://i.imgur.com/Tu3f9ds.png) * ![](https://i.imgur.com/snigbLM.png) * ![](https://i.imgur.com/TMM0mHN.png) * 常數不具記憶體位址,變數才有(才可用&) ![](https://i.imgur.com/yIfZ1CN.png) * ![](https://i.imgur.com/sRtDQZQ.png) ![](https://i.imgur.com/AcM1vJF.png) * ###陣列型別可轉型為指標 ![](https://i.imgur.com/NIo4ery.png) 並透過指標運算存取陣列元素 ![](https://i.imgur.com/9vktnqA.png) * 重要易混淆之概念: ![](https://i.imgur.com/QPDl1Hl.png) * 使用指標在函式間傳遞陣列 1. 陣列當引數傳 2. 參數型態為指標 3. 函式內部,指標相當於作為陣列使用 ![](https://i.imgur.com/rZXnhkF.png) * 指標與遞增遞減運算子 ![](https://i.imgur.com/XncWdag.png) * p++ //會先執行整個敘述後再將p的值加1 ++p //先把p的值加1,再執行整個敘述 * #虛線裡的資料為C語言系統自動產生且Read-only。宣告字元陣列時可改字元但不可改整串;宣告字元指標時恰好相反 ![](https://i.imgur.com/WprRNf3.jpg) * #strB 前面加了const 因此不能修改strB[0] 但是仍可以改指到其他字面常數 如"Test" ![](https://i.imgur.com/gSaYAAq.png) * 易混淆概念: -採用1和3,避免使用2,因為2意義不明易誤用 -7、8: 陣列無法直接被賦值,不能放在等號左邊 -9: 字元陣列可隱性轉型成字元指標,指標裡儲存陣列首元素位址 -10: strC為read-only,不允許其位址複製給strB,避免strB進行修改 -11: 字元陣列先轉成字元指標,字元指標接著轉成const字元指標,即原本可讀可寫變為僅可讀 ![](https://i.imgur.com/Iw1lEHI.png) * ![](https://i.imgur.com/gLJZxCN.png) //前面無加const,因此須確保空間有實際配置(代表空間存在且可寫入),此處不可使用字元指標 ![](https://i.imgur.com/HgI1JfA.png) * 1. 以小括弧中的*q優先解釋 --> q是一個指標,此指標儲存的記憶體位址為整個三元素陣列之位址,但中括弧裡的數字不可為空 2. 此方法可使用sizeof,但第一點中括弧裡的數字須持續做變動 ![](https://i.imgur.com/xBIvsmF.png) ![](https://i.imgur.com/UbhElLY.png) 3. 當把整數陣列隱性轉型成指標時,即失去長度的概念,此時需額外再傳遞一個size參數。雖無法採用sizeof,但可保持共用同一個print函式 ![](https://i.imgur.com/BeuOYMK.png) * ![](https://i.imgur.com/Ajcazhv.png) * ![](https://i.imgur.com/d0l4RFW.png) ![](https://i.imgur.com/HBE0lIC.png) * ![](https://i.imgur.com/S23vKFo.png) * ![](https://i.imgur.com/oM6x7wz.jpg) * ![](https://i.imgur.com/9A7ZESY.png) ![](https://i.imgur.com/5xoRTmB.jpg) * ![](https://i.imgur.com/T4m5vES.png) //指標變數初始化為0表示無指向任何記憶體位址 ![](https://i.imgur.com/FMjsZb0.jpg) * //realloc所回傳的記憶體位址與起初傳進去之記憶體位址ptr可能為同一個 ![](https://i.imgur.com/qFLypwl.png) ![](https://i.imgur.com/UpXAKGc.jpg) * ![](https://i.imgur.com/4FbvDGR.png)