はじめに
プログラムでは制御文があることで、入力に応じて様々な演算をしたり、結果を出力することができます。
ある程度の雰囲気が掴めてしまえば扱うことは難しくないので、サクッとやっていきましょう!
また、表現がわかりにくい点があったらコメント欄にて教えてください。よろしくお願いします。
制御文ってなに?
プログラムは通常ソースコードの先頭から順に実行されます。しかしプログラムの目的によっては途中で順番を変えたい場合もあります。
制御文はそのプログラムの実行順を変えることができる文のことです。
要するに、制御文があれば自分の思うがままにプログラムを実行させることができるようになるということです!
条件式について理解しよう!
早速、制御文について学んでいきたいところではありますが、その前に条件式について理解していきましょう。
制御文は「こういった条件の時に、これを実行してください」という命令をするので、その条件について理解しておく必要があります!
条件についての式を条件式といい、関係演算子を用いて次のように表します。
データ 関係演算子 データ
関係演算子には次のようなものが挙げられます。
- 「==」:一致
- 「!=」:不一致
- 「<」「>」「<=」「>=」:大小比較
例えば「aとbが不一致である」という条件式は次のように表します。
a != b
また、より複雑な条件を作りたい時には、論理演算子を用いることで対応できます。
論理演算子には次のようなものが挙げられます。
- 「&&」:かつ
- 「||」:または
- 「!」:否定
これらは上で作った単純な条件式について演算をするために存在していますが、条件式の真偽(満たしていれば真、満たしていなければ偽)というデータについて評価をしています。
このため条件式や論理演算子が組み合わさった条件式については括弧をつけて、論理演算子がどのデータを評価するのか示してやる必要があります。
以下に例を示します。
例えば「aとbが共に2より小さい」といった条件式は次のように表します。
(a < 2) && (b < 2) //条件式に括弧をつけて,どのデータについて評価するのか示す
例えば「aとbが共に2より小さいということの否定」という条件式であれば次のように表します。
!((a < 2) && (b < 2)) //論理演算子が組み合わさった条件式に括弧をつけて,どのデータを否定するのか示す
どうですか?条件式はたったこれだけを覚えておけばほぼ完璧です!
関係演算子や論理演算子という言葉については覚えていなくても全く問題ないです。
実際に制御文を書いてみよう!
順番に四つの制御文について理解し、扱えるようにしましょう!
if文
「ある条件を満たしている時にプログラムを実行する」
という制御文を書きたい時には「if文」を使って次のように書きます。
if(条件式){ プログラム }
この場合「条件式が真の時、プログラムを実行する」となります。
例として次に「年齢から20歳以上であれば成人であると表示するプログラム」を示します。
#include<iostream> int main(){ int a; //int型変数aの宣言 std::cout << "年齢を入力してください(ex:20)" << std::endl; std::cin >> a; //標準入力から変数aに格納 if(a >= 20){ std::cout << "成人です" << std::endl; //変数aが20以上であれば標準出力 } return 0; }
if 〜 else文
「ある条件を満たしている時はプログラムAを、満たしていない時はプログラムBを実行する」
という制御文を作りたい場合には「if 〜 else文」を使って次のように書きます。
if(条件式){ プログラムA } else{ プログラムB }
この場合「条件式が真の時、プログラムAを、条件式が偽である時、プログラムBを実行する」となります。
例として次に「年齢から20歳以上であれば成人であると表示し、20歳以上でなければ未成年であることを表示するプログラム」を示します。
#include<iostream> int main(){ int a; //int型変数aの宣言 std::cout << "年齢を入力してください(ex:20)" << std::endl; std::cin >> a; //標準入力から変数aに格納 if(a >= 20){ std::cout << "成人です" << std::endl; //変数aが20以上であれば標準出力 }else{ std::cout << "未成年です" << std::endl; //変数aが20以上でなければ標準出力 } return 0; }
if 〜 else if 〜 else文
「条件Aを満たしている時はプログラムAを、条件Aを満たしていないが条件Bを満たしている時はプログラムBを、それ以外の時はプログラムCを実行する」
という制御文を作りたい場合には「if 〜 else if 〜 else文」を使って次のように書きます。
if(条件式A){ プログラムA } else if(条件式B){ プログラムB } else{ プログラムC }
この場合「条件式Aが真の時、プログラムAを、条件式Aは偽だが条件式Bが真の時、プログラムBを、どちらの条件式も偽である時、プログラムCを実行する」となります。
「else if(条件式){}」の部分については複数個作っても構いませんが、あまりに多い場合は、後に説明する「switch文」を使うことをお勧めします。
例として次に「年齢から20歳以上であれば成人であると表示し、20歳以上ではなく18歳以上であれば成人コンテンツは見れるということ表示し、どちらにも当てはまらなければ後何年で成人かを表示するプログラム」を示します。
#include<iostream> int main(){ int a; //int型変数aの宣言 std::cout << "年齢を入力してください(ex:20)" << std::endl; std::cin >> a; //標準入力から変数aに格納 if(a >= 20){ std::cout << "成人です" << std::endl; //変数aが20以上であれば標準出力 }else if(a >= 18){ std::cout << "ビデオ屋の黒幕の奥に行けます" << std::endl; //変数aが20以上ではなく18以上であれば標準出力 }else{ std::cout << "成人まで" << 20-a << "年です" << std::endl; //変数aが上記のどちらにも当てはまらなければ標準出力 } return 0; }
for文
「希望の回数分プログラムを実行する」
という制御文を書きたい時には「for文」を使って次のように書きます。
for(初期化式;継続条件式;再初期化式){ プログラム }
この場合「初期化式を最初に一度実行した後、継続条件式を満たしていればプログラムと再初期化式を繰り返し実行する」となります。
初めて目にする単語があると思うので、それぞれを説明します。
- 初期化式とは、「for文」の最初に一度だけ実行される式で主に「for文」で使う変数の宣言と初期化を行います。
- 継続条件式とは、名前の通り繰り返すかどうか判定するための条件式のことです。呼び方が少し変わっただけで「if文」に出てきた条件式と同じです。
- 再初期化式とは、プログラムを一回実行する毎に最後に行う処理のことです。主に条件式に含まれている変数の値を変化させる処理を行います。
継続条件式を一度も満たさない場合にはプログラムは一度も実行されません。
また、再初期化式の後には「;」をつけないということに注意してください。
例として次に「入力された文字を指示された回数表示する」プログラムを示します。
#include<iostream> int main(){ char a; //char型変数aの宣言 int b; //int型変数bの宣言 std::cout << "文字を指定回数表示します。文字と整数値を入力してください。(ex:a 3)" << std::endl; //標準出力 std::cin >> a >> b; //標準入力から変数aに格納 for(int i = 0; i < b; i++){ //int型変数iの宣言と初期化(0),変数iが「i < b」を満たしている時,括弧内を繰り返す,最後にiに1を加える std::cout << a << std::endl; //標準出力 } return 0; }
while文
「ある条件を満たしている間プログラムを実行し続ける」
という制御文を書きたい時には「while文」を使って次のように書きます。
while(継続条件式){ プログラム }
この場合「継続条件式が真である時、プログラムを繰り返し実行する」となりますが、初めから条件を満たさずに継続条件式が真でない場合は一度も実行されることはありません。
例として次に「入力された数の約数に2がいくつ含まれているか判定するプログラム」を示します。
#include<iostream> int main(){ int a,b; //int型変数a,bの宣言 b = 0; std::cout << "入力された数の約数に2がいくつ含まれるか判定します。\n整数値を入力してください。" << std::endl; //標準出力 std::cin >> a; //標準入力から変数aに格納 while(a%2 == 0){ //変数aを2で割った時余りが0(要するに2で割り切れる時)括弧内を繰り返す a /= 2; //変数aを2で割った数を変数aに代入 b++; //変数bに1を加える } std::cout << "約数に含まれる2の数は" << b << std::endl; //標準出力 return 0; }
do 〜 while文
「一度はプログラムを実行し、その後ある条件を満たしている間、実行し続ける」
という制御文を書きたい時には「do 〜 while文」を使って次のように書きます。
do{ プログラム }while(継続条件式);
この場合「一度プログラムを実行した後、継続条件式が真である時、プログラムを繰り返し実行する」となります。「while文」と違う点は最低でも一度はプログラムが実行されるということです。
例として次に「0を入力されるまで入力を求め続けて、最後に入力されたもの全ての合計を表示する」プログラムを示します。
#include<iostream> int main(){ int a,b; //int型変数a,bの宣言 b = 0; do{ std::cout << "入力された数字を合計します。\n整数値を入力してください。(ex:2)\n0を入力すると終了して結果を表示します。" << std::endl; //標準出力 std::cin >> a; //標準入力から変数aに格納 b += a; //bにaを加算 }while(a != 0); //変数aが0でなければ直前の括弧内を繰り返す std::cout << "合計値は" << b << std::endl; //標準出力 return 0; }
switch文
「ある式の値について、定数AであればプログラムAを実行し、定数BであればプログラムBを実行し、…定数ZであればプログラムZを実行する」
という制御文を書きたい時には「switch文」を使って次のように書きます。
switch (式){ case 定数A: プログラムA; break; case 定数B: プログラムB; break; . . . case 定数Z: プログラムZ; break; default: break; }
「switch文」は今までの制御文に比べるとやや難しいですね。
まずはそれぞれのソースコードについて説明します。
- 「case 定数:」:caseラベルと呼ばれ、評価する式の値が定数と一致した際に、その位置まで移動します。
- 「default:」:defaultラベルと呼ばれ、評価する式の値がどのcaseラベルにも一致しなかった場合に、その位置まで移動します。
- 「break」:繰り返し処理やswitch文から抜けます。
説明に移動という言葉を使いましたが、switch文は評価する式の値が一致するところへ移動し、その後は順にプログラムを実行します。
つまりこの場合「式を評価してcaseラベル、もしくはdefaultラベルに移動してプログラムを順に実行し、breakのところでswitch文から抜ける」ということをしているわけです。
また、「if文」のように中括弧の中身を実行するというわけではないので、breakがなかった場合、そのまま下にあるプログラムを実行します。
例えば次のプログラムのようにbreakがない場合、式の値が定数Aであった場合「プログラムA、プログラムB、…、プログラムZが順に実行」され、定数Bであった場合「プログラムB、…、プログラムZが順に実行」されます。
switch (式){ case 定数A: プログラムA; case 定数B: プログラムB; . . . case 定数Z: プログラムZ; default: break; }
では最後に例として「1〜5の中で好きな数字を入力させ、数字によって適当なことを表示する」というプログラムを以下に示します。
#include<iostream> int main(){ int a; //int型変数aの宣言 std::cout << "好きな数字を1〜5の中から一つ入力してください(ex:1)" << std::endl; std::cin >> a; //標準入力から変数aに格納 switch(a){ //aについてのswitch文 case 1: //1の場合,ここに移動 std::cout << "強そう" << std::endl; break; //switch文から抜ける case 2: //2の場合,ここに移動 std::cout << "支えてくれそう" << std::endl; break; //switch文から抜ける case 3: //3の場合,ここに移動 std::cout << "控えめだけど"; case 4: //4の場合,ここに移動 std::cout << "巧みな感じ" << std::endl; break; //switch文から抜ける case 5: //5の場合,ここに移動 std::cout << "反射神経が良さそう" << std::endl; break; //switch文から抜ける default: break; //switch文から抜ける } return 0; }
制御文のあれこれ
ここまでで制御文の基本的なことは説明し終わりました。
ここからはいざプログラミングをしている時に、あれ?これってどうなんだろ?と疑問に思うような内容についてサクッと説明していきます!
制御文の中に更に制御文を使うことができる
題名の通りです。
例えば次のようにして「if文」の中に「if文」を使うことができます。
if(条件式A){ プログラムA if(条件式B){ プログラムB }else{ プログラムC } }
この場合「条件式Aが真であればプログラムAを実行して、更に条件式Bが真であればプログラムBを、偽であればプログラムCを実行する」となります。
他にも例えば次のようにして繰り返し処理の中に繰り返し処理や「if文」を使うことができます。
while(継続条件式A){ プログラムA if(条件式B){ プログラムB } while(継続条件式C){ プログラムC } }
この場合『継続条件式Aが真である間、プログラムAを実行し、条件式Bが真であればプログラムBを実行し、「継続条件式Cが真である間、プログラムCを実行するのを繰り返す」という動作を繰り返す』となります。
ごめんなさい言葉で表すのが難しいタイプのプログラムでした。うまく伝わっていなかったらすみません。
要するに制御文の中に制御文を入れることができて、その数に制限とかも一切ないということです!
繰り返し処理の中のbreak文
説明では「switch文」の中でしか使わなかった「break文」ですが「while文」や「for文」の中でも使うことができます。
例えば次のようなプログラムです。
while(継続条件式A){ プログラムA if(条件式B){ break; } }
この場合「継続条件式Aが真である間、プログラムAを実行し、条件式Bが真であればbreak文によってwhile文の繰り返し処理から抜けるという処理を繰り返す」となります。
要するに「break文」が実行されると継続条件式が真であろうと「while文」の繰り返し処理を途中で抜けることができるということです。
ただし次のような場合には注意が必要です。
while(継続条件式A){ プログラムA while(継続条件式B){ プログラムB if(条件式C){ break; } } }
この場合『継続条件式Aが真の間、プログラムAを実行し「継続条件式Bが真の間、プログラムBを実行し条件式Cが真であれば継続条件式Bを持つwhile文から抜けるという処理を繰り返す」という処理を繰り返す』となります。
要するに条件式Cが真であったとしても一番外側にある「while文」(継続条件式Aのもの)からは抜けることができません。
「break文」は繰り返し処理から抜けることができますが、抜けられるのは一つの繰り返し処理であり、複数個の繰り返し処理から同時に抜けることはできないということが重要な点です。
繰り返し処理が入れ子構造(繰り返し処理の中に繰り返し処理があること)となっている場合には、「break文」がどの繰り返し処理から抜けることを指すのかに注意してください。
演習問題
最後に演習問題をやって制御文を完璧にしましょう!
演習問題1
整数値を二つと文字を一つ入力させ、二つの整数値の差だけ文字を出力し、差が0の場合はエラーを出力するというプログラムを作成せよ。
例えば「1 3 a」と入力されれば「a」を二回出力する。
ヒント:二つの整数値の差は大きい数字から小さい数字を引けば良い。
演習問題2
整数値を二つと、a,s,m,dの中から一つの文字を入力させ、入力された文字に対応する演算(「a:加算」「s:減算」「m:乗算」「d:除算」)を二つの整数値に対して行い、結果を出力するプログラムを作成せよ。
ただし先に入力された数値に対して後に入力された数値で演算を行う。
例えば「1 2 b」と入力されれば「1 – 2」を実行し「-1」を出力する。
ヒント:case文を用いるとより簡単に作成できる。
演習問題3
「2〜99」までの整数値を一つ入力させ、素数であれば「素数である」と出力し、そうでなければ「素数でない」と表示せよ。
また、入力された整数値が「2〜99」でない場合にはエラーを出力せよ。
ヒント1:演算子「%」を用いて「a % b」とすることで、aをbで割った時の余りを出すことができる。
ヒント2:素数はその数と1以外を約数に持たない。つまり、素数は1とその数の間にある全ての数で割り切ることができない。
演習問題1解答
いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。
#include<iostream> int main(){ int a,b; //int型変数a,bの宣言 char c; //char型変数cの宣言 std::cout << "二つの整数値の差の分だけ文字を出力します。\n整数値二つと文字を一つ入力してください(ex:1 2 a)" << std::endl; //標準出力 std::cin >> a >> b >> c; //標準入力から変数a,b,cに格納 if(a > b){ //aがbより大きい場合 for(int i = 0; i < (a - b); i++){ //aからbを減算した数だけ繰り返し実行 std::cout << c << std::endl; } }else if(a < b){ //aがbより小さい場合 for(int i = 0; i < (b - a); i++){ //bからaを減算した数だけ繰り返し実行 std::cout << c << std::endl; } }else{ //aとbが同じ場合 std::cout << "Error" << std::endl; } return 0; }
演習問題2解答
いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。
#include<iostream> int main(){ int a,b,c; //int型変数a,b,cの宣言 char d; //char型変数dの宣言 std::cout << "二つの整数値について演算を行います。\n整数値を二つと行いたい演算に対応する文字を一つ入力してください(ex:1 2 a)\n「a:加算」「s:減算」「m:乗算」「d:除算」" << std::endl; //標準出力 std::cin >> a >> b >> d; //標準入力から変数a,b,dに格納 c = 0; switch(d){ case 'a': c = a + b; break; case 's': c = a - b; break; case 'm': c = a * b; break; case 'd': c = a / b; break; default: break; } std::cout << c << std::endl; return 0; }
演習問題3解答
いくつかの解答があると思われるが、解答例として以下のプログラムを用意した。
#include<iostream> int main(){ int a,b; //int型変数a,bの宣言 b = 0; std::cout << "2〜99までの整数値の中から整数値を一つ入力してください素数であるか判定します。" << std::endl; //標準出力 std::cin >> a; //標準入力から変数aに格納 if(a > 1 && a < 99){ //2〜99までの整数値が入力されていた場合 for(int i = 2; i < a; i++){ if(a % i == 0){ //2〜入力値までの全ての数で入力値を割って余りが0になっている場合、素数である。 std::cout << "素数でない" << std::endl; b = 1; //素数でないのでbに1を代入 break; //素数でない場合はそれ以上繰り返す必要がないので繰り返し処理から抜ける } } }else{ //2〜99までの整数値以外が入力されていた場合 std::cout << "Error" << std::endl; b = 1; //素数でない(判定外)なのでbに1を代入 } if(b == 0){ //素数でない場合はbに1を代入した、つまりbが0である場合、素数である。 std::cout << "素数である" << std::endl; } return 0; }
コメント