006. 条件式を書いてみよう

過去のブログのアーカイブ
この記事は前身のブログのアーカイブを引き継いだものです. 画像が正しく表示できないなど,コンテンツの表示に問題がある恐れがあります.

プログラムは決められた動作をずらずらする一方的なものばかりではありません。使う人が操作し、その操作に応じて動作させるものがほとんどです。
○○な操作をされたら××をするといった条件に応じた動作を「条件分岐」と言います。

条件式を書こう

まずは条件分岐をさせるために必要な条件式を書いていきましょう。
条件式には様々なものがあります。一番使われるのは「○○と××が一緒なら」といったイコールの条件式ですね。
まずは基本的なものを覚えましょう。基本的に比較対象を左辺に、何と比較するのかを右辺に書きます。

記号(演算子) 意味
一緒である == 左辺と右辺が同じものならtrue
一緒ではない != 左辺と右辺が違うものならtrue
より大きい > 左の方が大きければtrue
より小さい < 左の方が小さければfalse
以上である >= 左の方が大きい又は同等ならtrue
以下である <= 左の方が小さい又は同等ならtrue

条件式で判定した結果はBoolean型(bool)で返されます。つまりtrueかfalseで返されるというわけです。
また、条件式も式の一種なので、記号を演算子とも言います。==演算子は+演算子の仲間みたいなものなのです。
では例を見てみましょう。

int a = 10;
int b = 20;
int c = 10;
bool b1 = a == b;
// b1 => false
bool b2 = a == c;
// b2 => true;

イコールだらけでごちゃごちゃしてますね;;
条件式の結果はbool型で返されると前述しました。つまり、結果はbool型の変数に格納することも可能なのです。

結果を否定する

trueとfalseをひっくり返す場合は、!を先頭につけるだけでOKです。といってもわかりづらいので例を見てみましょう。

int a = 10;
int b = 20;
bool result = a == b;
// result => false

まずは普通の条件式から。aとbの中身は違うので==で比較すれば当然、falseが返ってきます。
そしてflagという変数にresultとは反対の値を代入したい場合はこのように記述すればいいのです。

bool flag = !result;

このように!を先頭につけるだけでいいのです。
これはこのように応用することもできます。

bool flag = !(a == b);

このようにカッコの中に条件式を書き、カッコの左すぐ外側に!をつければ、結果をひっくり返して返すこともできます。

○○または××なら〜(AND条件)

二つの条件を組み合わせることもできます。双方の条件がともにtrueならtrueを返し、どちらかがfalseならfalseを返す条件です。
表にするとこんな感じ

条件2がtrue 条件2がfalse
条件1がtrue true false
条件1がfalse false false

この2つの条件を束ねるのは&&演算子です。
例を見てみましょう。

bool b1 = true;
bool b2 = false;
bool b3 = true;
bool b4 = false;
bool res1 = b1 && b2;
// res1 => false
bool res2 = b1 && b3;
// res2 => true
bool res3 = b2 && b4;
// res3 => false

この演算子は両方一緒なら〜ではありません。両方ともtrueならという演算子です。両方ともfalseで&&を使うとfalseが返ってきます。

○○または××なら〜(OR条件)

こちらの方はどちらかがtrueならtrueを返すという条件式です。
表にするとこんな感じ
 

条件2がtrue 条件2がfalse
条件1がtrue true true
条件1がfalse true false

どちらかがtrueならいいのです。両方ともがfalseの時だけ、falseを返します。
そして、こちらの演算子は||です。
例を見てみましょう。

bool b1 = true;
bool b2 = false;
bool b3 = true;
bool b4 = false;
bool res1 = b1 || b2;
// res1 => true
bool res2 = b1 || b3;
// res2 => true
bool res3 = b2 || b4;
// res3 => false

 応用編

ではもしも、b1がfalse, b2がfalse, b3がtrueならtrueを返す条件を組んでみましょう。

bool res = !b1 && !b2 && b3;

とこのようになりますね。
余談ですが、&&のグループと||のグループは分けると可読性が上がります。
例えば、b1がfalse, b2がtrue、ただしb3がfalseなら、無条件にtrueを出す条件式を書いてみましょう。

bool res = (!b1 && b2) || !b3;

このようになりますね。

 余談

なお、==や!=を使って比較する時には注意点があります。その双方が同じ型である必要があること。(互換性がある場合はまた別の話)
なのですが、参照型のオブジェクトを比較する際は、同じ型であろうと注意点があります。
まず値型と参照型の違いがわかっている前提で話を進めます。わからない場合はこちらの記事をどうぞ。
http://yryr.me/programming/csharp/beginner/object-model/dotnet-refarence-value-type-variable.html
参照型のオブジェクトの場合、パラメータ等で指定する時には、メモリのアドレスが渡されると言いました。
なので、双方のオブジェクトの内容が一緒であろうと、参照されているアドレスの番地が違えば==をしていしてもfalseとなってしまうのです。
例を見てみましょう。

public class A {
    public int Value = 0;
}
public void Main() {
    A a1 = new A(); // 仮に、メモリの#1000番地にデータが記録されてるとする
    A a2 = new A(); // 仮に、メモリの#2000番地にデータが記録されてるとする
    // a1.Value => 0
    // a2.Value => 0
    // とValueの中は双方今のところ同じです。
    // a1とa2はそれぞれアドレスの番地が違うので==で比較するとfalseになる
    bool result = a1 == a2;
    // result => false
}

このように、同じ内容のオブジェクトであれ、参照型のオブジェクト同士を比較してしまうと思ったような結果が出ません。
Equalsメソッドで比較するという選択肢もあるのですが…少し厄介なのでここでは割愛させていただきます。