連載
» 2014年08月21日 11時00分 公開

完全マスター! 組み込みC言語プログラミング(9):【問題8】繰返しと配列は相性がいい (2/2)

[横田一弘 埼玉県立新座総合技術高等学校 教諭,MONOist]
前のページへ 1|2       

問題8の解説

 それでは、lifo.cについて解説しましょう。以下にlifo.cのフローチャートを示します。

photo lifo.cのフローチャート

 プログラムは2つのループで構成されます。1つ目のループは「入力ループ」と呼べるもので、キーボードから入力された整数を配列dataに格納します。2つ目のループは「出力ループ」と呼べるもので、dataに格納された整数をディスプレイに表示します。

 「入力ループ」では入力scanfが2か所現れます。「入力ループ」の繰り返しの条件は、「負数が入力されるまで」なので、負数を入力する分1回多くscanfを実行しなければなりません。このようなプログラムでは、ループの前で1度scanf(先頭のデータ入力)し、ループの最後でscanf(次のデータ入力)するのがプログラミングの定石です。

 もしscanfを1つにしたいならば、

i = 0;
while (1) {     /* 無限ループ */
    printf("数を入力してください->");
    scanf("%d", &n);
    if (n < 0) break;
    data[i] = n;
    i++;
}

 とも書けますが、ループの途中でループを抜ける(break)のは、できれば避けたいものです。

 「入力ループ」を抜けた段階で、iには入力されたデータの個数が入っています。そして、例えば5個の整数が入力された場合では、data[0]に最初のデータが、data[4]に最後のデータが保持されます。「出力ループ」では最後のデータから出力しなければならないので、iを減じた後にdata[i]を表示しているのです。

ポストインクリメントとプリデクリメント

 lifo.cは、次のlifo2.cようにも書くことができます。

#include <stdio.h>
 
int main(void)
{
   int n, i, data[100];
   printf("数を入力してください->");
   scanf("%d", &n);
   i = 0;
   while (n >= 0) {
       data[i++] = n;
       printf("数を入力してください->");
       scanf("%d", &n);
   }
    while (i) printf("%d\n", data[--i]);
}
「lifo2.c」

 lifo.cとlifo2.cは全く同じプログラムですが、iのインクリメント演算子(++)とデクリメント演算子(--)の書き方を変えてみました。lifo.cとの違いは、++と--が文の中に入れ込まれていることです。

 「入力ループ」の

data[i++] = n;

 では、添字に++が記述されています。

 ++の働きは、「演算対象(オペランド)に1加算」ですが、実はオペランドの前にも後ろにも書くことができます。

 上の例のように++がiの後ろに書かれている場合、ポストインクリメント(後置増分)と呼び、オペランドの値を取り出した後、オペランドの値を増分します。ここではdataの添字にiを指示した後iに1加えます。

 --も同じように扱うことができ、「出力ループ」の

printf("%d\n", data[--i]);

 では、--がiの前に書かれているので、プリデクリメント(前置減分)と呼び、オペランドの値を減分した後、オペランドの値を取り出します。ここではiを1減じた後、dataの添字とします。

 以上のように、++と--は細かい処理が記述できます。

問題9

 それでは、次回の宿題です。

問題9:

「問題8」のプログラムを、添字の代わりにポインタを使って書いてみましょう。


⇒解答と解説は次回



前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.