皆さんこんにちは、 南 晴輝 ( みなみ せいき )です。
今回は、C言語で特に重要な、制御構造 を解説します。
制御文とは、プログラムの流れを制御するものです。
C言語も他のプログラム言語と同じように、上から下に順次プログラムは実行されます。
これを「順次構造」とよびます。
しかし、プログラムによっては、処理を繰り返したり、条件によって違う処理をさせたい時などは、
順次構造以外の制御の流れが必要になります。
以下のような制御構造があります。
順次構造
分岐構造
単一分岐構造
多重分岐構造
ケース構造
反復構造
前判定型反復構造
後判定型反復構造
順次構造
上から下にかけて順に実行されます。
分岐構造
分岐の条件が1つだけの時に単一分岐といいます。
次に例を示します。下の例では、キーボードから数字を入力し、それが1960年以上 1970年未満なら
「1960年代」と表示します。
*/
/*
#include <stdio.h>
void main(){
int yea_r;
printf("西暦で年を入力してください。");
scanf("%d", &yea_r);
if ( 1960 <= yea_r && yea_r < 1970 )
printf("1960年代です。\n");
}
*/
/*
上の例のように、「1960年以上」という条件と「1970年未満」という条件を
「&&」(アンド記号)で区切ることで、その両方を満たす場合に限り、次の文が実行されます。
そして、複数の条件のうちどれか一つでも満たされていれば実行させたい場合は、
「&&」の代わりに、「||」(オア記号)で区切ります。
もし、条件が満たされない場合の処理が必要なければ、「else」文を省略できます。
多重分岐
単一分岐を組み合わせたもので、単一分岐の処理の中にまた条件分岐を含むものです。
if(条件1){
if(条件2){
処理3;
}
else{
処理2;
}
else{
処理3;
}
以下に例を示します。以下の例では、キーボードから数字を入力し、その数字が負数なら「負数」、
0なら「0」、整数なら「整数」と表示します。2例を示すが、どちらも同じ結果になります。
*/
/*
#include <stdio.h>
void main(){
int yea_r;
scanf("%d",&yea_r);
if ( yea_r < 0 ){
printf("負の数です。\n");
}
else{
if ( yea_r == 0 ){
printf("零です。\n");
}
else{
printf("正の数です。\n");
}
}
}
*/
/*
上のように、多重分岐では、「else」は直前の「if」に対応します。
*/
/*
3つ以上の異なった処理の中から、条件にあう処理を行うことを多方向分岐と言い、
次のような書き方をします。
「switch」文の括弧の中は、「int」型、「char」型、「enum」型のみが許されます。
西暦を入力し、その年の干支を表示させます。ただし西暦0年は申年とします。
*/
/*
#include <stdio.h>
void main(){
int yea_r;
printf("西暦を入力してください : ");
scanf("%4d", &yea_r); // 西暦入力
if ( yea_r < 0 )
yea_r = -yea_r; // 正に直す
switch( yea_r % 12 ){ // 12で割ったあまり
case 0 :
printf("%d年は申年です。\n", yea_r);
break;
case 1 :
printf("%d年は酉年です\n", yea_r);
break;
case 2 :
printf("%d年は戌年です\n", yea_r);
break;
case 3 :
printf("%d年は亥年です\n", yea_r);
break;
case 4 :
printf("%d年は子年です\n", yea_r);
break;
case 5 :
printf("%d年は丑年です\n", yea_r);
break;
case 6 :
printf("%d年は寅年です\n", yea_r);
break;
case 7 :
printf("%d年は卯年です\n", yea_r);
break;
case 8 :
printf("%d年は辰年です\n", yea_r);
break;
case 9 :
printf("%d年は巳年です\n", yea_r);
break;
case 10 :
printf("%d年は午年です\n", yea_r);
break;
case 11 :
printf("%d年は未年です\n", yea_r);
break;
}
}
*/
/* 反復構造(while)
ここで紹介するwhile文は、前判定型であり、繰り返し処理に入る前に繰り返し条件をチェックします。
したがって、条件によっては繰り返し処理を1度も実行しない場合もありえます。
1から100までの合計を求めてみます。
*/
/*
#include <stdio.h>
void main(){
int n, t;
n = 1;
t = 0;
while(n <= 100){
t = t + n;
n = n + 1;
}
printf("1から100までの合計は%dです。\n",t);
}
*/
/*
while文ではwhileの後の括弧の中に条件式を記述し、その条件式が真になる間、処理が繰り返されます。
もちろん、複数の条件式を「&&」「||」でつなげることもできます。
*/
/*
ここで紹介するdo~while文は、後判定型であり、繰り返し処理を行った
後に繰り返し条件をチェックします。
したがって、どんな条件でも最低1回は繰り返し処理が実行されます。
前ページ同様、1から100までの合計を求めてみます。
*/
/*
#include <stdio.h>
void main(){
int n, t;
n = 0;
t = 0;
do{
t = t + n;
n = n + 1;
}while(n <= 100);
printf("1から100までの合計は%dです。\n",t);
}
*/
/*
do~while文ではwhileの後の括弧の中に条件式を記述し、その条件式が真になる間処理が繰り返されます。
もちろん、複数の条件式を「&&」「||」でつなげることもできます。
*/
/*
反復構造(for)
ここで紹介するfor文は、前判定型であり、繰り返し処理に入る前に繰り返し条件をチェックします。
したがって、条件によっては繰り返し処理を1度も実行しない場合もあり得ます。
for文は、while文に初期設定と、変化式を組み合わせたものです。
これまでの例と同様に1から100までの合計を求めてみる。while文を使用すると下記のようになります。
void main(){
int n, t;
n = 1; // 初期設定
t = 0; // 初期設定
while(n <= 100){
t = t + n;
n = n + 1; // 変化式
}
printf("1から100までの合計は%dです。\n",t);
}
*/
/*
void main(){
int n, t;
for ( n = 1, t = 0 ; n <= 100 ; n = n + 1 ){
t = t + n;
}
printf("1から100までの合計は%dです\n",t);
}
すなわち、
for ( 初期設定 ; 条件式 ; 変化式 )
繰り返し処理となる。
初期設定、変化式はカンマ「,」で区切って複数の式にすることもできますが、あまり使いません。
また、初期設定、変化式が必要ない場合は、必ずしも記述する必要はなく、省略することもできます。
しかしこの場合もセミコロン「;」は省略できません。その例を下記に示します。
void main(){
int n, t;
n = 1; // 初期設定
t = 0; // 初期設定
for( ; n <= 100 ; n = n + 1){
t = t + n;
}
printf("1から100までの合計は%dです。\n",t);
}
繰り返す処理が1文の時は、中括弧を省略し、下記のように書くこともできます。
void main(){
int n, t;
n = 1;
t = 0;
for( ; n <= 100 ; n = n + 1)
t = t + n;
printf("1から100までの合計は%dです。\n",t);
}
このように処理が1文の時に中括弧を省略できるのは「if」「else」文、「while」文も同様です。
*/
/*
補助制御文
反復構造では同じ処理を繰り返しましたが、場合によっては条件式が真でも反復構造から
抜け出したい場合が生じたりする場合もあります。、
実際のプログラムでは、このように反復処理中にその処理から抜け出した方が、
プログラムがすっきり書ける場合も少なくありません。
そのような時には補助制御文を使用します。補助制御文には以下のような物が用意されています。
break
「switch~case文」のところでも紹介しましたが、「while」「for」などの反復処理中に使用すると
強制的に反復処理を抜けます。
反復処理が入れ子になっている場合(多重反復処理)は、内側の反復構造を1つだけ抜けるだけです。
continue
反復構造中に使用すると、反復処理が終了したことになります。すなわち条件評価を行い、
条件が真ならばもう一度反復処理を実行します。なお、「for」文であれば、
変化式も実行した後に条件式を評価します。
goto
ラベルへの無条件分岐です。C言語では、まず使いません。
組み込み系では、ハードウェアのトラブルなどの緊急に処理が必要な時のみ使います。
return
その関数から抜けます。
以下に例を示します。この例では、数字を2つ入力しa,bに代入します。
そしてaからbまでの偶数の和を求めますが、bが100以上の場合はaから100までの偶数の合計を求めます。
なおaの方が大きい場合のチェックはしていません。
*/
/*
#include <stdio.h>
void main(){
int a, b, t;
scanf("%d %d", &a, &b);
for ( t = 0 ; a <= b ; a++ ){
if ( a > 100 ) // 100以上になったら終了
break;
if ( a % 2 ) // 偶数じゃなかったら、変化式を実行
continue;
t = t + a;
}
printf("%d\n", t);
}
*/
/*
上の例の「continue」文の前の「if」文の条件ですが、本題からはずれますが、ここで解説します。
条件式は「真」か「偽」で判断します。C言語では「0」と「偽」は等価です。
また「0以外」と「真」は等価です。
したがって、「a % 2」すなわち「a÷2」の余りが真(0以外)ならば「continue」を実行します。
したがって「if ( a % 2 )」は「aが奇数なら」という意味になります。
「a % 2」すなわち「a÷2」の余りが真(0以外)ならば「continue」を実行します。
「aが偶数なら」「a % 2」の値は、ゼロ(0)になります。
*/
今回は、少し難しかったと思いますが、とくに良く使う制御構造ですので、
繰り返し読んで、理解してください。
ありがとうございました。
南 晴輝
追伸 : 私は、劇団四季のファンです。 大阪ライオンキングを、7月15日に観劇しました。
観客全員が スタンデングオベーション でした。
皆さんも、是非観劇してください。