---
# System prepended metadata

title: C語言入門

---

# 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)











 



  




