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
