第4回. 制御文 Written by Rorrim Cプログラミングのなかで結構重要な位置を占める制御文をお勉強しましょう。 この制御文とはプログラムの流れを制御するのにつかいます。 まず覚えて欲しいのは制御文の種類です。 今回は一番良く使う「if」「while」「for」について勉強しましょう。 まずは「if文」を使った簡単なプログラムを書きますので それを例として制御文とはなんなのかを考えましょう。 ----------------------------------------------------- 1| #include 2| #include 3| 4| int main(void) 5| { 6| int myInt; 7| myInt = 5; 8| 9| if ( myInt == 0 ); 10| printf("myInt is equal to ZERO."); 11| else 12| printf("myInt is NOT equal to ZERO."); 13| 14| return 0; 15|} ----------------------------------------------------- さて初めて見る行はなんでしょうか? 「2」「4」「9」「11」「14」行目ですね? これらの文から順番に説明します。 2 ここでと呼ばれるヘッダを読み込んでいます。   あんまり深く考えないで下さい。   私自身このプログラムにstlib.hが必要かどうか解らないんですから。   (Cに詳しい方、教えて下さ〜い) 4 今までの「main()」とは、趣向を変えてvoid-mainにしてみました。   このvoidと言うのは「中身が空」だということを意味しています。   中身とは、「main()」の中、つまり「(」と「)」の中の事です。   もう少し詳しく言うと5行目の「{」から15行目の「}」までの   中身が空だと言う事を宣言しているんです。   ですから、14行目(つまりプログラムの終わり)で   「return 0;」と書いて「今までのはぜ〜んぶなしよ!」   と言っているんです。   こうする事によって宣言されていた「myInt」等は初期化されて   解放される事になります。 9 今回のメインである制御文のお出ましです。 < if文> 「if」を日本語に訳したらなんでしょう? 答えは「もし〜ならば・・・」ですね? つまり if文とは、そう言う真偽判定をプログラムに用いたものです。 基本的な文法は「if (条件式、文) 実行文」です。 このプログラムでは、 ・条件:myInt == 0 ・実行:printf("myInt is equal to ZERO."); となります。 また条件に合わない場合は「else」以下が実行されます。 if (条件) この条件が真ならば { 文1;  −−−−− 文2; |  ・ | このブロックを実行する   ・ |  文N;   −−−−− } else if (条件) このの条件が真ならば { 文1;  −−−−− 文2; |  ・ | このブロックを実行する   ・ |  文N;   −−−−− } else if (条件) このの条件が真ならば { 文1;  −−−−− 文2; |  ・ | このブロックを実行する  ・ |  文N;   −−−−− } else  それ以外ならば { 文1;  −−−−− 文2; |  ・ | このブロックを実行する   ・ |   文N;   −−−−− } さてさて条件に見られる「==」について ちょっと時間を割いて頂きます。 このような「==」「!=」「>」「>=」等は、関係演算子と呼ばれ、 2つの値を比較する時に使います。 ================================================ 式        真になる場合 ------------------------------------------------ a == b aはbに等しい a != b aはbに等しくない a < b aはbより小さい a > b aはbより大きい a <= b aはb以下である a >= b aはb以上である ================================================ ですから出力は以下の様になります。 ------------------------------------------------- myInt is NOT equal to ZERO. ------------------------------------------------- また、2つ条件を組み合わせる方法として「&&」「||」の演算子 があります。 ========================================================================== 式          真になる条件 -------------------------------------------------------------------------- a > b && b == c aはbより大きく「かつ」bはcに等しい c != d || d > b cはdに等しくないか「または」dはbより大きい ========================================================================== さてどうでしょうか? これでif文についての説明を終えて、while文、for文の説明に移ります。 <while文> while文の文法はif文と構造的にそっくりです。 違いはwhile文の場合、条件に真である間、繰り返し実行文を 実行し続けると言う事です。 条件に偽であったり、また実行中に偽になれば文は実行されず while文の次の処理単位に処理が移ります。 実際のプログラムの例と実行結果を書きますと次の様になります。 ------------------------------------------------- #include #include main () { int i = 0; while (i < 5) printf("%d¥n", i++); printf("We're out of the LOOP.¥n"); } ----------EOP---------- 0 1 2 3 4 We're out of the LOOP. % ------------------------------------------------- プログラムの動作順序は以下の様になります。 =========================================================== iを0に初期化する; i < 5 の条件式を評価する; この条件式が真ならば、最初のprintfを実行する; printfでiの現在の値を出力する; 次にiを1インクリメントする; ・     ・     ・ もとのwhileへ戻り、i < 5 の条件を再び評価する; 同様にして、最終的に i < 5 の条件に偽になる; ループを脱出して、We're out of the LOOP. と出力する; =========================================================== インクリメントの説明は後でしますので、 前回のような図を書きましょう。 while (条件) この条件が真ならば { 文1;  −−−−− 文2; |  ・ | このブロックを実行する   ・ |   文N;   −−−−− } こういった図は、混乱しがちな制御文を特徴付けて覚えるのに 大変役に立つので覚えておいた方がいいと思います。 さてインクリメントの説明をします。 単純に言うと1を足すって事なんです。 逆に1を引く場合をデクリメントと言って「a--」とか書きます。 ちなみにa++と書こうが++aと書こうが1を足す事に変わりありません。 同じようにa--と--aも一緒です。 しかしこれらの演算子を、前置演算子として使うか後置演算子として使うか では意味が異なります。 ややこしい話ですが、仮に変数aの値を5として考えましょう。 b = ++a これは、aの値が1インクリメントされ6になりbに代入されています。 つまり a = a + 1 b = a ですね?では b = a++ これはどうでしょう?bの値にaの値を代入してaを6にインクリメント しています。 つまり b = a a = a + 1 と言う事です。 デクリメントに付いても同様です。 この2つの違いをよく理解してください。 ではいよいよ今回の目玉であるfor文を説明します。 <for文> for文はCで最も頻繁に使われるループ構造と言えます。 何故かと言うとfor文を使えばループに関する次の3点を1行で 書けるからです。 1指定回数のループを行う為のカウンタの初期化 2ループを継続するための条件判定 3カウンタの再設定 図で説明するとこうなります for (カウンタの初期化; 条件判定; カウンタの再設定) { 文1;  −−−−− 文2; |  ・ | このブロックを実行する   ・ |   文N;   −−−−− } これをwhile文で次の様に書くのとまったく同じです。 カウンタの初期化; while (条件判定) { 文1; 文2;  ・   ・   文N; カウンタの再設定; } つまり以下の2つのプログラムは動作的に考えると同じものになります。 -----素数判定プログラム---while---------------------------- main () { int i = 1; int n = 1234; /*この値を判定する*/ while ( ++i < n) if (n % i == 0) /*iで割り切れたら素数でない*/ { printf("NOT prime¥n"); break; } if ( i == n) /*breakで脱出しなかったら実行*/ printf("PRIME!!¥n"); } ----------EOP------------------------------------------ -----3から1235までの素数を出力-----for------------ main () { int i, n; for (n = 3; n <= 1235; ++n) { for ( i = 2; n < n; ++i) if (n % i ==0) break; if ( i == n) printf("%d¥n", i); } } ----------EOP----------------------------------------- どうでしょうか?while文を使うよりfor文を使った方がすっきりして わかりやすいプログラムになったと思いませんか? 最後に「%」と「break」の意味を説明して 今回のお勉強を終わります。 %はモジュロ演算子と呼ばれる余り(剰余)を求める時に使う演算子です。 整数で除算(/)を行った場合、余りは切り捨てになります。 つまり5/3の結果は1であり、3/5は0となるのです。 そこで余りを知りたいときには、モジュロ演算子「%」を使う必要があります。 この演算子の動作は次の様になります。 ・5%3は2 ・3%5は3 ・3%3、6%3は0 注意点としては、この演算子がint型、char型の整数型データに対しては作用 しますが、float型やdouble型の実数型データには作用しません。 breakはループの脱出に利用されます。 ループ中にbreakが検出されると制御は即座にループに続く 最初の文に渡されます。 つまり実行中のブロックから抜けて、1つ外側の実行単位に移ります。 さっきのプログラムで言うと、iが2の時、1234 / 2 = 617になり、 剰余が出ないのでプログラムはすぐに終わります。 つまり、iの値が2のときに、「NOT prime」のメッセージが出力され、 break文によりループを脱出します。 プログラムの制御は、その直後にあるif文に移り、i(この時点では2)と n(この時点で1234)が比較されます。この比較は正しくないので、 プログラムはifの実行文をスキップし終了します。 今回はこれで終わります。 (さすがに疲れた〜)