for文 3種類の繰り返し文の中の最後,for文を見ましょう。
■for文(for Statement)
for ( 式1 ; 式2 ; 式3 ) 文
条件式2 はスカラ型に限る。
for文は,式1 を最初に評価し,式2 が真であれば 文 を実行後 式3 を評価します。式1 が繰り返しの初期条件,式2 が繰り返す条件,そして 式3 が条件変更と解釈できます。while文で書き直すと,
式1;
while(式2)
{
文
式3
}
となります。
/* Example 14.7 */
#include <stdio.h>
int main(void)
{
int sum = 0, x[6] = {0}, *p = NULL;
printf("Input integers: ");
scanf("%d%d%d%d%d", x, x + 1, x + 2, x + 3, x + 4);
for(p = x; *p; p++)
sum += *p;
printf("sum = %d\n", sum);
return 0;
}
これは Example 14.5 の while文を for文で書き直したものです。実行結果は同じになります。
次の例は,文字列 str[] を文字列 key[] で分割し,それをポインタの配列 *s[] に格納するものです。
/* Example 14.8 */
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[] = "ABCD\tabc\t123";
char key[] = "\t";
char *s[10];
char **z;
z = s;
*z = strtok(str, key);
++z;
for ( ; (*z = strtok(NULL, key)); z++);
for (z = s; *z; z++)
printf("%s\n", *z);
return 0;
}
実行結果は次の通りです。文字列 ABCD\tabc\t123 がタブ \t で分割されている様子が分かるかと思います。
ABCD abc 123
ここでは,NULLポインタで for 文の繰り返しから抜けます。strtok 関数はヘッダファイル string.h に入っている関数で,第1変数の文字列から第2変数の文字列が現れるまでの文字列を返します。もしこの処理に失敗すると NULLポインタを返します。成功すれば,残りの文字列から探索します。strtok 関数のソースファイル(原物)は,練習問題で取り上げますので,そこで動作を確認してください。
次の例は 3 から 100 の間の自然数から素数を抽出するプログラムです。3 からの数を順番に素数であるものを int 型配列 p に格納します。for文と論理演算子を組み合わせて素数で割り切れる数をスキップします。また,100 の中から 2 を除く素数を抽出するので配列 p のサイズは 50 としています。素数 2 は抽出しないことを前提にしている訳です。(2 も抽出するプログラムは読者自身で考えてください。また,理論的には unsigned long long を使って 264 までの素数を計算できますが,メモリ消費や処理に無駄のあるプログラムです。)
/* Example 14.9 */
#include <stdio.h>
int main(void)
{
int n;
int p[50] = {2};
int *v;
for (n = 3; n <= 100; n++)
{
for (v = p; *v && (n % *v); v++);
if (!*v)
*v = n;
}
for (v = p; *v; v++)
printf("%d ", *v);
putchar('\n');
printf("number of prime numbers = %td\n", v - p);
return 0;
}
実行結果です。
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 number of prime numbers = 25