演算子を理解しよう!

[C#] 演算子を理解しよう!

※ 当サイトは広告を含みます。

型と変数を学んだので演算ができるようになりました。という事で、ここではC#で利用できる演算子について理解しましょう。
この中でbit演算を使用するので、理解してない人はコンピュータサイエンスの講座を先に読んでください。

算術演算子

+, -, *, /, %

いわゆる四則演算です。簡単なので例を見て覚えましょう。

算術演算子

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 50;
      int y = 7;
      int z = -7;

      double d = 7D;

      Console.WriteLine(-x); // -を付けると符号が反転する
      Console.WriteLine(-z); //   〃
      Console.WriteLine();

      Console.WriteLine(x + y); // 足し算
      Console.WriteLine(x - y); // 引き算
      Console.WriteLine(x * y); // 掛け算
      Console.WriteLine(x / y); // 割り算
      Console.WriteLine();

      Console.WriteLine(x % y); // 割り算の余り
      Console.WriteLine(x % z); //   〃
      Console.WriteLine();

      Console.WriteLine(y / 3); // 整数型の場合は小数点以下は捨てられる
      Console.WriteLine(z / 3); //   〃
      Console.WriteLine();

      Console.WriteLine(d / 2.0); // 浮動小数点数値型なら小数点まで計算が可能
    }
  }
}
管理人

整数型に小数点は無いので消えます。

++, --

インクリメント演算子デクリメント演算子と呼びます。
さらにお互いに前置後置が存在するので全部で4つあります。

インクリメント / デクリメント演算子

この前置と後置が少し分かりづらいので、先にインクリメントとデクリメントの仕様を覚えましょう。
インクリメントとは+1する演算子で、デクリメントが-1する演算子です。

実際にはこうやって書きます。


x++; // インクリメント演算子の記述
x--; // デクリメント演算子の記述

結論として次の処理と同じになります。要は簡略化して記述できます。


x = x + 1; // インクリメント演算子と同じ
x = x - 1; // デクリメント演算子と同じ

そして前置と後置は++(--)を記述する位置を示します。
具体例を先に見せるとこんな感じです。値に対して演算子を前に書くか後ろに書くかです。


++x; // 前置インクリメント
x++; // 後置インクリメント

では、これの何が違うのでしょうか。この差が影響するのは演算結果を利用する場合です。

まずは次のサンプルコードを実行してみてください。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 10;
      int y = 10;

      // 前置
      Console.WriteLine(++x); // インクリメントしてから演算結果を返す
      Console.WriteLine(x);

      // 後置
      Console.WriteLine(y++); // 演算結果を返してからインクリメントする
      Console.WriteLine(y);
    }
  }
}

同じインクリメントでも前置と後置で出力される値が異なりますよね。
これはWriteLine()に値を渡す際、前置と後置でインクリメントするタイミングが違うからです。

結論を言うと演算結果を同時に利用したい場合に影響します。そうじゃない場合はどっちでもいいです。
実際のところ、この演算子はめちゃくちゃ使うんですが前置と後置を意識することは少ないです。

仮に先程のように途中の値を利用したいのであれば、記述を分けたほうが誤りの少ないコードになります。
絶対1行に書きたいとか余程の理由がないなら前置と後置は無視でいいです。

論理演算子

論理演算子はbool型かそれ以外で動作が異なります。
大雑把に説明するとbool型なら真偽値を求め、数値型ならbit演算をします。

(bool型) !, &, |, ^

順番にNOT, AND, OR, XORです。これも簡単なので例をみましょう。

論理演算子 (bool型)

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      bool b = true;

      // NOT
      Console.WriteLine(!b);
      Console.WriteLine();

      // AND
      Console.WriteLine(true & true);
      Console.WriteLine(true & false);
      Console.WriteLine(false & true);
      Console.WriteLine(false & false);
      Console.WriteLine();

      // OR
      Console.WriteLine(true | true);
      Console.WriteLine(true | false);
      Console.WriteLine(false | true);
      Console.WriteLine(false | false);
      Console.WriteLine();

      // XOR
      Console.WriteLine(true ^ true);
      Console.WriteLine(true ^ false);
      Console.WriteLine(false ^ true);
      Console.WriteLine(false ^ false);
      Console.WriteLine();
    }
  }
}
管理人

単にtrueを1、falseを0としたbit演算ですね。

(bool型) &&, ||

条件付き論理AND(OR)演算子と呼びます。演算結果は先程のANDとORと変わりません。
違いは短絡評価と呼ばれる機能が付いていて、左側から演算した結果で評価式が確定する場合、後半の演算がスキップされます。

条件付き論理演算子
りさ

言ってる意味が分かりません。

管理人

これにはANDとORの性質が関係するんだ。画像を含めて説明するね。

前提としてプログラムは複数の評価式を同時に演算できません。必ず左側から順番に演算します。
では、3つの値を演算する場合を例にANDとORを考えてみましょう。

短路評価 (AND)
短路評価 (OR)

もう画像に答えが書いてありますが、前半を演算した時点で後半の結果が確定してます。
つまりは後半にどんな演算をしても結果は同じ、だから演算をスキップできるのです。

プログラムの記述例は以下です。無理やり書いてるので見ずらいと思いますが我慢してください。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x1 = 10, x2 = 10;

      Console.WriteLine(true && true && x1++ > 0); // インクリメントされる
      Console.WriteLine(x1);
      Console.WriteLine();

      Console.WriteLine(true && false && x2++ > 0); // インクリメントされない (短絡評価でスキップ)
      Console.WriteLine(x2);
      Console.WriteLine();

      int y1 = 10, y2 = 10;

      Console.WriteLine(true || false || y1++ > 0); // インクリメントされない (短絡評価でスキップ)
      Console.WriteLine(y1);
      Console.WriteLine();

      Console.WriteLine(false || false || y2++ > 0); // インクリメントされる
      Console.WriteLine(y2);
      Console.WriteLine();
    }
  }
}
管理人

1番使うのはif文で条件式を書くときですね。

(数値型) ~, &, |, ^, <<, >>, >>>

順番にbit反転, AND, OR, XOR, 左シフト, 右シフト, 符号なし右シフトです。

論理演算子 (数値型)

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 0b00000000000000000000000010101010;
      int y = 0b00000000000000000000000000001111;
      int z = 0b00000000000000001111111111111111;

      Console.WriteLine($"{Convert.ToString(~z, 2), 32}"); // bit反転
      Console.WriteLine();

      Console.WriteLine($"{Convert.ToString(x & y, 2), 32}"); // AND
      Console.WriteLine($"{Convert.ToString(x | y, 2), 32}"); // OR
      Console.WriteLine($"{Convert.ToString(x ^ y, 2), 32}"); // XOR
      Console.WriteLine();

      Console.WriteLine($"{Convert.ToString(x << 2, 2), 32}"); // 左シフト
      Console.WriteLine($"{Convert.ToString(x >> 2, 2), 32}"); // 右シフト
      Console.WriteLine();

      int xx = -8;
      Console.WriteLine($"{Convert.ToString(xx, 2), 32}");       // 2進数で表示
      Console.WriteLine($"{Convert.ToString(xx >> 2, 2), 32}");  // 右シフト
      Console.WriteLine($"{Convert.ToString(xx >>> 2, 2), 32}"); // 符号なし右シフト
    }
  }
}
管理人

2進数で表示するために少し特殊な書き方をしてますが、関連する演算子以外は無視して構いません。
注意が必要なのは右シフトです。>>は演算する型が符号ありの場合は算術シフトになります。

りさ

マスターが使うなって言ってたやつだ。

管理人

よく覚えてるね。>>で論理シフトするためには符号なしの型を利用する必要があります。
これが恐ろしく使いづらく、そんな意見が100万件集まり>>>が誕生しました。

等値演算子

==, !=

2つを比較した結果をbool型で返す演算子です。==は2つが等しいかを確認して、!=はその逆です。

等値演算子

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 10;
      int y = 10;
      int z = 7;

      // == は等しい場合はtrue、それ以外はfalse
      Console.WriteLine(x == y);
      Console.WriteLine(x == z);

      // != は異なる場合はtrue、それ以外はfalse
      Console.WriteLine(x != y);
      Console.WriteLine(x != z);

      // 演算子だから代入も可能
      bool b = x == y;
      Console.WriteLine(b);
    }
  }
}

比較演算子

<, >, <=, >=

これも2つを比較した結果をbool型で返す演算子です。見ての通りで大なり小なりです。

比較演算子

namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 10;
      int y = 10;
      int z = 5;

      // 大なり、= を付けると以上を含む判定
      Console.WriteLine(x > y);
      Console.WriteLine(x >= y);

      // 小なり、= を付けると以下を含む判定
      Console.WriteLine(x < y);
      Console.WriteLine(x <= y);

      // 演算子だから代入も可能
      bool b = x > z;
      Console.WriteLine(b);
    }
  }
}

複合代入

一部の演算子で可能な省略形の記述方法です。

例えばこんな感じの式を


x = x + 10;

以下みたいに記述できます。


x += 10;

例を作ったのでサンプルコードで動作を確認してください。記述は違っても同じ結果が得られるはずです。
大抵の演算子はこの記述ができますが、できなかったら諦めてください。


namespace Sample
{
  internal class Program
  {
    static void Main(string[] args)
    {
      int x = 10;
      int y = 10;

      x = x + 5;
      y += 5;

      Console.WriteLine(x);
      Console.WriteLine(y);
    }
  }
}
管理人

普通にコード書いてると省略形しか使いません。

あとがき

この演算子は他のプログラミング言語でも同じです。違うとすれば対応してる有無くらい。
それもあって自分の得意な言語で覚えれば、全部覚えたのと同じですよ。

◆ C#に関する学習コンテンツ

この記事は参考になりましたか?

関連記事

コメント

この記事へのコメントはありません。