<div id="TITLE"> <div style="float: left;"> <strong>とある撞到資訊週の</strong> </div> <div id="super"> <strong>醒</strong> </div> <div style="float: left;"> <strong>獅大雜燴</strong><br> <b id="base"><strong>Waking Lion</strong></b> </div> </div> <div style="visibility: hidden; overflow: hidden;"> <iframe width="560" height="315" src="https://www.youtube.com/embed/T_0sh30AONQ?loop=1&autoplay=0" frameborder="0" allowfullscreen> </iframe> </div> <style> #super { background: red; color: white; font-size: 90px; } #TITLE { color: red; font-size: 60px; width: 100%; } #super { float: left; } #base { font-size: 36px; vertical-align: top; float: right; } </style> --- # 大雜燴 ###### tags: `wake lion` `csie` --- ## 這堂課要幹嘛? * 程式編譯 * make * Hello World! * 資料流重導向 --- ## 程式編譯 * 前處理(preprocess) * 編譯(compile) * 組譯(assembly) * 連結(link) * 執行(execute) ---- * gcc 其實是compiler driver,不單純是編譯器 * 其中包含了: * Preporcessor 預處理器(cpp) * Compiler 編譯器(cc1) * Assembler 組譯器(as) * <b style="color: #14ff00;">Linker</b> 連結器(ld) --- ### 預處理(preprocess) #### `#include`是怎麼一回事? ![](https://i.imgur.com/z0XbABL.png) ---- <h3 style="color: #ce1085;">PRACTICE MODE</h3> * 寫個Hello World! `$ gcc -o pre.c -E hello.c` * 打開pre.c看看發生什麼事 ---- `gcc -E` 代表對輸入檔進行 __預處理__ 包含: * 把`#include`的檔案內容展開到原始碼中 * 把`#define`的東西做代換 * `#ifdef`, `#ifndef`, `#elif`, `#endif`, ... --- ### 編譯 <h3 style="color: #ce1085;">PRACTICE MODE</h3> * 寫個Hello World! `$ gcc -S hello.c` * 打開hello.s看看發生什麼事 ---- `gcc -S` 代表對輸入檔進行 __編譯__ 和我們平常說的編譯不同 這邊是把原始碼編成 __組合語言__ 組合語言要在轉換成 __機械碼__ 則是透過 __組譯器__ --- ### 組譯 <h3 style="color: #ce1085;">PRACTICE MODE</h3> `$ gcc -c hello.c` * 打開hello.o看看發生什麼事 ---- `gcc -c` 代表對輸入檔進行編譯,但不連結 所以輸出的hello.o檔大部份已經是機器碼了 --- ### 連結 * 觀察.o檔和平常編出來的執行檔差異 * <b style="color: #14ff00;">Linker</b>會把剛剛編譯完留下的symbol用位址代換,完成完整的機械碼 --- # Make ---- * 下`make`指令時,make會自動讀取同一個目錄中的makefile(M可以是大寫或小寫) ![](https://i.imgur.com/SqN1GN4.png) * 兩者都有時會採用小寫的makefile ---- ## make用處 * 幫你下指令編譯程式(重要!) * 檢查哪些檔案被修改過,只重新編譯修改過得部份 ---- ### Makefile寫法 * 變數可直接宣告 * 取用變數時用`$(變數名稱)` (只有一個字可以省略()) ---- * 最簡單的Makefile * 用法:`$ make <程式名稱>` * 結果:`$ gcc -g -Wall -std=c99 hello.c -o hello` ![](https://i.imgur.com/2lsvd2j.png) ---- <h3 style="color: #ce1085;">PRACTICE MODE</h3> 練習Makefile和`make`指令 ---- ### 進階Makefile ![](https://i.imgur.com/vVA0WS1.png) <b style="color: red;">第二行開頭一定要用tab!</b> * 如果需要的檔案沒辦法用Makefile中的規則產生,資料夾中也沒有,就會出現錯誤訊息 * 選項`all`:下`make`時的目標 ---- 實例: ![](https://i.imgur.com/xBoP7Bk.png) --- ## 程式分檔 ---- ### 如何自己寫.h檔? * 把function __宣告__ 寫在.h * 把function __定義__ 寫在.c ---- 例: add.h ![](https://i.imgur.com/NZOtFkx.png) add.c ![](https://i.imgur.com/cZSneiJ.png) ---- main.c ![](https://i.imgur.com/NmbhQx1.png) ---- ### 如何編譯? `$ gcc -c main.c` `$ gcc -c add.c` `$ gcc -o main main.o add.o` ---- <h3 style="color: #ce1085;">PRACTICE MODE</h3> 寫一個分檔的次方程式(計算a的b次方) 並用Makefile自動化編譯 --- # Hello World ---- ![](https://i.imgur.com/NRAMHYI.png) ---- ## ANSI色碼表 ```c= #define NONE "\033[m" //取消顏色用 #define RED "\033[1;32;31m" #define GREEN "\033[1;32;32m" #define BLUE "\033[1;32;34m" #define CYAN "\033[1;36m" #define PURPLE "\033[1;35m" #define BROWN "\033[1;33m" #define YELLOW "\033[1;33m" #define WHITE "\033[1;37m" ``` --- # 資料流重導向 ---- ```graphviz digraph transport { nodesep=1.0 node [color=Black, fontname=Courier, shape=box] edge [color=Red, fontname=Courier, style=dashed] {rank=same;screen file} {file screen}->program [label = "STDIN", fontsize = 8, fontname=Courier] program->{screen file} [label = "STDOUT", fontsize = 8, fontname=Courier] } ``` ---- ||STDIN|STDOUT| |:-:|:-:|:-:| |符號|<|> or >>| ---- ## STDIN < 檔案 * 用 "檔案內容" 代替 "鍵盤輸入" ---- ## STDOUT > 檔案 * 檔案若不存在,系統會自動建立 * 檔案存在時,檔案會被覆蓋掉 ---- ## STDOUT >> 檔案 * 檔案若不存在,系統會自動建立 * 檔案存在時,會在檔案尾端開始寫入 ---- ## 用途 * 輸入大量測資 or 需要重複輸入同測資 * 需要將螢幕輸出的資訊存下來時
{"metaMigratedAt":"2023-06-14T12:10:34.051Z","metaMigratedFrom":"Content","title":"大雜燴","breaks":true,"description":"程式編譯","contributors":"[]"}
    1331 views
   Owned this note