開啟章節選單
define
罕見define 的概念
#define
是一個非常好用的小技巧,用途是「把程式碼中的某個字串替換成另一個字串」,中文名稱叫做「巨集」,你可以透過 #define
來把程式碼寫的更簡短!
define 的基本使用方式
#define
的使用方式很簡單,只要在程式碼中加入 #define
並指定一個名稱和一個值,之後在程式碼中使用這個名稱時,程式碼會自動替換成你所指定的值:
#define MAX 10 cout << MAX << endl; // 10 int a = MAX; cout << a << endl; // 10 vector<int> v(MAX, 0); cout << v.size() << endl; // 10
#define
的原理其實就是在編譯階段將程式碼中的 MAX
字串替換成 10
,所以在編譯後的程式碼中是看不到 MAX
這個字串的。
#define
的行尾不需要加分號 ;
,除非你想把分號也一起定義進去。
而且也可以用來替換更複雜一點的程式碼:
#define pii pair<int, int> #define mp make_pair pii p = mp(1, 2); cout << p.first << " " << p.second << endl; // 1 2
當然也可以 #define
在 main
函式裡面,甚至是迴圈或者條件式裡面:
int main() { #define MAX 10 cout << MAX << endl; // 10 for (int i = 0; i < MAX; i++) { #define cool_variable i cout << cool_variable << " "; } cout << endl; }
#define
最有意思的部分就是,它還可以拿來取代一些符號!
#include <bits/stdc++.h> #define ouo << #define uwu cout #define owo endl #define awa int #define qwq main() #define u_u using #define AWA namespace #define OaO std u_u AWA OaO; awa qwq { uwu ouo "Hello World" ouo owo; }
是不是很好玩呢?這樣就可以讓別人看不懂你的程式碼了!
define 一個函式
#define
也可以用來定義一個函式:
#define ADD(a, b) ((a) + (b)) int sum = ADD(1, 2); cout << sum << endl; // 3
這樣就可以把 ADD
這個函式定義在程式碼中,而且不用寫 return
,這樣的好處是可以讓程式碼更簡潔,但缺點是沒辦法像函式一樣做型態檢查,所以要小心使用。
多行 define
#define
也可以定義多行的程式碼,只要在每行的最後加上 \
即可:
#define SWAP(x, y) \ int tmp = x; \ x = y; \ y = tmp; int a = 1, b = 2; SWAP(a, b); cout << a << " " << b << endl; // 2 1
好用的 define
尤其是在追求速度的競賽程式的文化中,已經發展出了許多經典的 #define
應用,例如:
#define rep(i, n) for (int i = 0; i < (n); i++) #define for(i, a, b) for (int i = (a); i < (b); i++) #define F first #define S second #define pb push_back #define mp make_pair #define pii pair<int, int> #define all(x) (x).begin(), (x).end()
上面這些 #define
都是為了讓程式碼更簡潔,例如 rep(i, n)
可以取代 for (int i = 0; i < n; i++)
,F
可以取代 first
,pb
可以取代 push_back
,等等。
而接下來介紹的這類 #define
則是有特定功能性的。
首先第一個就是用來避免 size_t
運算時變成負數造成錯誤,比如陣列為空的時候執行 v.size() - 1
就會變成一個很大的數字,這時候就可以用這個 #define
來避免這個問題:
#define sz(x) (int)(x).size()
接下來是用來加速程式輸出的 #define
,原因 endl
這個語法其實不只有換行的功能,它還會同時刷新緩衝區,所以如果你非常大量的使用 endl
來換行,可能會造成程式執行速度變慢,這時候可以用這個 #define
來加速程式輸出:
#define endl '\n'
你有遇過因為數字太大而造成 overflow 的問題嗎?這時候可以用這個 #define
預先把 int
都定義成 long long
來避免這個問題,不過要注意有些函式傳值的時候要注意型態,且如果造成 TLE 或 MLE 可能要考慮改回 int
:
#define int long long
最後是用來避免浮點數精度不夠高的問題,這時候可以用這個 #define
把 double
定義成 long double
來避免這個問題,當然這樣會增加程式的執行時間與記憶體使用量,所以要視情況使用:
#define double long double
小測驗
下列何者為正確的 #define 用法?