型と変数を学んだので演算ができるようになりました。という事で、ここではC#で利用できる演算子について理解しましょう。
この中でbit演算を使用するので、理解してない人はコンピュータサイエンスの講座を先に読んでください。
コンピュータにはbit単位、つまり0と1だけで演算するbit演算が存在します。それがどんな演算なのか、今回は実用例も交えて学習しましょう。ちなみにbit単位で演算すると言っても、実際にはbyte単位で処理されます。その場合は複数のbitを計算することになりますが、常に同じ桁同士をbit演算すると覚えれば大丈夫です。よく分からないけど分かりました。後に説明するANDとかORの時にこの話を思い出して欲しいな。論理演算とbitシフトbit演算は、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です。これも簡単なので例をみましょう。
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を考えてみましょう。
もう画像に答えが書いてありますが、前半を演算した時点で後半の結果が確定してます。
つまりは後半にどんな演算をしても結果は同じ、だから演算をスキップできるのです。
プログラムの記述例は以下です。無理やり書いてるので見ずらいと思いますが我慢してください。
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文で条件式を書くときですね。
ここではC#のif文について理解しましょう。これはプログラムの基本構造で説明した選択にあたる処理です。なお、プログラムの基本構造が分からない人は先に次の記事を読んでください。if statement (ステートメント)いわゆる条件分岐でif文と呼びます。つまりは何らかの条件に従って、いずれかの処理を実行する構文です。パターン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#に関する学習コンテンツ
この記事は参考になりましたか?
コメント