C の for ループは柔軟にできている。初期設定部でループ変数を初期化しなくてもいいし、インクリメント部でインクリメントしなくてもいい。他にもいろいろな書き方ができる。例を見ながら試してみよう。
条件判定部にループ変数以外を使う例
#include
int main(void)
{
    int i;
    char ch;
    ch = 'a';
    for (i = 0; ch != 'q'; i++) {
        printf("Times: %d\n", i);
        ch = getchar();
    }
    return 0;
}
実行例:
takatoh@nightschool $ ./sample_3_3a Times: 0 a Times: 1 Times: 2 b Times: 3 Times: 4 q
なんか思ったのと違うな……ああ、そうか。文字を取得するのに getchar() を使ってるから入力した a とか b のほかに改行文字を取得してループが回ってるのか。たぶん getche() を使えればこうはならないんだろう。
初期設定部が空の例
for 文の中の式は空でもいい。次の例では、初期値を入力から受け取っているので、for の初期設定部が空になっている。
#include
int main(void)
{
    int i;
    printf("Input positive integer: ");
    scanf("%d", &i);
    for (; i; i--) {
        printf("%d\n", i);
    }
    return 0;
}
実行例:
takatoh@nightschool $ ./sample_3_3b Input positive integer: 5 5 4 3 2 1
ターゲットが空の例
ターゲット(for ループで実行する文)が空でもいい。次の例では q が入力されるまでループが回り続ける。初期設定部とインクリメント部で入力を受け付けているのにも注目。
#include
int main(void)
{
    int ch;
    for (ch = getchar(); ch != 'q'; ch = getchar()) {
        ;
    }
    return 0;
}
実行例:
takatoh@nightschool $ ./sample_3_3c a b x q
無限ループ
初期設定部、条件判定部、インクリメント部をすべて空にすると無限ループになる。条件判定部に式がないと、コンパイラはそれを真と仮定するようだ。
for ( ; ; ) {
    ....
}
インクリメントをターゲット内で行う例
ループ変数をインクリメント部以外で変更しても構わない。次の例ではターゲット内で変更しているため、インクリメント部が空になっている。
#include
int main(void)
{
    int i;
    for (i = 0; i < 10; ) {
        printf("%d\n", i);
        i++;
    }
    return 0;
}
実行例:
takatoh@nightschool $ ./sample_3_3d 0 1 2 3 4 5 6 7 8 9