1.4 Сокращение кода¶
В соревновательном программировании короткий код имеет большое значение, потому что программы нужно писать быстро. Из‑за ограничения по времени участники часто используют сокращённые обозначения типов данных и повторяющихся конструкций.
Сокращения типов (typedef и using)¶
С помощью typedef можно задать более короткое имя для типа данных. Например, тип long long довольно длинный, поэтому удобно ввести краткое имя:
typedef long long ll;
Теперь вместо:
long long a = 123456789;
long long b = 987654321;
cout << a * b << "\n";
можно написать:
ll a = 123456789;
ll b = 987654321;
cout << a * b << "\n";
Это делает код компактнее и быстрее в наборе.
typedef можно применять и к более сложным типам. Например:
typedef vector<int> vi;
typedef pair<int,int> pii;
Теперь вместо vector<int> можно писать vi, а вместо pair<int,int> — pii.
В современных версиях C++ часто используют альтернативу — using:
using ll = long long;
using vi = vector<int>;
Макросы¶
Другой способ сократить код — использовать макросы. Макрос — это текстовая подстановка, которая выполняется до компиляции программы. В C++ макросы объявляются с помощью директивы #define.
Например:
#define F first
#define S second
#define PB push_back
#define MP make_pair
Теперь вместо:
v.push_back(make_pair(x1, y1));
v.push_back(make_pair(x2, y2));
int s = v[i].first + v[i].second;
можно написать:
v.PB(MP(x1, y1));
v.PB(MP(x2, y2));
int s = v[i].F + v[i].S;
Код становится короче и удобнее для быстрого написания.
Макросы с параметрами¶
Макросы могут принимать параметры. Это удобно для сокращения циклов.
Например:
#define FOR(i,a,b) for (int i = a; i < b; i++)
Теперь вместо:
for (int i = 0; i < n; i++) {
process(i);
}
можно написать:
FOR(i,0,n) {
process(i);
}
Это особенно удобно, если такие циклы используются часто.
Осторожность при использовании макросов¶
Макросы могут приводить к труднообнаруживаемым ошибкам, потому что это всего лишь текстовая подстановка.
Рассмотрим макрос для вычисления квадрата числа:
#define SQR(x) x*x
Если написать:
cout << SQR(2+3) << "\n";
то после подстановки получится:
cout << 2+3*2+3 << "\n";
Результат будет равен 11, а не 25.
Правильная версия макроса должна содержать скобки:
#define SQR(x) ((x)*(x))
Теперь выражение:
cout << SQR(2+3) << "\n";
превратится в:
cout << ((2+3)*(2+3)) << "\n";
и даст корректный результат 25.
Итоги¶
В соревнованиях по программированию компактность кода играет важную роль:
- сокращения типов (
typedef,using) уменьшают объём записи; - макросы позволяют быстро писать повторяющиеся конструкции;
- однако макросы требуют аккуратности, так как работают как простая текстовая подстановка.
Хороший стиль в контестах — это простой, лаконичный и понятный код, который можно написать быстро и без лишних деталей.