初学者が独習C#をざっくり読んでみる 第5回 -制御構文-

## ぜんかいまでのあらすじ
データ型, 演算子を経てついに制御構文.
550ページある本のまっだ100ページをやった

## §4 制御構文
構造化プログラミングのための三つのプログラム

- 順次: 記述の順に処理を実行
- 選択: 条件に応じて処理を分岐
- 反復: 特定の処理を繰り返し実行

これらをやる

### 4.1 条件分岐
#### 4.1.1 if文 単純分岐
言わずもがな. `if (statement) {...}`で書かれて, stateがTrueの時のみ実行
注意点として以下のポイントが書いてあった

- statementの部分にassignmentつかわないようにね. ==だよ
- boolを格納してる変数, 返す関数は, XX==T/F, とかやらん方がみやすいよ
- ドモルガンうまく使って, 否定が入る場合は見やすくしよう

#### 4.1.2 多岐分岐
`else`, `else if`が使えるよ.
言語によっては, elseifとつながってたり, elifになってたりするからたまに間違える

おなじみ注意点として, matchするstatementが出た時, そのstatementに続くブロックのみが実行されて, 他はスキップされるよとのこと

#### 4.1.3 入れ子構造
入れ子構造を作れるよ. ネストできるよ.
ただし, ネストすると可読性減るよ.

可読性とかコーディングルールにかんする色々な指標としてVisualStudioことVSではコードメトリックス機能があるからつかってね, とも書いてあった. [これは](https://docs.microsoft.com/ja-jp/visualstudio/code-quality/code-metrics-values?view=vs-2017)とても興味深い. 

#### 4.1.4 {}は省略可能
一行ifの場合はブロックを省略できるらしい.
ただ, 範囲が不明瞭になるからおすすめはしないとか.



``` c#:if文まとめ
// 一般化した書き方
if(statement)
{
    hogehoge
}
else if(statement)
{
    piyopiyo
}
else
{
    honyamorake
}

// nest
if(state)
{
    if(state)
    {
        hogehoge
    }
    piyopiyo
}

//oneline
if(state)
    hogehoge
```

#### 4.1.5 switch命令
`else if`の連続よりかはswitchを使おうと書いてある.
問題は`==`か`===`か, なのだが(PHP脳)C#はそもそも型判定なしの判定方法がObject.Equalだけなので大丈夫ぽい
また, 型の判定をできるらしい.

```C#
// template
switch (val)
{
case val:
    hogehoge
    break; //break無しのfall through文は"処理が存在しないcase文"が続かない限り文原則許されない.
case val1: //大丈夫な例: val1, 2, 3の時はhonyaが実行
case val2:
case val3:
    honya
default:
    piyopiyo
}

// 型判定
object = -123

switch(obj)
{
    case int i when i>= 0: // when obj is int & non negative num.
        Console.WriteLine(i)
        break;
    case int i:
        Console.WriteLine(Math.Abs(i));
    case string str: // when obj is string
        Console.WriteLine(str[0]);
        break;
}

### 4.2 繰り返し処理
- while
- do while
- for 
- for each

の四つ

#### 4.2.1 while / do while
stateがtrueである限りloopを続ける文

``` c#: while / do while
// while template
while(statement)
{
    hogehoge
}

// do while template
do
{
    piyopiyo
} while(statement);

// ex
int i = 6;
while(i<6)
{
    Console.WriteLine($"number:{i}");
}
```

do whileが個人的に可読性低く見える.
条件を後置判定にする意味はあるのか...?
一応内部的には, 最低でも一回実行するのが"do while", しないのがwhileらしい

#### 4.2.3 for文
pythonのノリのforはfor each, こちらはJSとかcのノリのforみたいだ

```C#:for
// template
for(initializer; condition; iterator)
{
    hogehoge
}

// ex.
for(int i=6; i<6; i++)
{
    Console.Writeline($"number:{i});
}
```

loopに必要不可欠な機能を宣言のタイミングで書くのがfor

- initializer: ループで使う変数(ループ変数)を宣言. スコープの問題上, forで使うカウンターはここで宣言するのがよい
- condition: 継続するための条件
- iterator: ループ処理一回ごとに実行されるカウンター変数増減の処理

注意点として以下が挙げられていた

- カウンターのループ変数に浮動小数点は使わない(ループの回数は離散値だし, 何より0.1を表現できないから危険)
- ブロックの中でループ変数への副作用を起こすようなコードを書かない
- ループ全般に言えることだけど, 処理部分でむやみにオブジェクトを生成しまくらない(ガベージコレクト頻発で死ぬ
- ループ全般に言えることだけど, 処理部分でむやみに例外処理をしなくらない(オーバーヘッドがけっこうかかる

##### iteratorの部分には複数の文や式を指定できる
コードゴルフ技術な気もするけれど...

`for(int i=0; i<6; Console.WriteLine("hogehoge"); i++) ;`

と書くことで一行forが実装できるみたい(セミコロンをお忘れなく)

また,

```c#
for(int i=0, j=0; i<6; i++, j++)
{
     i*j
}
```

なんてのも可能のよう.
julia感を感じた.

#### 4.2.4 foreach
pythonとかでのfor.
指定された配列やコレクションの要素を取り出して順に処理するmap関数のような働きをする.

```c#:foreach
//template
for(dtype variable in array/collection)
{
    hogehoge
}

// ex
var data = new[]{ 1, 2, 3}
foreach(var e in data)
{
    Console.WritLine(e);
}
```

array/collectionようの要素が順にvariableでおかれた変数に格納され, hogehoge処理を実行する文

##### コマンドライン引数の取得
コマンドライン引数はMain関数の引数argsに格納されるので, foreachを使って取り出すことが可能になる.

```c#:get_args
foreach (var value in args)
{
    Console.WritLine(value);
}
```

なるほど.

---

長くなるまでここまで.
次回にbreak; continue;をやり, goto:, プリプロセッサディレクティブをやってからようやく標準ライブラリに