前回の復習
算術演算, 代入演算, 関係演算と追ってきた. 論理演算, ビット演算, その他と進んで次回から制御構文にいきたい
§3 演算子(続き)
3.4 論理演算子
- 論理積...&& AND
- 論理和...|| OR
- 排他的論理和... ^ XOR
- 否定... ! NOT
という物たち. 集合論の本で一番最初の章に出てくる論理演算.
3.4.1 ショートカット演算
論理演算の特徴は, 左オペランドの評価だけで結果が分かる場合, 右オペランドは評価されない
var num = 1;
num==10 && num2==10 // 左辺だけでfalseが確定されるため右辺は評価すらされない
num==1 || num2==10 // 左辺だけでtrueが確定できるので右辺は(ry
// use case
if (str != null && str.StartWith("http://")
{
Console.WriteLine("asdf");
}
上のケースでは本来, strがnullだった場合でメソッドを呼ぶとエラーが出るけれど, その場合は左辺のみの評価でショートカットが発生するので問題なく動作する.
3.5 ビット演算子
operater | abs | ex. |
---|---|---|
& | 論理積, 両辺に双方にセットされてるビットをセット | 10&1 -> 1010&0001 -> 0000 -> 0 |
| | 論理和. 両辺のいずれかにセットされてるビットをセット | 10|1 -> 1010|0001 -> 1011 -> 11 |
^ | 排他的論理和. 両辺のいずれかでセットされており, 双方にはセットされてないビットをセット | 10^1 -> 1010^0001 -> 1011 -> 11 |
~ | 否定. ビットを反転 | ~10^ -> ~1010 -> 0101 -> -11 |
<< | ビットを左にシフト | 10 << 1 -> 1010<<1 -> 10110 -> 20 |
>> | ビットを右にシフト | 10 >>1 -> 1010 >> 1 -> 0101 -> 3 |
正直ビット演算子あまりよくわかってないのでちゃんと勉強する.
ビット演算子は大きく分けて, ビットの論理演算子とシフト演算子の二種に分けられるのだとか.
3.5.1 ビット論理演算子
二進数に直した数字を桁ごとに論理演算していくという物だった.
// 論理演算子
5&3を考える.
5(10) = 0101(2)
3(10) = 0011(2)
この時,
0101
&0011
-----
0001
となる. (桁ごとに0=false, 1=trueとみなしたANDを考える)
0001(2) = 1(10)より, 5&3 -> 1
// 否定演算子
5(10)の否定を考える
5(10) = 0101(2)
この時,
~0101
-----
1010
ただし, 1010(2) = 10(10)より, 演算の答えは10とやりたいのはわかるが, それは間違え.
否定の演算子は, 正負を決める数値ビットの一番最初も同時に反転する.
符号が負の場合の数値の計算方法は, ビットを反転させて1を加えたものが絶対値になる...という物のため
1010 -> 0101 + 1 -> 0110 -> 6 より, ~0101 -> -6(10)
3.5.2ビットシフト演算子
左シフト<<, 右シフト共に新しい桁を左/右に付け加えるものだった
// シフト演算子
10<<2を考える
10(10) = 1010(2)より,
1010 << 2 = 1010"00"
よって, 101000(2) = 40(10)のため, 10<<2 -> 40
右シフトも同じだけれど, 右シフトで加えたビットの値が問題.
数値ビットの最上位は符号を表すため, 最上位の値を残すか残さないか(符号を維持するか)の話になる.
残すのを算術シフト, 残さないのを論理シフトといい, 符号有の型か符号無の型によってどちらのシフトが選択されるかが変わる
3.6 その他の演算子
3.6.1 sizeof演算子
値型のサイズをバイト単位で取得する.
基本的にstaticにサイズが決まっている数値型のみしかこのメソッドは使えないが, unsafeモードを利用することで, 三法型を含まない構造体とポインターの賤母求められるとか.
sizeof(int) // 4
sizeof(decimal) //16
unsafe
{
sizeof(MyStruct)
}
unsafe使うには, unsafeブロックでくくったうえで, プロジェクトの設定をunsafeにする必要があるらしい.
3.6.2 nameof演算子
変数名のようなラベルとして使われている識別子を文字列として取得する
int data = 1;
nameof(data) // "data"がゲットできる
例外処理で使えるね, みたいな話が書いてあった.
3.7 演算子の優先順位と結合測
優先順位
優先順位があるよ.
kwsk
結合測
- 代入演算子以外の二項演算子は左結合
- 代入演算子と条件演算子は右結合
要するに, 右から評価されるかと左から評価されるかによって, 結合測()の利用は変わるよという話
思ったより残って多分が短かった.
次回制御構文