C++のコードの書き方
概要
競技プログラミングで C++ を使うときの、基本的なコードの書き方。
コメントについてもここで解説する。
コード例
基本の枠
以下は、C++ で「何もしない」を実行するコード。
#include <bits/stdc++.h>
using namespace std;
int main() {
// ここに、コンピューターにやってほしいことを書く
return 0;
}
何が書いてあるかを $1$ 行ずつ解説する。
#include <bits/stdc++.h>
まず、1行目のこれは「機能集、全部使うからよろしく!」という感じの文。
冒頭に毎回書く必要があるが、覚えなくてもコピペでよい。
C++ では、よく使う機能集みたいなものが存在する。
しかし、それらを使うには、「機能集の $3$ 巻と $7$ 巻使うからよろしく!」みたいに伝えなければならない。
もちろん、使いもしないものを無駄に読み込ませたら、仕事で書いたコードであれば怒られるだろう。
が、競技プログラミングはコードが動けば勝ちである。
豪快に「機能集、全部使うからよろしく!」をやってしまって何も問題ないし、誰にも怒られない。
using namespace std;
次に、$2$ 行目のこれは、「機能の名前を略して書くからよろしく!」という感じの文。
冒頭に毎回書く必要があるが、覚えなくてもコピペでよい。
C++ のいろんな機能名は、std::vector とか std::sort() のように、名前が長めである。
これは言ってみれば 苗字::名前 みたいな形で書いているようなもの。
だが、C++ 界の苗字は std:: が大多数。
そこで、「苗字書いてなかったら std:: かもしれないと思ってね」をやっているのがこの文。
稀にこれが意図しない問題を引き起こす可能性があるので、仕事で書いたコードであれば怒られるだろう。
が、競技プログラミングはコードが動けば勝ちである。
豪快に「std:: は略して書くからよろしく!」をやってしまって何も問題ないし、誰にも怒られない。
int main() {
}
$4$ 行目と $10$ 行目のこれは、main 関数の枠。
int main() { と } は毎回書く必要があるが、覚えなくてもコピペでよい。
main 関数は、言ってみれば main という名前のコンピューターへの指示書である。
C++ のコードは、まず main という名前の指示書を探して { } 間の内容を実行することになっている。
つまり、与えられた問題を解くためのプログラムは、基本的にこの間に書くと思っておいてよい。
// ここに、コンピューターにやってほしいことを書く
$6$ 行目のこれは、コメント。
スラッシュを $2$ つ書き並べたら、その行の残りは人間用のメモ書きであり、コンピューターは無視する。
詳しくは後述。
return 0;
最後に、$8$ 行目のこれは、終了報告。
main 関数を終える } の直前に書いておき、「無事に終わりました!」とコンピューターに知らせる。
覚えなくてもコピペでよく、なんなら書き忘れてもちゃんと動作する。
命令の記述ルール
言ってみれば、原稿用紙の使い方のルール。
ここでは $3$ つ紹介する。
まず、$1$ つ $1$ つの命令の終わりには、必ずセミコロン ; をつけること。
これは日本語で言う句点 。 のようなもの。
日本語ならうっかり句点を忘れても人間は読んでくれるが、プログラムではそうはいかない。
むしろ、プログラムに勝手に推測で変な動きをされても困るので、ちゃんと「; ないよ」とエラーする。
詳しくは「エラー」のページ参照。
次に、インデントを整えること。
波括弧の開き括弧 { と閉じ括弧 } は、非常に離れた位置に書くことが多い。
すると、今、どの { と、どの } の間にいるのかよくわからなくなってくる。
そこで、以下のように記述する。
(命令の内容に対して意味はないので、波括弧の位置と、行の先頭位置だけに注目)
int main() {
int n, m;
cin >> n >> m;
int a = 0;
int b = 0;
for (int i=0; i<n; i++) {
a += i;
for (int j=0; j<m; j++) {
b += i*j;
}
}
cout << a << " " << b << endl;
return 0;
}
このコードにあるように、{ が出てきたら、その場で改行する。
そして、次の行からは半角スペース $2$ つ分先頭を下げて書き始める。
その中でまた { が出てきたら、さらに $2$ つ下げる。
($4$ つ下げるという人、$8$ つ下げるという人もいる)
そして、} が出てきたら、その直前で改行し、その行から半角スペースの数を $2$ つ減らす。
こうすると、どの { を閉じているのがどの } なのかわかりやすくなる。
$3$ つめに、記号の前後には適度に半角スペースを入れる。
例えば、以下に、同じ内容の文を $4$ 回書いてある。
どれが見やすいかは人によるだろうが、一番上が見やすいという人はあまりいないだろう。
if(a==0)b=c+d;
if (a==0) b = c+d;
if (a == 0) b = c + d;
if ( a == 0 ) b = c + d ;
どの記号の前後に半角スペースを入れるかは、そのコードを書くのに参加する全員で決めて統一する。
競技プログラミングでは自分 $1$ 人で全部書くので、自分の好きに決めてよい。
未来の自分が困らないように、自分で決めたルールには自分でちゃんと従うこと。
余談だが、このページを作っている人は、わりと独特なルールを採用している。
コード例が、普通の人には読みにくいかもしれない。
コメントの書き方
// を書くと、その行のそこより右が全部コメントになる。
コメントは実行時には無視されるため、メモを書くことができる。
int x; // x に入力を受け取る
cin >> x;
また、/* と */ で囲むと、その間が全部コメントになる。
/*
この間に
書いた内容が
全部コメントになる
*/
使い方の応用
コメントをメモとして使う
プログラムを書くというよりは、そのための補助に使うもの。
難易度問わず利用する。
短時間のコンテストでは、コメントを書きすぎると時間ロスが大きい。
しかし、後で提出前に見直したいところなどはメモに残しておきたい。
また、WA が出た場合に真っ先に疑いたいところなども短くメモしておくと助かることもある。
長時間のヒューリスティック系コンテストでは、各変数の意味やロジックをコメントで残しておきたい。
「明日の自分は他人と思え」。
また、解説コードなどでは、コード例にコメントが書き足してあることが多い。
他人の解説などを読むときに混乱しないよう、実力問わず正しい知識を身に着けておきたい。
コードをまとめて有効化・無効化する
切り替えたいところの前後に以下のように書く。
この状態では、間のコードは有効。
//*
いろいろ(有効)
//*/
最初のスラッシュを $1$ つ消すと、その間をまとめて無効化できる。
/*
いろいろ(無効)
//*/
もちろん、スラッシュを $1$ つ付け足せばまた有効化できる。
2種類のコードを切り替える
切り替えたいところの前後に以下のように書く。
この状態では A の方が有効。
//*
いろいろA(有効)
/*/
いろいろB(無効)
//*/
最初のスラッシュを $1$ つ消すと、A を無効化して B を有効化できる。
/*
いろいろA(無効)
/*/
いろいろB(有効)
//*/
もちろん、スラッシュを $1$ つ付け足せばまた A の方を有効化できる。
VSCodeでの操作
VSCode でコードを書いている場合、「範囲選択して Ctrl+/」が便利。
その範囲全てをコメント化したり、逆にそれを解除したりできる。
注意点
無効化したのを忘れてそのまま提出しないようにする
有効化・無効化を活用する場合、有効無効の設定が意図通りになっているかを提出前に確認すること。
全角文字をコード部分に混ぜないようにする
日本語の文章はコメントの中なら書ける。
一方で、コード部分に全角スペースや全角記号が混ざると、コンパイルエラーの原因になることがある。
コメントを書いた後、半角に戻し忘れたままスペースを書くと大変なことになるので注意。
/*……*/ はネストできない
/* コメント1の途中に /*コメント2*/ を挟む */
うっかり上のように書くと、1つ目の /* から1つ目の */ までがコメント範囲と判定されてしまう。
そして、後ろの を挟む */ 部分がコメント扱いされず、エラーになる。
こういう記述をしないように注意すること。
関連知識
入出力
cin や cout の詳しい使い方は、入出力で扱う。
エラー
コードの書き方を間違えると、コンパイルエラーや実行時エラーになることがある。
エラーが出た場合は、エラーメッセージを読んで原因を探す。