一週間で身につくC言語の基本

おさえておきたいプログラミングの基本

【4日目】 繰り返し処理

4-1.C言語での繰り返し処理

(1) アルゴリズムと繰り返し処理

コンピュータのプログラムの処理には、順次処理(じゅんじしょり)分岐処理(ぶんきしょり)があることはすでに述べました。ここでは、もうひとつの処理、繰り返し処理について説明します。 コンピュータのプログラムのプログラムの処理のことを、一般にアルゴリズムと言いますが、アルゴリズムは、この3つの処理によって記述されています。

(2) C言語の繰り返し処理

C言語では、繰り返し処理を記述するためにfor(フォー)文while(ホワイル)文do~while(ドゥ・ホワイル文)という3つの文が用意されています。ここではそれらについて説明します。

4-2.for文

(1) for文の基本

では、まず手始めに繰り返し処理の最も基本的な処理である、for(フォー)文について学んでいくことにしましょう。

for文は、{}で囲まれた処理を、指定した条件が満たされるまで繰り返す処理です。 繰り返し処理をループ処理ということから、for文による繰り返しを、forループとも呼びます。forループは、C言語のプログラムの中で最もよく使われる処理の一つです。しっかりと覚えておきましょう。まずは、以下のサンプルを実行してみてください。

list4-1:main.c
#include <stdio.h>

int main(int argc, char** argv) {
    int i;
    for(i = 1;i <= 5;i++){
        printf("%d ",i);
    }
    printf("\n"); 
    return 0;
}
実行結果
1 2 3 4 5

(2) for文の書式

プログラムの結果をみると、for()文の{}に囲まれた部分が5回実行されたことが分かります。しかもiが1から5に1つづつ増加していたことはわかります。ではなぜこのような結果になるのでしょう。

それを知る前に、まずはfor文の書式をみてみましょう。

for文の書式
for ( 初期化処理 ; 条件式 ; 増分処理 ){ 処理 }

これをlist4-1にあてはめてみましょう。

まず「i = 1」としていますから、最初はiの値は1から始まるわけです。

条件式はif文で用いられるものと同じもので、この場合「i <= 5」ですから、iが5以下の場合この処理は継続されるわけです。

では、増分処理には「i++」と書いてありますが、これは一体なんでしょうか?これは、インクリメントと言って、iの値を1増加させる処理なのです。

以上より、このfor文は、i=1から始めて、iを一つずつ増分させていき、iが5以下ならば{}内の処理を実行することを繰り返し、iが5より大きくなれば、ループから抜けるという処理になるのです。(図4-1)

図4-1.forループの仕組み
C言語のforループの仕組み

(3) インクリメント・デクリメント

for文では、このインクリメントおよび、デクリメントという処理をよく行います。デクリメントとは、インクリメントの反対で、変数の値を1減らす処理です。この処理を表にまとめると、以下のようになります。(表4-1)

表4-1:インクリメント・デクリメントの処理一覧
演算子 呼び名 意味 該当する演算
i++ インクリメント(後置:こうち) 変数の値を1増加させる。 i=i+1;
i+=1;
++i インクリメント(前置:ぜんち) 変数の値を1増加させる。
i-- デクリメント(後置:こうち) 変数の値を1減少させる。 i=i-1;
i-=1;
--i デクリメント(前置:ぜんち) 変数の値を1減少させる。

(4) 前置と後置

これをみると、i++と++i、i--と--iはそれぞれまったく同じ意味であるように見えます。しかし、このように前置(ぜんち)後置(こうち)があるのには、それぞれ意味があるのです。例えば、

後置と代入の処理を同時に行う
int a,i=1; a=i++;

といった処理を行うと、a,iの値は次のようになります。

後置と代入の処理を同時に行った結果
a=1 i=2

なぜこのような処理になるかというと、この処理は以下のような処理と同等だからです。

後置と代入の処理を同時に行った場合の処理の内容
a=i; i+=1;

つまり、aにiの値を代入した後にiに1を足すのです。

同様に前置でも同じ処理をしてみましょう。

前置と代入の処理を同時に行う
int a,i=1; a=++i;

といった処理を行うと、a,iの値は次のようになります。

前置と代入の処理を同時に行った結果
a=2 i=2

なぜこのような処理になるかというと、この処理は以下のような処理と同等だからです。

前置と代入の処理を同時に行った場合の処理の内容
i+=1; a=i;

これは後置が代入の後に加算を行うのに対し、前置が代入の後に加算を行うということによる違いに基づくものです。デクリメントに関しても同様です。

このような処理はかつてコンピュータの処理速度がさほど速くなかったり、メモリなどが十分になかったころ、リソースを少しでも節約するために用いられた手法です。しかし濫用するとプログラムがわかりにくくなるという欠点があります。さらに現在のコンピュータは処理スピードも早く、メモリも十分に搭載していることから、こういった処理をプログラム中で書くことはほとんどなくなりました。

(5) 様々なfor文の記述方法

これで、基本的なfor文の使い方がわかったことと思います。次に、これを用いて色々な記述方法を見てみましょう。list4-1の5行目を、表4-2のように、様々な値に変えてみましょう。

表4-2:for文の記述方法の例
記述方法 実行結果 説明
for(i = 0 ; i < 5 ; i++) 0 1 2 3 4 変数の値を1増加させる。5になるとループを抜ける
for(i = -2 ; i <= 2 ; i++) -2 -1 0 1 2 -2から2まで、値を1つずつ増加させる
for(i = 0 ; i < 10 ; i+=2) 0 2 4 8 変数の値を2づつ増加させる。10になるとループを抜ける
for(i = 5 ; i >= 1 ; i--) 5 4 3 2 1 5から1まで、値を1つずつ減少させる
for(i = 2 ; i >= -2 ; i--) 2 1 0 -1 -2 2から-2まで、値を1つずつ減少させる
for(i = 12 ; i > 0 ; i-=3) 12 9 6 3 変数の値を3づつ減少させる。0になると、ループを抜ける

この例では、intの場合をとりあげましたが、その他のデータ型でもforループを利用することは可能です。

4-3.多重ループ

(1) 多重ループとは何か

多重ループとは、繰り返し処理(ループ)構造の中に別の繰り返し構造が含まれているものです。ループの入れ子(ネスト)構造とも呼ばれます。多重ループはネストの数に応じて、二重ループ、三重ループ、・・・と呼ばれます。

多重ループは、行列の処理や2次元配列の操作など、複雑なデータ処理に活用されます。そのため、一番使用頻度が高いのが2重ループです。

(2) forの二重ループ

実際にforの二重ループ、もしくはforのネストと呼ばれる処理を作ってみましょう。この処理はforループの中に更にforループを記述する二重の処理で、よく用いられるテクニックです。

list4-2:main.c
#include <stdio.h>

//	forの二重ループ
int main(int argc, char** argv) {
	int i,j;
	for(i = 1; i<= 2; i++){
		for(j = 1; j <= 3; j++){
			printf("%d+%d=%d  ",i,j,i+j);   // 繰り返される処理
		}
		printf("\n");
        return 0;
	}
}
実行結果
1+1=2 1+2=3 1+3=4 2+1=3 2+2=4 2+3=5

このプログラムではその側の変数iのループ(2回)が、内側の変数jのループ(3回)を繰り返しています。そのため2回×3回で、6回の表示処理のループが実現しています。(表4-3)

表4-3:i,jの関係性と表示内容
回数 i j 表示内容
1 1 1+1=2
2 1+2=3
3 1+3=4
2 1 2+1=3
2 2+2=4
3 2+3=5

iが1の時、jのループで最初のループで①~②の内容が表示され、ループが終了すると改行(10行目)され、iが2になり、再びjのループが繰り返され、③~⑥の内容が表示されます。

4-3.while文

(1) while文の基本

ループ処理を行うのは、for文だけではありません。while(ホワイル)文を用いることによっても実現可能です。まずは、以下のサンプルを見てください。

list4-3:main.c
#include <stdio.h>

//	iを用いたループ
int main(int argc, char** argv) {
   int i = 0;
   while(i <= 5){	
	   printf("%d ",i);
	   i++;
   }
   printf("\n");
   return 0;
}
実行結果
0 1 2 3 4 5

(2) while文の書式

プログラムについて解説する前に、まずはwhile文の書式を見てみましょう。

whileの書式
whlie(条件式){ 処理 }

while文は、()内の条件が成り立つ間は、{}内に記述されている処理を繰り返します。

つまりlist4-3では、i<=5という条件が成り立っている間は中の処理が繰り返されることを意味します。()内で記述する条件式の記述方法は、if文の場合と同様のものです。

5行目で、iを0で初期化していますから、この段階でwhile文の条件である、「i<=5」は偽ですから、ループ処理に入ります。ループ内で、iの値を表示すると共に、i++を行うことによって、iの値が増加しています。そのため、i=6となると、i<=5という命題は正しくない、つまり「偽」となります。ループから出ます。(図4-2)(表4-4)

図4-2.whileループの仕組み
whileループの仕組み
表4-4:iと条件の関係性
i 条件式 真/偽
1 1<=5
2 2<=5
3 3<=5
4 4<=5
5 5<=5
6 6<=5

見てわかるとおり、このサンプルは、list4-1と同等の処理です。しかし、for()文と違うのは、インクリメント・デクリメントといった処理や、初期値を設定する処理がループ内に存在しないことです。

4-3.do ~ while文

(1) do ~ while文による繰り返し処理

次に、ループ処理の3つ目である、do~while(ドゥ・ホワイル)文について説明しましょう。まずは、次のサンプルを入力してください。

list4-4:main.c
#include <stdio.h>

//	iを用いたループ
int main(int argc, char** argv) {
   int i = 0;
   do{	
	   printf("%d ",i);
	   i++;
   }while(i <= 5);
   printf("\n");
   return 0;
}
実行結果
0 1 2 3 4 5

(2) do~while文の書式

実行結果は、list4-1,4-3と変わりません。

do~while文は一度{}内の処理を実行した後にwhileの後の条件を確認し、その後処理を繰り返すかを判断します。(図4-3)

図4-3.do~whileループの仕組み
do~whileループの仕組み

ここで出てくる、do~while文の書式は次の通りです。

do~whileの書式
do{ 処理 }whlie(条件式); ← whileの後にセミコロンがついている

基本的にはdo~while文は、条件式の判定が後ろについているだけで、while文と似た働きをします。ただし、こちらは、whileの後に;(セミコロン)がついていますので、注意してください。

(3) while文との違い

ここまでくると、「いったい、whileとdo~whileはどう違うのか?」という疑問をもたれる方もいることでしょう。実は、この二つには大きな違いがあるのです。まずは、以下のサンプルを実行してみてください。

list4-5:main.c
#include <stdio.h>

//	iを用いたループ
int main(int argc, char** argv) {
	int i,num;
	printf("回数を入力:");
	scanf("%d",&num);	//	キーボードからループの回数を入力
	//	whileループで実行
	printf("whileで実行\n");
	i = 1;
	while(i <= num){
		printf("*");
		i++;
	}
	printf("\n");
	//	do~whileループで実行
	printf("do~whileで実行\n");
	i = 1;
	do{
 		printf("*");
 		i++;
	}while(i <= num);
	printf("\n");
    return 0;   
}

このプログラムは、コンソールから数字を入力し、その数だけ*を表示するプログラムです。そのため、入力した値により、実行結果は異なります。まず、5を入力するとwhile、do~while共に星が5つ出ます。

実行結果1(5を入力した場合)
回数を入力:5 ← 入力してEnterキーを押す whileで実行 ***** do~whileで実行 *****

こういった場合は、while,do~while共に同じ結果になります。しかしここで0を代入すると、以下のようになります。

実行結果2(0を入力した場合)
回数を入力:0 ← 入力してEnterキーを押す whileで実行 do~whileで実行 *

whileの方は、何も表示されていません。しかし、do~whileの方は、1つだけ表示されています。

これは、whileの場合、iの値はもともと条件を満たしていないので、{}内の処理が実行されないのに対し、 do~whileの場合、まず{}の処理を実行してから条件判定をしているため、仮に条件式を満たしていなくても最低限1度は処理が実行されることによるものです。

4-4.ループの流れを変える

最後に、ループの流れを変えるbreak(ブレイク)continue(コンティニュー)の使い方を説明します。

(1) break

まずは、ループを途中から抜けるbreakから説明しましょう。次のサンプルを実行してみてください。

list4-6:main.c
#include <stdio.h>

//	breakでループを抜ける
int main(int argc, char** argv) {
    int num;
	printf("負の値で、ループから抜けます。¥n");
	while(1){
		printf("数値を入力:");
		scanf("%d",&num);
		if(num < 0){
			//	ループから抜ける処理
			break;
		}
	}
	printf("終了\n");
    return 0;   
}
実行結果
数値を入力:9 ← 入力してEnterキーを押す 数値を入力:3 ← 入力してEnterキーを押す 数値を入力:42 ← 入力してEnterキーを押す 数値を入力:-1 ← 入力してEnterキーを押す 終了

プログラムを実行すると、「数値を入力:」と言う文字が出力され、コンソールからの数値の入力待ちになります。ここに様々な数値を入力していくことになります。ここに正の数を入れる限り、同じことが繰り返されます。しかし、負の数を入れると、「終了」と表示されて、プログラムが終了します。

while(1)とすると{}内の処理は無限に繰り返されます。これは、ifやwhileの条件式は、偽の場合は0、真の場合はそれ以外の値をとるからです。

while(1)とすることにより、()内の条件がつねに成り立っているのと同じ状態になり、処理が無限に繰り返されます。

ただこういったループでも、breakがあるとループから出ることができます。このサンプルでは、入力した値が負の値の場合、12行目のbreakでループから抜けることにより処理が終了します。

(2) 無限ループ

一般に、際限なく繰り返されるループの事を無限ループと言います。

無限ループは、forでも、do~whileでもできます。いずれも、breakで出ることができます。ただ、無限ループにはこのサンプルのように故意に行うものと、意図せずにできるものがあります。

故意に用いる場合は、このプログラムのように、必要な箇所にbreakを入れて、ループから出ることができるようになります。 しかし、そうでない場合は、強制的にプログラムを終了させる必要がある場合もあります。

(3) continue

continueはループの冒頭部分に戻る処理です。次のサンプルはcontinueを使ったサンプルです。

list4-7:main.c
#include <stdio.h>

//	continueでループの先頭に戻る
int main(int argc, char** argv) {
    int i;
    for(i = 1;i <= 5;i++){
        //  iが2の時にループの先頭に戻る
        if(i == 2){
            continue;
        }
        printf("%d ",i);
    }
    printf("\n");
    return 0;   
}
1 3 4 5

これはlist4-1のforループに8~10行目の処理を追加したものです。

実行結果からわかる通り、「2」が表示されていません。これはiが2のときに9行目のcontinueでループの先頭に処理が戻るからです。

以上で、順次処理分岐処理繰り返し処理という、アルゴリズムの三大要素を記述する方法について説明しました。しかし、これだけではより複雑な実用プログラムを作るにはまだ不十分です。そこで、次からは、より複雑なプログラムを作るために必要な知識を身につけていくことにしましょう。

練習問題 : 問題4.


一週間で学べるコースの一覧
Udemy
...
2024/10/01

Udemyでも学びましょう!

一週間でわかるC言語・C++言語がオンライン講座になりました!動画音声によってさらにわかりやすくなりました!! 1講座で2つの言語を学ぶことができる上に、練習問題の回答もダウンロードできます。

Read →
Impress一週間シリーズ
1週間でC言語の基礎が学べる本
2024/10/01

書籍化された一週間シリーズ

本講座が「1週間でC言語の基礎が学べる本」として書籍化されました!サイトの内容プラスアルファでより学習しやすくなっています!Impressより発売中です!!

Read →
Impress一週間シリーズ
...
2024/10/01

書籍化された一週間シリーズ

一週間シリーズは書籍化されています。こちらもどうぞ!

Read →
プログラマーなら欲しいグッズ
プログラミンググッズ

プログラミンググッズ

快適なプログラミング環境を構築したい人々にぜひとも揃えてほしいグッズです。

Read →
制作・管理
シフトシステム株式会社

シフトシステム株式会社

このサイトはシフトシステム株式会社によって制作・管理がなされています。

Read →