📝

【rep(i,n)】競プロの解説で最初わからなかった表記まとめ

2023/09/03に公開

少し前に競プロを始めた。競プロでは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

参考記事

https://qiita.com/hakatashi/items/f9d9abf05a002b5c4dc5
https://monozukuri-c.com/langc-include/
https://www.sejuku.net/blog/25927
https://programming.pc-note.net/cpp/namespace.html

GitHubで編集を提案

Discussion