今まで、プログラムの流れは上から下に流れていくだけでした。これでは、ゲームのような、同じ事を繰り返して処理の実装は出来ません。C言語にはいくつかのループを実現するための命令が用意されています。今回は盛りだくさんですので、是非、VS2022 でステップトレースをするなどで動作を確認してみてください。
※ キーボードは使ってて楽しいのが良い♪
※ 品質が高いのは意外にも(当然?)ゲーミングキーボード。これはテレビで紹介された事もある秀逸な製品です。
昇順ループはカウンタ変数である num の値が 0,1,2,3...9 と増えていきますが、降順ループでは 9,8,7,6...0 と数値が減っていきます。結果としてはどちらも同じです。余談ですが昔の Cコンパイラは降順ループの方が少しだけ高速に動作しました。今は全く認知できませんので、通常は昇順ループで良いと思います。
--
いきなりここに飛んで来ちゃった人は、よろしければ下記からご覧ください。
- while は前判定
まずは基本の構文を示します。
while (真偽) { 処理(スコープ内) }
これが基本形です。while の括弧に真偽とあります。多くの解説では、ここに条件式と書いてあるのが殆どですが、そう覚えてしまうと後で苦労するかもしれません。条件式は、その判定の結果を真偽で返却します。if 等はその結果である真偽によって、動作を変えていましたよね。このループ判定も同様です。括弧の中が真の状態であればスコープ内をループし続けます。
ここで少し復習ですが、真偽って数値的には 0 が偽の状態で、それ以外は真でしたよね?そのため、以下のような書き方をするとどうなるでしょうか。
while (1) { 処理(スコープ内) }
そう、真の状態が不変になりますので無限ループします。実は初期のゲーム制作では、メインループはこのように作られていた事が多かったです。Esc キーを押したらループから抜けるには…
while (Escキーが押されていない) { 処理(スコープ内) }
このような処理を括弧内に記述すれば実現してしまいます。では、以下はどうでしょうか。
while (0) { 処理(スコープ内) }
いきなり真偽判定で偽である 0 が記述されています。この場合は、処理(スコープ内)は全く通りません。この書き方を実際にプログラム内で書く事は殆ど無いと思いますが、一度も通らないという処理の流れについては理解しておいてください。
このようにスコープが始まる前にループの条件判定を行っているので、前判定と呼ばれています。
このようにスコープが始まる前にループの条件判定を行っているので、前判定と呼ばれています。
- do ~ while は後判定
最低でも一度は処理を通したい場合は、while ループではなく、do ~ while ループを使います。基本の構文は以下の通りです。
do { 処理(スコープ内) } while (真偽);
この書き方であれば、必ず一度はループ範囲内の処理を通ります。無限ループは、while でを記述するのが一般的です。do ~ while は使う機会は少ないかもしれません。
スコープの後でループ判定を行っているので、後判定と呼ばれています。
スコープの後でループ判定を行っているので、後判定と呼ばれています。
Logicool(ロジクール)
2022-08-04
- for はループ回数を指定できる
条件が成立し続けると、結果として真となるためループし続けます。それを利用して、例えば10回ループをさせたい場合は…
int num = 0; while (num < 10) { 処理(スコープ内) ++num; }
このように記述すると、10回ループを実現できます。ですが、回数指定のループというのはよく使う処理だったりします。そのためか、C言語ではループ回数を指定する専用命令が用意されています。それが for です。まずはループの基本構文を示します。
for (初期化; 真偽判定; 後処理) { 処理(スコープ内) }
この for を使って、先ほどの 10回ループを記述すると以下のようになります。
int num; for (num = 0; num < 10; ++num) { 処理(スコープ内) }
新しいバージョンの C言語だと、初期化部分で変数宣言が出来ます。その場合は…
for (int num = 0; num < 10; ++num) { 処理(スコープ内) }
このように、もっとシンプルに記述する事が出来ます。さて、この for ですが、実は初期化、真偽判定、後処理の各場所には文法エラーにならない範囲であれば、何を記述しても通ります。例えば…
int num = 0; for (printf("始まる\n"); num < 10; scanf_s("%d", &num)) { printf("今の数値は%dです。\n", num); } printf("終わった\n");
こんな見づらい書き方ですら以下のように実行できてしまうのです。

先にも示したとおり、for とは while を補完する命令です。複数行にまたがる処理を完結に記述できるようにした命令と言えるので、こんな書き方でも実行できてしまいます。ただ、上記のような書き方はあくまでも「出来る」と示しただけで、このような書き方を推奨しているわけではないです。上記のような処理は、下記のような書き方が適切と考えます。

先にも示したとおり、for とは while を補完する命令です。複数行にまたがる処理を完結に記述できるようにした命令と言えるので、こんな書き方でも実行できてしまいます。ただ、上記のような書き方はあくまでも「出来る」と示しただけで、このような書き方を推奨しているわけではないです。上記のような処理は、下記のような書き方が適切と考えます。
int num = 0; printf("始まる\n"); while (num < 10) { printf("今の数値は%dです。\n", num); scanf_s("%d", &num); } printf("終わった\n");
Logicool(ロジクール)
2018-07-05
- for ループの昇順と降順
同じ 10回ループでも、大きく分けて2通りの方法があります。それがカウンタ変数が大きくなっていく昇順ループと、カウンタ変数の値が小さくなっていく降順ループです。それぞれのサンプルを示します。
昇順ループ
昇順ループ
for (int num = 0; num < 10; ++num) { 処理(スコープ内) }
降順ループ
for (int num = 10 - 1; num >= 0; --num) { 処理(スコープ内) }
昇順ループはカウンタ変数である num の値が 0,1,2,3...9 と増えていきますが、降順ループでは 9,8,7,6...0 と数値が減っていきます。結果としてはどちらも同じです。余談ですが昔の Cコンパイラは降順ループの方が少しだけ高速に動作しました。今は全く認知できませんので、通常は昇順ループで良いと思います。
降順ループの変数の初期化で 10 - 1 と記述しているのは、10回ループと言う事を分かりやすくしているためです。読者の中にはもしかすると・・・
for (int num = 10; num > 0; --num) { 処理(スコープ内) }
こう書けば良いのでは無いかと思う人もいるかと思います。実際、num の値に意味が無い場合は、この書き方で構いません。ですが、このカウンタ変数をインデックスとして扱う場合は、この書き方だと 0 まで変数の値が変化しないので使いづらいのです。
※ インデックスってのはなんなの?ってのは、後日解説する予定の配列までお待ちください。
- ループの応用
さて、ここでかなり特殊な使い方になりますが、ループの応用も示しましょうか。これ、何をしているか理解できますでしょうか?
int posX = 20; int posY = 5; printf(SCRCLEAR); for (int i = 0; i < posY; ++i) { printf(LF); } for (int i = 0; i < posX; ++i) { printf(" "); } printf("●");
※ include "Define.h" を使用しています。
printf(LF); はカーソル位置を1行下げてます。printf(" "); はスペースを表示する事でカーソルを右側に移動しています。そう、ループを使えば、カーソル位置を任意の場所に移動させる事も出来てしまうのです、実行するとこのように右に20キャラ、下に5行ズレた位置に●が表示されます。

この例では1つしか表示できないので実用的ではありませんが、任意の数をループにすれば、このような制御も可能と言う事をお伝えしたかったのです。エスケープシーケンスには、そもそも位置を指定する LOCATE がありますので、

この例では1つしか表示できないので実用的ではありませんが、任意の数をループにすれば、このような制御も可能と言う事をお伝えしたかったのです。エスケープシーケンスには、そもそも位置を指定する LOCATE がありますので、
printf(LOCATE, posY, posX);
このように記述するだけでカーソル移動は実現できてしまいますが、機能が無いからと諦めず、現時点で出来る事を組み合わせる事で、意外な事も出来る・・・という事をお伝えして、今回のループに関しては〆とします。お疲れ様でしたー
※ 冬場、キーボードやマウスを使っていると指先から冷えてきませんか。これを使うと本当に暖かいです!
NOSCH
コメント