あらゆるアルゴリズムは次の3つの構造で実現可能と言われています(構造化定理)。
C言語でこれらを実現する制御文についてみていきます。
3つの構造に対してC言語での制御方法は次のようになります。
C言語の規約に従って順次にプログラムを実行させます。
選択処理は「~のとき~する」といった場合に使用します。
if文は主に択一分岐処理をおこなう制御文で、次のような構文になります。
if (条件) {
条件が真のとき行う処理;
}
if (条件)
条件が真のとき行う処理;
※ソースの可読性を低めるので、この省略形はあまりお勧めできません。(コーディング規約などで禁じている開発現場も多いです。)
if (条件) { 条件が真のとき行う処理1; } else { 条件が偽のとき行う処理2; }
if (条件1) { 条件が真のとき行う処理1; } else if (条件2) { 条件1が偽で条件2が真のとき行う処理2; } else { 条件1、条件2が共に偽のとき行う処理3; }
・サンプルソース(sample0401.c)
#include <stdio.h>
int main() {
int x = 70;
if (x >= 80) {
printf("%d点は「優」です。\n",x);
} else if (x >= 60) {
printf("%d点は「良」です。\n",x);
} else if (x >= 40) {
printf("%d点は「可」です。\n",x);
} else {
printf("%d点は「不可」です。\n",x);
}
return 0;
}
・実行結果
C:\dev\c>sample0401 [Enter]
70点は「良」です。
switch文は多分岐処理をおこないます。構文は次の通りです。
switch (式) { case 値1: 処理1; case 値2: 処理2; case 値3: 処理3; }
switch (式) { case 値1: 処理1; break; case 値2: 処理2; break; case 値3: 処理3; }
switch (式) { case 値1: 処理1; break; case 値2: 処理2; break; default 値3: 処理3; }
・サンプルソース(sample0402.c)
#include <stdio.h>
int main() {
char x = 'B';
switch (x) {
case 'A':
printf("賞品の筆箱を獲得しました。\n");
case 'B':
printf("賞品の消しゴムを獲得しました。\n");
case 'C':
printf("賞品のえんぴつを獲得しました。\n");
}
return 0;
}
・実行結果
C:\dev\c>sample0402 [Enter]
賞品の消しゴムを獲得しました。
賞品のえんぴつを獲得しました。
つぎは悪名高きgoto文です。構造化プログラミングを考える上で絶対使うな!っていわれます。かといってgoto文を使っていないだけでこれってよけいに悪くなってない?って感じのソースもよく見かけるし、プログラミング手法を考える上で、一つの命令文を悪の根源みたいにいうのもどうかとおもうのですが。ほんとgoto文は見なくなりました。一応紹介します。
goto ラベル;
上記goto文が呼ばれると次の書式で記述されている”ラベル”以降に処理が移行します。
ラベル :
処理;
・サンプルソース(sample0403.c)
#include <stdio.h>
int main() {
printf("処理1実行!。\n");
goto exec3;
printf("処理2実行!。\n");
exec3 :
printf("処理3にとんで実行!。\n");
return 0;
}
※上記ソースは「printf("処理2実行!。\n");」の処理が実行される事が無いためコンパイル時に警告がでます。
・実行結果
C:\dev\c>sample0403 [Enter]
処理1実行!。
処理3にとんで実行!。
反復処理はよくループ処理とも言われています。繰り返し制御の方法が異なる次の2種類があります。
for文は「~回繰り返す」、「~回ループさせる」といった場合に使用します。書式は次の通りです。
for (ループ制御用変数の初期化 ; 終了条件 ; ループ制御用変数の増減式) {
処理;
}
または処理が1行のとき”{}”を省略して
for (ループ制御用変数の初期化 ; 終了条件 ; ループ制御用変数の増減式)
処理;
次のように書くと無限ループになります。
for ( ; ; ) {
処理;
}
・サンプルソース(sample0404.c)
#include <stdio.h>
int main() {
int i;
for ( i=1 ; i<=10 ; i++) {
printf("10回表示します。%d回目\n", i);
}
return 0;
}
・実行結果
C:\dev\c>sample0404 [Enter]
10回表示します。1回目
10回表示します。2回目
10回表示します。3回目
10回表示します。4回目
10回表示します。5回目
10回表示します。6回目
10回表示します。7回目
10回表示します。8回目
10回表示します。9回目
10回表示します。10回目
for文は「~の間繰り返す」、「~の間ループさせる」といった場合に使用します。書式は次の通りです。
while (条件式) {
処理;
}
または処理が1行のとき”{}”を省略して
while (条件式)
処理;
do { 処理; } while (条件式);
または処理が1行のとき”{}”を省略して
do 処理; while (条件式);
while (true) {
処理;
}
または
do { 処理; } while (true);
・サンプルソース(sample0405.c)
#include <stdio.h>
int main() {
int i = 10;
while (i > 0) {
i--;
printf("iが0になるまで表示します。i=%d\n", i);
}
return 0;
}
・実行結果
C:\dev\c>sample0405 [Enter]
iが0になるまで表示します。i=9
iが0になるまで表示します。i=8
iが0になるまで表示します。i=7
iが0になるまで表示します。i=6
iが0になるまで表示します。i=5
iが0になるまで表示します。i=4
iが0になるまで表示します。i=3
iが0になるまで表示します。i=2
iが0になるまで表示します。i=1
iが0になるまで表示します。i=0
for文やwhile文においてbreak文やcontinue文を使用することでループ制御またはループ内処理を中断することができます。
ループ中にbreak文が読み込まれると、そこでループ制御を終了します。
・サンプルソース(sample0406.c)
#include <stdio.h>
int main() {
int i = 10;
while (i > 0) {
i--;
if (i == 5) { /* iが5のときループ制御を終了する。 */
break;
}
printf("iが0になるまで表示します。i=%d\n", i);
}
return 0;
}
・実行結果
C:\dev\c>sample0406 [Enter] iが0になるまで表示します。i=9 iが0になるまで表示します。i=8 iが0になるまで表示します。i=7 iが0になるまで表示します。i=6 ← i=5のときループ制御を終了している。
ループ中にcontinue文が読み込まれると、そこでループ内処理を終了します。
・サンプルソース(sample0407.c)
#include <stdio.h>
int main() {
int i = 10;
while (i > 0) {
i--;
if (i == 5) { /* iが5のとき、ここでループ内処理を終了する。 */
continue;
}
printf("iが負になるまで表示します。i=%d\n", i);
}
return 0;
}
・実行結果
C:\dev\c>sample0407 [Enter] iが0になるまで表示します。i=9 iが0になるまで表示します。i=8 iが0になるまで表示します。i=7 iが0になるまで表示します。i=6 iが0になるまで表示します。i=4 ← i=5のとき出力前にループ内処理を終了している。 iが0になるまで表示します。i=3 iが0になるまで表示します。i=2 iが0になるまで表示します。i=1 iが0になるまで表示します。i=0