專案建置[6]
by 鹽亞倫
Headers
我們來看看上禮拜的code
可以發覺
宣告、實作與測試
全部都混再一起了
程式變的又臭又長
事實上,一個比較好專案當中
應該要把不同功能的程式碼放在不同的檔案當中
所以要怎麼做ㄌㄟ˙
假設今天有一個class a
其實我可以將a的實作部分另外放在一個檔案當中
class A{
int x, y, z;
void print();
}
int main() {
A a;
cin >> a.x >> a.y >> a.z;
a.print();
}
void A::print() {
cout << "("
cout << this->x << ", ";
cout << this->y << ", ";
cout << this->z << ")\n";
}
所以要怎麼做ㄌㄟ˙
假設今天有一個class a
其實我可以將a的實作部分另外放在一個檔案當中
class A{
int x, y, z;
void print();
}
void A::print() {
cout << "("
cout << this->x << ", ";
cout << this->y << ", ";
cout << this->z << ")\n";
}
class A{
int x, y, z;
void print();
}
int main() {
A a;
cin >> a.x >> a.y >> a.z;
a.print();
}
main.cpp
a.cpp
要注意的是,宣告必須在兩個地方都存在
可是假設我今天linked list的宣告那麼長
又要在很多個檔案裡面使用它
一直複製好麻煩?
因此,C/C++出現了標頭檔
#include <iostream>
#include "person.h"
其中,用<>的話代表是系統標頭檔
例如電腦
的/usr/bin/include中會有一個iostream.h
用 "" 的則是你自己寫的標頭檔
,要放在同一個目錄底下來把上禮拜的Linked List的宣告變成標頭檔吧!
來研究一下我寫的haeder檔
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
.......
#endif
這個是什麼?
這是為了防止被重複引用
利用巨集指令,確保只會被一個cpp檔案引用一次
才不會重複宣告
如果在一個.h檔或是.cpp檔中,
需要用到在另外一個.cpp檔案中宣告的全域變數
需要使用extern關鍵字代表你要引用他
Ex.
main.cpp (實際宣告處)
a.cpp (引用處)
int GlobleTime;
extern int GlobleTime;
你可能會發覺你不知道該怎麼編譯執行那麼多檔案了
所以現在來講講編譯器吧
g++ 的 flags
-o
-c
-s
-shared
g++ CPP_NAME.cpp
執行檔檔名會是 a.out 或是 a.exe
一個一個慢慢來講吧
-std
-D
-g
-I
-l
-L
多檔案:
g++ FILE1.cpp FILE2.cpp FILE3.cpp
直接變成執行檔
首先是基本參數
基本上一定會加上這些
除錯用參數
-g
允許gdb相關功能
-Wall
顯示所有錯誤訊息
版本參數
-std
選擇c++版本,例如:
-std=c++11
巨集參數
-D
從這裡#define
東西,例如:
-DAaW
(相當於#define AaW)
我的常見g++用法:
g++ -g -Wall -DAaW -std=c++17 -o OUTPUTNAME.out FILENAME.cpp
檔名參數
-o
更改輸出檔名
副檔名.o
編譯以及組譯完之後會產生的二進位檔
通常如果有多個cpp檔,會先一個一個編譯成.o之後,再連結成執行檔
如何生成object files
用 -c (小寫)
g++ -c -o haha.o hahaha.cpp
將hahaha.cpp編譯成haha.o
如果沒有用-o預設會和cpp檔同名
g++ -c hahaha.cpp
(生成hahaha.o)
g++ -o hahaha.exe a.o b.o c.o
透過以上方法就可以將多個檔案編譯並執行了
#include <> 只能include系統標頭檔
#include "" 只能include同個資料夾的
啊我如果想要include別的資料夾的怎麼辦?
.
├── build
├── include
│ ├── a.h
│ └── b.h
├── lib
└── src
└── a.cpp
用 -I 參數
例如:
g++ -I./include -o haha.exe a.cpp
這樣就可以在程式碼中用<>了
-s 參數
可以先把cpp檔變成組合語言
然後之後組合語言可以再用-c參數
組合成object files
我不會組合語言 去問溫室菜
library
有一些程式碼,每一次要使用時都還要慢慢編譯,實在是太慢了
例如,整個STL加起來可能有幾萬行
不可能每次重新編譯
因此有個東西叫做函式庫(library)
本身就是二進位模式,編譯時可以直接和object files 連結,以減少重新編譯時間
(Static library)
-shared
$ gcc -c -o hello.o hello.c
$ gcc -shared -o libhello.so hello.o
$ gcc -c -o sum.o sum.c
$ ar -rcs libsum.a sum.o
-l 和 -L 參數
使用靜態函式庫
-L(大寫):資料夾
-l(小寫):檔案名
假設資料夾長這樣(pwd在build)
.
├── build
│ └── a.o
├── include
│ ├── a.h
│ └── b.h
├── lib
│ └── libhahaha.a
└── src
└── a.cpp
而我想要將a.o和hahaha函式庫編譯在一起
$ gcc -o eee.exe -L../lib -lhahaha a.o
$ gcc -o eee.exe ../lib/libhahaha.a a.o
或是
寫一個build.sh來練習編譯吧
是不是有人還沒備明天ㄉ演算法啊
話說