【rep(i,n)】競プロの解説で最初わからなかった表記まとめ
少し前に競プロを始めた。競プロではC++なる言語が使われていると聞いてネット上で軽くC++の勉強をしてから、いざ公式の解説を見てみるとよくわからない表記がいくつかあり、心が折れそうになったので簡単にまとめる。
当方競プロ、およびC++初心者なのであしからず。
using namespace std;
- 役割:std::coutやstd::cinの"std"を省略できるようになる
本来はいちいちstd::coutやstd::cinといった形で"std::"を書かなければならないが、using namespace std;を記載することでこれを省略できる。
例えば、本来であれば以下のようになるコードを、
std::cout << "Hello World!" << std::endl;
次のように書くことができる。
using namespace std; // なお、この行は本来はmain()関数の外側に書く
cout << "Hello World!" << endl;
これは名前空間というC++の概念に起因するもので、C++では名前空間を用いることで名前の衝突を避けている。(例えば同じ太郎くんでも、A組の太郎くんとB組の太郎くんと言った形で「組」という名前空間を用いることで、同じ名前でも区別できる)
std::coutやstd::cinといった関数はstdという名前空間に属しているcoutやcin関数という意味だが、これを毎回書くのは大変ということで、この一行を記載することで「このコードでは名前空間はstdですよ」とコンピュータに伝えることができる。
using namespace std;は危険?
名前空間stdが持つ名前群は多く、コードを書く上で普通に使いそうな単語も含まれるため、バグを防ぐために実際には使われることは少ないらしい。
しかし、競プロの範囲内ではとりあえず気にしなくてもいいと思われる。
#include <bits/stdc++.h>
- 役割:標準ライブラリを一括インクルード
いきなり公式の解説で#include <bits/stdc++.h>が登場して、今まで慣れ親しんでいたinclude文が無かったので困惑したが、「標準ライブラリを一括インクルード」という意味らしい。
もちろん、std::coutやstd::cinのような標準入出力を使うために<iostream>をインクルードしたり、std::setを使う場合は別途で<set>をインクルードしたり、、、と使いたい機能に応じてインクルードしていくスタイルでも全く問題ないが、いちいちインクルード文を書くのは大変だよね、ということで#include <bits/stdc++.h>を使う。
例えば今まで
#include <iostream>
#include <algorithm>
...
とincludeを羅列していたものを
#include <bits/stdc++.h>
の一行で済ませられるようになる。
なお、コンパイラにgccを使っていないと使えないので注意。例えばMacではデフォルトコンパイラはclangという別のもの*なので、自分でコンパイラにgccを使うようセットアップしなければいけない。
*Macのデフォルトコンパイラについて
「Macのデフォルトコンパイラはclang」とは言ったものの、Macのデフォルトコンパイラの名前はgccらしい。しかし、中身はclangという紛らわしい仕様になっている様子。
#define rep(i,n) for (int i=0; i<(n); i++)
- 役割:for文をrep(i,n)でだけで書けるようにする
#defineなんて聞いたことがなかったので最初はとても難しく感じたが、これは単にfor文を短く省略して書けるようにするためのものらしい。
#define マクロ名 定数や式
と書くことでマクロ名で指定した部分を定数や式にコンピュータが置き換えて解釈してくれるようになる(マクロ処理)。
つまり、
#define rep(i,n) for (int i=0; i<(n); i++)
は「rep(i,n)と書いてあったらfor (int i=0; i<(n); i++)」に読み替えてね」とコンピュータに指示するような形である。以下、2つの文は全く同じ意味になる。
#include <bits/stdc++.h>
using namespace std;
int main(){
for(int i=0; i<5; i++){
cout << i << endl;
}
}
#include <bits/stdc++.h>
#define rep(i, n) for (int i=0; i<(n); i++)
using namespace std;
int main(){
rep(i,5){
cout << i << endl;
}
}
// いずれも出力は、
// 0
// 1
// 2
// 3
// 4
参考記事
Discussion