C言語/制御文

「明日、晴れたら、畑を耕そう。雨が降ったら、本を読もう。」のように、何かの条件によって処理が分かれることを条件分岐といいます。
C言語では条件分岐の為に、選択文が用意されています。
選択文( Selection statements ) は、制御式の値に応じて、一連の文の中から選択します 。 選択文は、そのスコープが周囲のブロックのスコープの厳密なサブセットであるブロックです。 関連するサブステートメントもまた、選択ステートメントのスコープの厳密なサブセットをスコープとするブロックです。
if文( if statement )は、最も単純な選択文です。
たとえば、プログラムでは「もし変数aが4だったら、変数gには15を代入しなさい」は、
と記述します。
と書かれた場合、もしaが 4 なら条件式の値は 1,a が4でなければ0です。 if 文は条件式が 0 でなければ、続く文を実行し、0 であれば実行しません。
このように、if文の条件式(上記のプログラムの場合は a==4)が満たされるときには中カッコ{}の内容が実行されます。
なお、条件式を書くときの等号は、==になります。条件式における等号は、=ではありません(C言語では、ひとつだけのイコール記号=は代入演算子です。)。
もし、条件式を変更すると、・・・
if文の外の文は実行されますが、if文の内側は実行されません。
if文でよくある間違いの1つに、 ==演算子の代わりに=演算子を誤って用いることがあります。 =演算子は左辺に右辺を代入した後その値を返すため、右辺が0の場合は偽となり、右辺が0以外の場合は真となります。 コンパイルエラーとはなりませんが、予期しない結果を引き起こします。
上の例では、式「i=0」の評価結果はiの値によらず偽となってprintf関数の文は常に実行されません。
if文でよくある間違いの1つに、if文の後に誤った;を付加することがあります。
上の例では、if文の式が真の時に実行される文がなく、printf関数の文は常に実行されます。
if文には次の2通りの形式があります。
どちらの形式でも、文1は、式の比較が0に等しくない場合に実行されます。 if-else形式では、式の比較値が0に等しい場合、文2が実行されます。
if文もまた文であるため、上の2つの形式を組み合わせて次のように連続して記述することもできます。
elseは、構文で許可されている場合、字句的に最も近い先行詞と関連付けられます。
if文に限りませんが、文はブロック(複合文; Compound statement )であってもかまいません。
Visual C/C++ では、scanf が「非推奨とマークされている関数」にあたり、設定によってはビルドに失敗します。⇒ コンパイラの警告 (レベル 3) C4996
これを回避するには、ソースコードに #pragma warning(disable:4996) を補う方法もありますが、 ここでは scanfの境界検査インターフェース版のscanf_sを使った実装を紹介します(scanf_sの3つめの引数 1は、記憶するデータの個数で、第1引数がスカラオブジェクトを指している場合、それは1要素の配列であるとみなされます。なので第3引数の値は 1 です。)
scanf_s の3つ目の引数 1 は、記憶するデータの個数で、第1引数がスカラオブジェクトを指している場合、それは1要素の配列であるとみなされます。
if文の中にif文を入れることを、ネストまたは入れ子という。
なお、上の入れ子のifの例は &&演算子 を用いて、次のように簡潔に書き換えることができます。

C言語のif文で、ある文字列変数が、指定する文字列に等しいかどうかを判定するには、== ではなく、strcmpを使う。 strcmpを使うために #include <string.h> で string.h をインクルードします。 strcmp 関数は文字列どうしを比較して、一致したときに(1ではなく)0を返す標準ライブラリ関数です。

switch文とbreak 文とを使って、複数個の「場合」のある場合分けができます。
たとえば
(以下略)
のような場合に、switch文とbreak 文で、場合分けをできます。
コードはイメージ的に言うと、
(イメージ)
(以下略)
のような記法になります。
まず、実行したい文の前に、それぞれcase文でラベルをつけます。
switch文に遭遇したときに、どのcaseに移動するかを決めます。
C言語の仕組みとして、もしbreakがないとそのまま次の文を実行します。
つまり、
switch {
(以下略)
というコードなら、もしa=2なら、実行されるのは、文m2だけでなく、さらに文m3や文m4も実行してしまいます。
このような仕組み(つまりbreak 文がないかぎり、次の関数を実行してしまう)のことをフォールスルー( fall through ) と呼びます。
switch文とは、選択文の内の1つであり、整数式(制御式)の値に従って、指定するいくつかの文からいずれかを実行するかどうか選択します。 switch文には、制御式と、ブロック(スイッチ本体)の中に、任意の個数のcaseラベルと、高々1つのdefaultラベルが含まれます。 switch文は、制御式の値と等しい整数定数式の値を持つcaseラベルへ制御を移します。 等しい値を持つcaseラベルがなければ、defaultラベルへ制御を移します。 defaultラベルもなければ、ブロックの次の文に制御を移します。
break 文はswitchブロックの次の文に制御を移します。 同一のswitch文のブロックの中に、同一の整数定数式の値を持つcaseラベルがあってはなりません。
switch文の記述は次のようになっています。
繰返し文( iteration statement ; より一般的には反復文)は、制御式( controlling expression )の0との比較が一致するまで、ループ本体( loop body )と呼ばれる文を繰返し実行します。 繰返し文はブロックで、そのスコープは、そのブロックを囲むブロックのスコープの狭義の部分集合( strict subset )です。 ループ本体もまた、繰返し文のスコープの狭義の部分集合をスコープとするブロックです。 繰返し文は、その制御式が定数式ではなく、本体、制御式、(for文の場合)式-3で以下の操作が行われていない場合、実装上は終了するとみなすことができます。
構文
※最後のfor文の構文は ; が不足しているように見えますが、declaration(宣言)は文で末尾に ; を含むので不足してはいません。
while文( while statment )では、制御式の評価は、ループ本体の各実行前に行われます。

do文( do statement )では、制御式の評価は、ループ本体の各実行後に行われます。
for文( for statement )
は次のように動作します。
先の「for文の使用例」の変数 i のスコープは
for文の中にfor文を入れることを、ネストまたは入れ子という。
無限ループとは、文の実行が無限に繰り返されることです。
いずれのコードも、継続条件は常に非ゼロの整数(あるいは、非ゼロの整数とみなされます)ので文の実行を無限に繰返します。 無限ループを用いる場合、後述する break br文を用いるなどして適切にループから脱出できるようにする必要があります。
このプログラムを終了するには、y(Yの小文字)を入力してエンターキーを押します。入力する「y」は直接入力モード(Windowsの場合は半角英数)にしてください。
なお、文字変数の中身を示す「'y'」のように、文字リテラルは ' (シングルクォーテーションマーク)で囲みます。文字列リテラルを囲む " (ダブルクォーテーションマーク)と間違えないうようにしましょう。
分岐文( jump statements )は、無条件に別の場所にジャンプします。
構文
goto文( goto statement )は、包含する関数内の、名前の付いたラベルを先頭に持つ文に無条件にジャンプします。 goto文の識別子は、包含する関数のどこかにあるラベルを指し示さなければなりません。 goto文は、可変的に変更された型を持つ識別子のスコープ外から、その識別子のスコープ内にジャンプしてはなりません
continue文( continue statement )は、それを囲む最小の反復文のループ継続部分、すなわち、ループ本体の終わりにジャンプする。
上の実行結果では、3の倍数の「3」と「6」と「9」と「12」が抜けています。
このように、continue 文は、そのループ内の以降の処理をスキップしつつも、カウントを1回ぶん、進めます。
break文( break statement)は、最小のswitch文または反復文を囲むものの実行を終了させます。 break文は、switch本体またはloop本体の中以外に現れてはいけません。
break文の記述は次のようになっています。
このように、for文の中にif文があり、if文のブロックの中にbreak;がある場合、一番内側のfor文の終わりに処理が移ります(ここでは、ラベル break_point の位置)。 for文が2つ以上ある場合、break 文で複数のfor文を一度に抜け出すことは不可能です。
return文( return statement )は、現在の関数の実行を終了し、呼び出し元に制御を返します 。 関数はいくつでもreturn文を持つことができます。 式を持つreturn文が実行されると、その式の値が関数呼び出し式の値として呼び出し元に返されます。式の型がその関数の戻り値の型と異なる場合、その値は関数の戻り値の型を持つオブジェクトに代入されたように変換されます。 式を持つreturn文は、戻り値の型がvoidである関数の中に現れてはなりません。式を伴わないreturn文は、戻り値の型がvoidである関数の中でのみ現れます。