if文制御
プログラムを分岐させる
これまでは、main()関数の中を上から下へ誠実にプログラムは動いてきました
入力を学んだことによって、さらに動的な結果を得られることもできるようになりました
ここではさらに、値を判定してプログラマの意図に従ってプログラムを動かします
すなわちプログラムを分岐させます
プログラムを分岐させるもっとも基本的な制御文はifステートメントです
ifは …が…であれば…する というプログラム制御を可能にします
…が…であれば という部分は条件式(ブール式、条件文などとも言います)という式を使います
if (条件式) ステートメント;
条件式は算術演算子ではなく等価、不等価、関係演算子を使います
以下は条件式で使われる演算子です
演算子 | 内容
|
---|
a < b | aがbより小さければ
|
a <= b | aがbと同じか小さければ
|
a > b | aがbより大きければ
|
a >= b | aがbと同じか大きければ
|
a == b | aとbが等しければ
|
a != b | aとbが等しくなければ
|
((a) && (b)) | 式aと式bが真ならば
|
((a) || (b)) | 式aまたは式bが真ならば
|
!a | aが真なら偽、偽なら真
|
等しければ、という条件は = ではなく == とイコールがふたつ続くことに注意してください
= は算術演算子の「代入」なので意味が違います。条件式で「等しければ」という意味の演算子は == です
条件式は、内容が指定された条件に合わなければ0を、合えば0以外を(普通1)返します
これは制御文を学ぶのに非常に大切なことなので、ここで条件式の仕組をしっかりと学びましょう
#include <stdio.h>
int main()
{
int ans;
int get_int;
printf("値を入力してください\n");
scanf("%d",&get_int);
ans = (get_int == 10); /*条件式の判定を変数ansに代入*/
printf("ans = %d" , ans);
return 0;
}
条件式で使われている演算子は == です。つまり「入力された値 get_int が10に等しければ」という意味です
もしget_intが 10以外 ならば、条件式はansに0を返します。この 0 のことを偽(false)と言います
また、get_intが 10に等しい ならば、条件式はansに0以外(普通1)を返します。この 1 のことを真(true)と言います
このプログラムで入力された値が10ならば ans に1が、そうでなければ ans に0が代入されることを確認してください
ifステートメントは「真か偽か」を判断材料にし、与えられた値が真ならば指定されたステートメントを実行します
つまり、ifステートメントに渡された値が0ならば指定ステートメントを実行せずに次の命令に進みます
逆にifステートメントに渡された値が0以外ならば指定ステートメントを実行して次の命令に進みます
ということは、上の条件式の使い方さえわかればif文を使えるようになりますね
#include <stdio.h>
int main()
{
int ans;
ans = (10 == 10);
if (ans) printf("同級生if... 美沙ちゃん良かったです");
return 0;
}
条件式が 10 == 10 なので、ansには1(真)が入ります
if文では変数 ans を参照しています。ansは1(真)なのでifステートメントはその後の指定ステートメントを実行します
試しに条件式を 10 != 10 に変えてみてください。これは10が10でなければという意味です
この条件は一致しないので ans には0(偽)が入ります
結果、ifステートメントは偽の場合指定ステートメントを実行することなく次の命令に移行します
#include <stdio.h>
int main()
{
int ans;
ans = (10 != 10);
if (ans) printf("同級生if... 美沙ちゃん良かったです");
return 0;
}
このプログラムでは、ifステートメントが偽を参照するのでprintf()関数は実行されません
つまり、何もすることなく終わるプログラムになります
ここまでの説明で、ifステートメントと条件式の仕組は理解できたと思います
ifの後の()には、冒頭で説明していますが条件式を直接指定することができます
おそらく実際に目にするifステートメントは条件式を直接指定しているでしょう
これまでのように、一度条件式の結果をint型変数に格納していては非常に面倒です
(なぜそんなことをやったかというと、ifステートメントと条件式の本質的な仕組を理解するためです)
さて、デモンストレーション(!?)はここまでにして本格的なifステートメントを使ったプログラムを作ってみましょう
#include <stdio.h>
int main()
{
int var1;
int var2;
printf("2つの数を比較します\n最初の数を入力してください\n");
scanf("%d",&var1);
printf("比較する数を入力してください\n");
scanf("%d",&var2);
if (var1 < var2) printf("%d は %d より小さいです",var1,var2);
if (var1 > var2) printf("%d は %d より大きいです",var1,var2);
if (var1 == var2) printf("%d と %d は等しいです",var1,var2);
return 0;
}
一見ややこしそうですが、特別難しいことはしていません
これまでの章を読み進めてきた方なら、簡単に意味がわかるはずです
これで、入力された値に対して適切な文字列を出力するということができるようになりました
だんだん面白くなってきましたね
二者択一分岐
ifステートメントによって、プログラムを分岐させることに成功しました
これでより柔軟な、ユーザーにやさしいプログラムが作成できるようになったことでしょう
プログラムによっては「…でなければ」という処理を付け足したい場合もあります
if文で作るには != 演算子などを用いてその処理が可能です
#include <stdio.h>
int main()
{
char ch;
printf("半角英数で一文字入力してください\n");
scanf("%c",&ch);
if (ch == 'X') printf("X感じてみろー!");
if (ch != 'X') printf("パスワードが違います");
return 0;
}
しかし、これは二者択一ではありません
得られる結果は二者択一ですが、実際には条件式をちがう形で二回評価しています
そうではなく、ひとつのifステートメントの評価に対して「偽」であればという処理をすることができます
それがelseステートメントです
elseステートメントの前には、必ず式を評価するifステートメントが必要です
そのifステートメントが「偽」であった場合の処理をelseに委ねることができます
if (式) ステートメント;
else ステートメント;
ifとelseは必ず一方しか実行されません
つまり、完全な二者択一でありifステートメントを2回使うよりも遥かに合理的なのです
#include <stdio.h>
int main()
{
char ch;
printf("半角英数で一文字入力してください\n");
scanf("%c",&ch);
if (ch == 'X') printf("X感じてみろー!");
else printf("パスワードが違います");
return 0;
}
先ほどのプログラムとまったく同じ結果が得られますが、こちらのほうが合理的です
このくらいの短いプログラムでは大きな差はありませんが、膨大なプロジェクトになると話は別です
ほんのわずかなプログラムの違いが、結果に大きな差を生みます
少しでも機械にやさしい、合理的なプログラムを作成するのもプログラマの腕です
また、ifとelseステートメントは次のようにネストすることもできます
#include <stdio.h>
int main()
{
char ch;
printf("半角英数で一文字入力してください\n");
scanf("%c",&ch);
if (ch == 'X') printf("X感じてみろー!");
else if (ch == 'G') printf("月海さんですか…それも良いですね");
else printf("パスワードが違います");
return 0;
}
コードブロック
C言語では、複数のステートメントを一つにまとめるコードブロックというものがあります
コードブロックは { } で囲みます
これまでifステートメントやelseステートメントで実行できた内容は1行でした
つまり、ひとつのステートメントまでしか実行できないということですね
しかし、ifやelseで実行するステートメントをコードブロックで一つにまとめることで
複数のステートメントをifやelseで指定できるのです
if (式) {
ステートメント1
ステートメントn...
}
else {
ステートメント1
ステートメントn...
}
こうすればifやelseで分岐実行するステートメントをいくらでも指定することができます(長すぎるのは好まれませんが…)
コードブロックは1つのまとまった単位であることを理解してください
ステートメントを記述できる場所ならば、どこにでもコードブロックを書くことができます
コードブロックには暗黙の約束があります。コードブロック内の文は全てTabキーを使ってインデントします
もし以下のようなプログラムソースを書いたとしたら、あなた以外に読んでくれる人はいないと思っていいでしょう
if (a == b) {
printf("string");
if (a == c) {
printf("string")
}
}
else {
printf("string");
}
共同開発やオープンソースウェア開発を考えて、初心者のうちから正しいソースの書き方を習慣づけてください
(VC++のエディタを使っている人には不要なのでしょうけど…)
現代のプログラムの世界は「移植」や「拡張」などの機会が多く、そのたびに過去に書いたソースを読み直すことになります
#include <stdio.h>
int main();
int main()
{
char ch;
printf("半角英数で一文字入力してください\n");
scanf("%c",&ch);
if (ch == 'X') {
printf("X感じてみろー!\n");
printf("X叫んでみろー!\n");
printf("X全て脱ぎ捨てろー!");
}
else printf("パスワードが違います\n");
return 0;
}
ifステートメントの実行ステートメントにコードブロックを指定しています
コードブロックは例外を除いて、基本的に上から下へとプログラムが流れます
三項演算子
C言語では、if-else文に似た非常に便利な演算子が用意されています
それが三項演算子 「 ? 」(または条件演算子)です
三項演算子は、ある変数に値を代入する内容を条件で分ける時に非常に便利です
if-else文を使用すれば最低でも2行にわたりますが、三項演算子を用いれば1行に収まります
式 ? 真の処理 : 偽の処理;
式の評価が真であれば、真の処理を実行し
偽であれば偽の処理を実行します
コードブロックを使わない簡素な二者択一分岐の場合はこちらのほうが便利です
#include <stdio.h>
int main()
{
int var;
printf("0か1の値を入力してください>");
scanf("%d" , &var);
printf("%s" , var ? "真です" : "偽です");
return 0;
}
このプログラムの場合、変数varが0ならば"偽です"が評価(出力)され
それ以外の値であれば"真です"が出力されます
if (expression) { statements } [ else { else-statements } ]
expressionを判定して、真ならばstatementsを実行します
偽の場合、elseが指定してあればelse-statementsを実行します
expression - 必ず指定します。ifステートメントで評価する式を指定します
statements - ifステートメントの評価が真だった場合に実行するステートメントをひとつ以上指定します
(処理系によっては省略可能ですが、省略に意味がないので警告が出る可能性があります)
else else-statements - 評価が偽だった場合の処理を指定します。省略可能です
expr1 ? expr2 : expr3
expr1の評価結果に従い、expr2かexpr3のいずれかを実行します
expr1 - 真偽を評価する条件式または値を指定します
expr2 - 評価が真の時に実行するステートメントを指定します
expr3 - 評価が偽の時に実行するステートメントを指定します
この演算子の構文は、次のif文と同じ構造です
if (expr1) expr2;
else expr3;