制御構文は、上から下へ流れるプログラムを途中で流れを分岐させたり、流れを繰り返したりすることができる構文を表します。
この制御構文を使うと・・・
・今までより複雑な処理をすることができる
・プログラムの流れを変えることができる
などと、今までと違ったプログラムを作成することができます。
A「制御構文って?」
B「判定して、どちらかの計算や出力を行うのか決めたり、同じ処理を繰り返し行うことが出来るようになるんだ」
A「どんな種類があるの?」
B「それはこれから見ていくよ。これを覚えれば、プログラムの流れを変えたり、より複雑な処理を行うことが出来たりなるよ」
と言うことで、これから制御構文の中身を見ていきましょう。
制御構文の主な種類としてif文、for文、while文、switch文の4パターンあります。
if文を使うと、分岐構造を作ることができます。
ゲームなどにもある「はい・いいえ」を選ぶとイベントやセリフが変わるアレと同じです。
if文の形式は以下の通りです。
パターン | 書き方 | 意味 |
---|---|---|
分岐構造(基本形) |
|
条件式を満たすと文1を実行する 条件式を満たさないと文2を実行する |
分岐構造(elseなし) |
|
条件式を満たすと文1を実行する 条件式を満たさないと何も行わない |
多分岐構造 |
: (中略) : } else if(条件式n) { |
条件式1を満たすと文1を実行する 条件式1を満たさないで条件式2を満たすと文2を実行する :
条件式1~n-1を満たさないで条件式nを満たすと文nを実行する(中略) : 全ての条件を満たさないと文xを実行する |
if文の入れ子 |
|
条件文1を満たし、さらに条件文2を満たすと文1を実行する 条件文1を満たし、条件文2を満たさないと文2を実行する 条件文1を満たさないと文3を実行する(ここは普通の分岐構造と一緒) |
条件式とは分岐するための条件で変数や数値・文字列などの値、関係演算子、論理演算子を用いて表します。
ここで関係演算子、論理演算子という新しい言葉が出てきました。
第3回で省略した演算子の一部ですが、これらは一体何でしょうか?
2つの値の大小を比較します。
条件を満たせば「真(true)」、条件を満たさなければ「偽(false)」となります。
関係演算子の形式は以下の通りです。
演算子 | 例 | 意味 |
---|---|---|
< | 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は等しくない |
条件式を複数組み合わせたり条件を否定させたりすることができます。
論理演算子の形式は以下の通りです。
演算子 | 例 | 意味 |
---|---|---|
&&(and) | a > 0 && b > 0 | aは0よりも大きいかつbは0よりも大きい |
||(or) | a > 0 || b > 0 | aは0よりも大きいまたはbは0よりも大きい |
!(not) | !a | aではない |
これらの条件式はif文以外でも使いますので必ず覚えましょう。
さて、長々と書いてしまいましたが、分岐構造(基本形)、多分岐構造、論理演算子を使った分岐構造の例を見て行きたいと思います。
#include <stdio.h> int main() { int a = 0, b = 0; printf("数値を2つ入力してください\n"); printf("a="); scanf("%d", &a); printf("b="); scanf("%d", &b); if(a == b) { //a, bが同じ数値なら以下の処理を行う printf("入力された数は同じです\n"); } else { // それ以外(a, bが違う数値)なら以下の処理を行う printf("入力された数は違います\n"); } return 0; }
(左)数値が同じ場合 (右)数値が違う場合
#include <stdio.h> int main() { int a = 0, b = 0; printf("数値を2つ入力してください\n"); printf("a="); scanf("%d", &a); printf("b="); scanf("%d", &b); if(a < b) { //変数a, bの比較(aがbより小さければ) printf("bのほうが大きいです\n"); } else if(a > b) { //変数a, bの比較(aがbより大きければ) printf("aのほうが大きいです\n"); } else { //変数a, bの比較(a, bが同じ大きさならば) printf("同じ大きさです\n"); } return 0; }
(左上)aの方が大きい場合 (右上)bの方が大きい場合 (左下)同じ場合
#include <stdio.h> int main() { int a = 0, b = 0; printf("数値を1つ入力してください\n"); printf("a="); scanf("%d", &a); // 式「a<=0」と式「a>=100」が真ならば(1)の処理、それ以外なら(2)の処理 if(a >= 0 && a <= 100) { printf("入力した数値は0~100の間にあります\n"); } else { //変数a, bの比較(a, bが同じ大きさならば) printf("入力した数値は0~100の間にありません\n"); } return 0; }
(左上)aが0~100の間にある場合 (右上)aが100以上の場合 (左下)aが0以下の場合
if文を書くときのポイントは以下の通りです。
・if文を記述した後はインデント(字下げ機能)をしてプログラムを見やすくする
・文が単文(1行のみ)の場合は{ }を省略できる
インデントはVC++2005などのプログラムエディタを使っている場合は自動的にインデントが行われるので心配いりません。
インデントはプログラムを見やすくするために行うので特にインデントする必要はありませんが、他の人にプログラムを見せるときはインデントをしておきましょう。
{ }は単文の場合のみ省略することが出来ます。
条件文以外のプログラムと混同することもありますので単文でも{ }を付けた方がいいでしょう。
複文の場合は必ず{ }は必要となります。
このポイントはif文だけではなく、for文、while文、switch文でも同じなので必ず覚えよう。
for文を使うと、処理を反復(繰り返し)させる構造を作ることが出来ます。
for文の形式は以下の通りです。
意味 | |
---|---|
初期条件 | for文を始めるときに初期化する変数と値を記述する。 基本的には継続条件となる変数を初期化する。 |
継続条件 | for文を継続させるための条件となる変数と値を記述する。 基本的には初期化式に記述した変数が使われる。 継続条件を満たしている限りはループを繰り返し、継続条件を満たしていない時はループをしない。 |
値変化 | for文をループした時に変化する変数と値を記述する。 基本的には初期化式に記述した変数が使われる。 |
例文 | 意味 |
---|---|
|
iが0からはじまり、iが10になるまで繰り 返し、ループするたびにiを1増やす |
例文で使用されている「i++」はインクリメント演算子というものです。
意味にも書いてあるとおりiを1増やすという意味になります。
要するに「i = i + 1」を省略した形だと考えてください。
この演算子には他にも「i--」というデクリメント演算子というものもあり、こちらはiを1減らすという意味になります。
ここで、簡単にインクリメント/デクリメント演算子の形式を説明します。
演算 | 演算子 | 例 | 意味 |
---|---|---|---|
インクリメント | ++ | a++ | aに1を加える |
++a | |||
デクリメント | -- | a-- | aから1を引く |
--a |
さて、ここで「aの前に演算子が書いてあるものとaの後ろに演算子が書いてあるものとは同じ意味」と捉えたかと思います。
確かに両方ともaに1加減するという意味なんですが、加減するタイミングが違います。
a++の場合
変数の前に演算子を書いた場合は式を評価する前に1を加えます。
++aの場合
変数の後に演算子を書いた場合は式を評価した後に1を加えます。
a--と--aの場合も同様です。
式を評価する前に計算することを前置演算、式を評価した後に計算することを後置演算といいます。
実際に例題4を書いてみて実感してみましょう。
#include <stdio.h> int main() { int a=0, b=0, c=0, d=0; printf("aの初期値:%d\n", a); printf("a++の値:%d\n", a++); //式を評価したあとに+1 printf("aの値:%d\n", a); printf("\n"); printf("bの初期値:%d\n", b); printf("++bの値:%d\n", ++b); //式を評価するまえに+1 printf("bの値:%d\n", b); printf("\n"); printf("cの初期値:%d\n", c); printf("c--の値:%d\n", c--); //式を評価したあとに-1 printf("cの値:%d\n", c); printf("\n"); printf("dの初期値:%d\n", d); printf("--dの値:%d\n", --d); //式を評価するまえに-1 printf("dの値:%d\n", d); return 0; }
printf()が多いのは気にしないで・・・とりあえず結果を見てみましょう!
結果のように、演算子を変数の前と後で位置を変えると結果が変化しますね。
またまた前置きが長くなってしまいました・・・for文もif文と同じように例題を書いていきましょう!
#include <stdio.h> int main() { int n = 0 ,s = 0 ,sum = 0, avg = 0; //変数の宣言と初期化 printf("数値を20個入力してください\n"); for(n=1; n<=20; n++) //nに1 を代入、nが20になるまで、nに1を足す { printf("%d個目の数値を入力してください=",n); scanf("%d",&s); //「sum = sum + s」で入力された数値sとsum(0)を足し結果をsumに代入 //これをすることにより今まで入力された数値の合計をsum変数内に格納できる sum = sum + s; } avg = sum / 20; //数値20個の平均を求める計算式 printf("平均値%d",avg); return 0; }
これをfor文を使わないで書いたらすごい行数になりそうですね。
暇な人はfor文を使わないで書いてみて、for文のありがたさを実感してみるのもいいでしょう。
while文を使うと、処理を反復(繰り返し)させる構造を作ることが出来ます。
「それではfor文と全く同じじゃないか!」と思っている人も少なくともいるでしょう。
一般的にfor文は「指定した回数分だけ処理を繰り返す」、while文は「指定した条件を満たすまで処理を繰り返す」と言う意味で、for文とwhile文は似ているようで定義されている意味は違います。
for文とwhile文の違いを簡単に理解してもらったところで、while文の形式は以下の通りです。
継続条件があらかじめ満たしていない場合はwhile文の命令は実行されません。
例文 | 意味 |
---|---|
|
iが10になるまでループを繰り返す |
それでは、for文と一緒の使い方をするためにはどのようにすればいいのでしょうか?
初期化式をwhile文が始まる前に、値変化をループの最後に記述すればfor文と全く同じになります。
for文を使ったとき | while文を使ったとき |
---|---|
for(i = 0; i < 10; i++) { |
|
今回は短い説明でしたね。それでは、例題を行ってみましょう。
#include <stdio.h> int main() { int n=1, s=0, sum=0, avg=0; printf("数値を20個入力してください\n"); while(n<=20) //()の中が真の間繰り返す { printf("%d回目の入力=",n); //nは1周するごとに+1されていく scanf("%d",&s); sum += s; //sum = sum + sという意味(sum + sを計算し、sumに代入) n++; //while(~)の条件になるまでnに1を足す } avg=sum/20; //平均値を求める式 printf("平均値=%d\n",avg); return 0; }
例題5と同じ結果になりましたね。
余談ですが、for文とwhile文、処理速度が速いのはどちらでしょうか?
昔、while文のほうが速いと聞いたことがあるのですがどうでしょう?
暇があれば書いてみたいと思います。
switch文を使うと、多分岐構造を作ることが出来ます。
if~else if~elseを使うより簡単に多分岐構造を作れます。
switch文の形式は以下の通りです。
意味 | |
---|---|
条件式 | 条件を比較するための式、基本的に変数を書く |
定数 | 条件に使われる定数、基本的に整数や文字を書く |
switch文では条件式を使って分岐させ、定数と条件が等しくなるとcase以下の処理を実行し、breakを見つけるとswitch文から抜け出します。
breakを書き忘れると、次のcase条件まで実行してしまうので、breakの書き忘れには十分注意が必要です。
条件式・定数はともに整数と文字のみ使え、小数などの実数や、文字列は使用できません。
それでは、例によって例題を行いましょう。
#include <stdio.h> int main() { int i = 0; printf("1~12の数値の内1つ数値を入力してください\n"); scanf("%d",&i); //switch(i)にはデフォルトだと0が入っている switch(i) { case 1: //1 月が入力された場合 printf("1月は31日です\n"); break; case 2: //2 月が入力された場合 printf("2月は28日です\n"); break; case 3: //3 月が入力された場合 printf("3月は31日です\n"); break; case 4: //4 月が入力された場合 printf("4月は30日です\n"); break; case 5: //5 月が入力された場合 printf("5月は31日です\n"); break; case 6: //6 月が入力された場合 printf("6月は30日です\n"); break; case 7: //7 月が入力された場合 printf("7月は31日です\n"); break; case 8: //8 月が入力された場合 printf("8月は31日です\n"); break; case 9: //9 月が入力された場合 printf("9月は30日です\n"); break; case 10: //10 月が入力された場合 printf("10月は31日です\n"); break; case 11: //11 月が入力された場合 printf("11月は30日です\n"); break; case 12: //12 月が入力された場合 printf("12月は31日です\n"); break; default: //1~12 の数値以外が入力された場合に出力される printf("数値が間違っています\n"); break; } return 0; }
(左)12と入力した場合 (右)8と入力した場合
日数が表示されましたね!ちなみに、うるう年は考えていません。
Cがある程度できるようになれば、うるう年の計算もできるようになります。
switch文のところでbreakというのが何回も登場しました。
switch文での意味は「switch文から抜け出す」という意味でしたね。
breakはswitch文以外にもfor文やwhile文のループの中でも使うことが出来ます。
この時もbreakは「for文やwhile文のループから抜け出す」という意味を持っています。
その中でもfor文やwhile文のbreakは無限ループでよく使用されます。
for文やwhile文などで継続条件を常に満たすようにすると無限ループになります。
breakとセットに覚えてほしいのがcontinueです。
continueはfor文やwhile文などのループ処理をスキップさせるに用います。
breakとは違い、continueはスキップした後は、ループの先頭に戻ります。
breakとcontinueの使い方を間違いないようにしてください。
#include <stdio.h> int main() { int i=0, n=0, sum=0; printf("数値を足していきます(0を入力すると計算を終了します)\n"); while(1) // 真の間以下の処理を繰り返す { printf("足す数を入力してください\n"); scanf("%d",&i); sum += i; //入力した数値を足してゆく式 ( sum = sum + i ) と同じ意味 printf("只今の合計%d\n",sum); if(i == 0) //i==0の場合ループから抜ける { break; } } return 0; }
while文の()の中に1と書くと、常に「真」の状態となり、{ }の中を無限に繰り返します。
例題8ではユーザが「0」を入力したときにbreak文でwhile文から抜け出しています。
数値を入力して、それらが正か負かのどちらか判断するプログラムを書いてみよう。
(注意)0は正数とします
(上)負数が入力された場合 (下)0を含む正数が入力された場合
//数値を入力してそれが正数か負数かの判別するプログラム #include <stdio.h> int main() { int i = 0; printf("正負判別プログラムです数値を入力してください\n"); scanf("%d",&i); if(i >= 0) //iが0以上ならば { printf("入力された数値は正数です\n"); } else { //それ以外ならば printf("入力された数値は負数です\n"); } return 0; }
if文を使用しています。
入力された数値が0以上であれば正数と表示し、それ以外は負数と表示させていますね。
数値を入力し、1から入力された数の合計を求めてみよう。
#include <stdio.h> int main() { int i = 0 ,s = 0 ,c = 0; printf("数値を入力してください\n"); scanf("%d",&i); for(s = 1; s <= i; s++){ //sに1を代入、sがi以上になるまで、sに1を足す c = c + s; //c += s; と書き換えることもできる } printf("1~%dまでの合計は%dです\n", i, c); return 0; }
ここではfor文を使います。
for文の中で使う変数sの宣言を忘れないでつけていますか?
また、()の中の区切りは「,」ではなく「;」です。
慣れないうちはよく間違えるので、気をつけてくださいね。
第2問のプログラムをwhile文を使って書いてみよう。
#include <stdio.h> int main() { int i = 0 ,s = 0 ,c = 0; printf("数値を入力してください\n"); scanf("%d",&i); for(s = 1; s <= i; s++){ //sに1を代入、sがi以上になるまで、sに1を足す c = c + s; //c += s; と書き換えることもできる } printf("1~%dまでの合計は%dです\n", i, c); return 0; }
for文をwhile文に書き直しただけですね。
while文の()の中は「真」の間中の処理を行っています。
コーヒー100円、コーラ120円、紅茶105円、野菜ジュース130円とします。コーヒー→1、コーラ→2、紅茶→3、野菜ジュース→4として、それぞれの数値が入力されたら種類と値段を表示するプログラムを書いてみよう。
(上)コーラを選択した場合 (下)選択肢以外の数値を入力した場合
#include <stdio.h> int main() { // switch用変数 int sel = 0; printf("1:コーヒー、2:コーラ、3:紅茶、4:野菜ジュース\n"); printf("あなたのお好みは?="); scanf("%d",&sel); switch(sel){ // 1が入力された場合 case 1: printf("種類:コーヒー\n値段:100円\n"); break; // 2が入力された場合 case 2: printf("種類:コーラ\n値段:120円\n"); break; // 3が入力された場合 case 3: printf("種類:紅茶\n値段:105円\n"); break; // 4が入力された場合 case 4: printf("種類:野菜ジュース\n値段:130円\n"); break; // それ以外が入力された場合 default: printf("お気に召しませんでしたか?\n"); break; } return 0; }
switch用の変数は用意できていましたか?
caseで振り分けたとき、breakでswitch文から抜けるのを忘れると、それ以降のものが表示されてしまいますね・・・
break文を入れる癖をつけておくといいでしょう。
Copyright (C) 2011 ほぷしぃ. All Rights Reserved.