if分岐
概要
変数の中身次第で特定のコードを実行したりしなかったりする。
あるいは、複数のコードのどれを実行するか選ぶ。
基本的な書き方
コードを実行したりしなかったりする
if (条件式) {
その場合に実行したいコード
}
実行したいコードが $1$ 行しかない場合は、以下でもよい。
if (条件式) その場合に実行したいコード
$2$ つのコードのどちらを実行するか選ぶ
if (条件式) {
その場合に実行したいコード
} else {
そうじゃない場合に実行したいコード
}
実行したいコードが $1$ 行しかない場合は、以下でもよい。
if (条件式) その場合に実行したいコード
else そうじゃない場合に実行したいコード
$3$ つ以上のコードのどれを実行するか選ぶ
if (条件1) {
条件1を満たす場合に実行したいコード
} else if (条件2) {
条件1を満たさないが条件2を満たす場合に実行したいコード
} else {
条件1も条件2も満たさない場合に実行したいコード
}
else if のところを増やしていけば、$4$ 択や $5$ 択、それ以上も可能。
実行したいコードが $1$ 行しかない場合については同様。
条件式
等しい a==b
整数型の場合は、数値が等しければ true。
double 型の場合は、数値が等しければ true ……だが、あまり信用ならない。
詳細は「double型」の記事参照。
char 型の場合は、同じ文字であれば true。
string 型の場合は、完全に同じ文字列であれば true。
pair、tuple、vector の場合は、個数と順番まで含め完全に同じ内容であれば true。
set の場合は、完全に同じ内容であれば true。
等しくない a!=b
a==b が false になるなら true。
より小さい a<b
整数型の場合は、数値が a の方が小さければ true。
double 型の場合は、数値が a の方が小さければ true ……だが、あまり信用ならない。
詳細は「double型」の記事参照。
char 型の場合は、a の方がASCIIコードが小さければ true。
string 型の場合は、前から順に見て最初に異なる文字のところを探す。
そこのASCIIコードが a の方が小さければ、または a の方だけもう文字が尽きていれば true。
pair、tuple、vector の場合も前から順に見て最初に内容の異なるところを探す。
そこが a の方が小さければ、または a の方だけもう内容が尽きていれば true。
以下 a<=b
a<b か a==b が成り立てば true。
より大きい a>b
b<a が成り立てば true。
以上 a>=b
a>b か a==b が成り立てば true。
よく使う処理
a と b の間の数という判定
真面目に書くと、
if ((a<x&&x<b)||(b<x&&x<a))
とすることになり、やや煩雑。
実はこれ、以下のように書ける。
ただし桁あふれに注意。
if ((x-a)*(x-b)<0)
あるいは、以下のようにも書ける。
if (min(a,b)<x&&x<max(a,b))
そうじゃなければ、という条件(B問題相当)
if (!条件) {
そうじゃない場合に実行したいコード
}
このように書くことで、条件が成り立たなければ実行、を書くことができる。
単純な条件なら逆の意味の記号があるので必要ない。
しかし、例えば「queue が空じゃなかったら」という条件を、以下のように書くなら必要。
if (!que.empty())
$2$ つの条件をどちらもチェックしたい場合
$2$ つの条件が両方成り立つなら実行、という場合は以下のように書く。
if (条件1&&条件2)
$2$ つの条件が片方だけでも成り立つなら実行、という場合は以下のように書く。
if (条件1||条件2)
詳細は「bool型」の記事参照。
$3$ つや $4$ つでも、個数が定まっているなら同様に書ける。
また、このとき、条件1の結果によっては、条件2がチェックされない。
つまり、以下において条件1が false だった場合、条件2は確認せずに全体を false として処理する。
if (条件1&&条件2)
これを利用すると、条件2での範囲外アクセスのエラーを防ぐことができる。
例えば、a という vector に対し以下のように書くことができる。
if (a.size()>10&&a.at(10)>0)
「$10$ 番目が正の数なら true、正の数でないかそもそも存在しなければ false」となる。
例えば a の長さが $5$ であった場合、$1$ つ目の条件で false になるため $2$ つ目の判定が行われない。
結果、範囲外アクセスが発生しない。
同様に、以下において条件1が true だった場合、条件2は確認せずに全体を true として処理する。
これもやはり条件2でのエラーを防ぐことができる。
if (条件1||条件2)
多数(不定個)の条件を全てチェックしたい場合
bool 型変数を用意して(または類する何らかの変数を用意して)forループで確認する。
詳細は「bool型」の記事参照。
注意点
等しいと書くつもりで誤って = と書かないこと
もし以下のように書いた場合、意図と違う挙動をする。
if (x=0)
これは、条件部分に bool 型以外が入っていた場合でも、それぞれ true 扱いや false 扱いされるため。
例えば、上のコードだと、まず $x$ に $0$ を代入し、代入した値 $0$ が判定に使われて false 扱いされる。
結果、元々の $x$ の中身が $0$ であっても false になる。
バグの発見が非常にしにくいので注意。
謎の WA が出た場合はとりあえずif文の中身を一通り確認してみる、くらいに警戒が必要。
関連知識
bool型
if文の条件式は、最終的に true か false として判定される。
!、&&、|| など bool 型の論理演算も扱う必要がある場合がある。
whileループ
if分岐と似ているが、条件に合う限り何度でも繰り返して実行する。