<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":"[]"}