第06回 繰り返し:for文
前回の復習
- while文による繰り返し
- [条件式] は 継続条件 であり、[条件式] が真である限り繰り返しを継続することに注意しましょう。
- ふりがな表
- 1回やったことは必ずできるようになっておくこと!
繰り返し:for文
while文と異なるもう一つの繰り返し構文はfor文です。 for文では、繰り返しを行う前の [初期化処理] と [処理] を繰り返す度に行う [更新処理] が加わります。 for文の読み下し文は以下の通りです。
表記 | ふりがな |
---|---|
for ( [初期化処理] ; [条件式] ; [更新処理] ) { [処理] } |
[初期化処理] [条件式] が真である限り以下を繰り返せ { [処理] [更新処理] } |
while文と同じように、for文の実行順序に注意しましょう。 はじめに [初期化処理] が実行されます。 次に [条件式] が評価され、[条件式] が真であれば [処理] が実行されます。 その後、[更新処理] を行い、[条件式] の評価に戻り繰り返しを行います。 [条件式] が真でなくなれば繰り返しを脱出します。 for文の実行順序は、 [初期化処理] → [条件式] → [処理] → [更新処理] → [条件式] → [処理] → [更新処理] → … → [条件式] → [処理] → [更新処理] → [条件式] となります。
例
以下のプログラムで、for文の実行順序を確認しましょう。 プログラムの開始から終了までの間に(1)〜(6)の箇所を通る順に並べてみましょう。 同じ番号のところが複数回出現します。
for (int i = 0 /* (1) */ ; i < 3 /* (2) */ ; i += 1 /* (3) */) {
println(i); /* (4) */
}
println("finish"); /* (5) */
まず、プログラムを理解するために読み下し文を作成しましょう。 読み下し文は以下の通りになります。
整数型の変数iを作成し、整数0で初期化しろ
変数iの値が整数3より小さいの真偽が真である限り以下を繰り返せ
{
変数iの値を表示しろ
変数iの値に整数1を足した結果を変数iに代入しろ
}
文字列「finish」を表示しろ
プログラムの実行結果は以下の通りになります。
0
1
2
finish
プログラムの実行にあたって、処理の実行順序は以下の通りとなります。
(1)
(2)
(4)
(3)
(2)
(4)
(3)
(2)
(4)
(3)
(2)
(5)
授業内課題06-1
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。
for (int i = 1; i <= 9; ++i) {
print("\t" + i);
}
println();
for (int i = 1; i <= 9; ++i) {
print(i);
for (int j = 1; j <= 9; ++j) {
print("\t" + i * j);
}
println();
}
授業内課題06-2
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。
size(400, 400);
int numBalls = 5;
int ballWidth = width / numBalls;
int ballHeight = height / numBalls;
for (int i = 0; i < numBalls; ++i) {
for (int j = 0; j < numBalls; ++j) {
if ((i + j) % 2 == 0) {
fill(0, 0, 0);
} else {
fill(255, 255, 255);
}
ellipse(ballWidth * i + ballWidth / 2, ballHeight * j + ballHeight / 2, ballWidth, ballHeight);
}
}
授業内課題06-3
(1) プログラムの先頭で、整数型変数nを1以上10以下の整数で初期化し、nの階乗(= 1 2 3 ... n)の値を出力するプログラムを作成せよ。 (2) また、完成したプログラムの読み下し文を書け。
10の階乗の値は3628800である。
授業内課題06-4
(1) コインを投げた時の裏表を乱数で表し、100回コインを投げて表が出た回数を表示するプログラムを作成せよ。 (2) また、完成したプログラムの読み下し文を書け。
for文とwhile文
[初期化処理] と [更新処理] を除けば、for文の読み下し分はwhile文の読み下し文と全く同じです。 実際に、以下のfor文とwhile文は(ほぼ)同じ処理を行います。
for ( [初期化処理] ; [条件式] ; [更新処理] ) {
[処理]
}
[初期化処理]
while ( [条件式] ) {
[処理]
[更新処理]
}
具体的なプログラムで表すと以下のようになります。
for (int i = 0; i < 10; i += 1) {
println(i);
}
int i = 0;
while (i < 10) {
println(i);
i += 1;
}
for文とwhile文のどちらでも同じような処理が可能です。 初期化処理、更新処理が複雑な場合などはwhile文の方がわかりやすいでしょう。 for文とwhile文のどちらを使う方がわかりやすいかを考え、適切に使い分けましょう。
授業内課題06-5
以下の3つのプログラムをfor文を用いて書き直せ。
float p = random(1);
while (p >= 0.1) {
println("外れ");
p = random(1);
}
println("当たり");
size(800, 400);
int x = 0;
int y = height / 2;
int w = 60;
while (x < width) {
ellipse(x + w / 2, y, w, w);
x += w;
}
size(400, 400);
int y = 0;
int d = 60;
while (y < height) {
int x = 0;
while (x < width) {
ellipse(x + d / 2, y + d / 2, d, d);
x += d;
}
y += d;
}
授業内課題06-6
以下のプログラムを繰り返しを用いて書き直せ。
size(400, 400);
background(0, 0, 0);
fill(0, 0, 0);
stroke(255, 255, 0);
float cx = width / 2;
float cy = height / 2;
float r = width / 2;
ellipse(cx, cy, 2 * r, 2 * r);
float theta = 270;
float dTheta = 360 / 5 * 2;
float x1, y1, x2, y2;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
まとめ
- for文による繰り返し
- while文との違い・共通点を意識して使い分けましょう。
- 次回は授業内テストに向けた演習を行います。
- 試験と同じ状況で40分。
- 範囲はこのクラスでのこれまでの内容全てです。
- 持ち込みPCを使用
- ネットの閲覧可。ただしメールやチャット等のコミュニケーションは不可。
- メモ用紙と筆記用具の持ち込み推奨
解答例
授業内課題06-1
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。
for (int i = 1; i <= 9; ++i) {
print("\t" + i);
}
println();
for (int i = 1; i <= 9; ++i) {
print(i);
for (int j = 1; j <= 9; ++j) {
print("\t" + i * j);
}
println();
}
読み下し文
整数型の変数iを作成して、整数1で初期化しろ
変数iの値が整数9以下の真偽が真である限り以下を繰り返せ
{
文字列「\t」に変数iの値を足した結果を表示しろ
変数iの値を1増やせ
}
改行しろ
整数型の変数iを作成して、整数1で初期化しろ
変数iの値が整数9以下の真偽が真である限り以下を繰り返せ
{
整数型の変数jを作成して、整数1で初期化しろ
変数iの値を表示しろ
変数jの値が整数9以下の真偽が真である限り以下を繰り返せ
{
文字列「\t」に変数iの値に変数jの値を掛けた結果を足した結果を表示しろ
変数jの値を1増やせ
}
改行しろ
変数iの値を1増やせ
}
実行結果
1 2 3 4 5 6 7 8 9
1 1 2 3 4 5 6 7 8 9
2 2 4 6 8 10 12 14 16 18
3 3 6 9 12 15 18 21 24 27
4 4 8 12 16 20 24 28 32 36
5 5 10 15 20 25 30 35 40 45
6 6 12 18 24 30 36 42 48 54
7 7 14 21 28 35 42 49 56 63
8 8 16 24 32 40 48 56 64 72
9 9 18 27 36 45 54 63 72 81
授業内課題06-2
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。
size(400, 400);
int numBalls = 5;
int ballWidth = width / numBalls;
int ballHeight = height / numBalls;
for (int i = 0; i < numBalls; ++i) {
for (int j = 0; j < numBalls; ++j) {
if ((i + j) % 2 == 0) {
fill(0, 0, 0);
} else {
fill(255, 255, 255);
}
ellipse(ballWidth * i + ballWidth / 2, ballHeight * j + ballHeight / 2, ballWidth, ballHeight);
}
}
読み下し文
画面の幅を 整数400 に、高さを整数400 に設定しろ
整数型の変数numBallsを作成して、整数5で初期化しろ
整数型の変数ballWidthを作成して、Windowの幅を変数numBallsの値で割った結果で初期化しろ
整数型の変数ballHeightを作成して、Windowの高さを変数numBallsの値で割った結果で初期化しろ
整数型の変数iを作成して、整数0で初期化しろ
変数iの値が変数numBallsの値より小さいの真偽が真である限り以下を繰り返せ
{
整数型の変数jを作成して、整数0で初期化しろ
変数jの値が変数numBallsの値より小さいの真偽が真である限り以下を繰り返せ
{
もし変数iの値に変数jの値を足した結果を整数2で割った余りが0と等しいの真偽が真ならば以下を実行しろ
{
塗り潰し色を( 整数0 , 整数0 , 整数0 )に設定しろ
}
そうでなければ以下を実行しろ
{
塗り潰し色を( 整数255 , 整数255 , 整数255 )に設定しろ
}
中心の座標を( 変数ballWidthの値に変数iの値を掛けた結果に変数ballWidthの値を整数2で割った結果を足した結果 , 変数ballHeightの値に変数jの値を掛けた結果に変数ballHeightの値を整数2で割った結果を足した結果 )とした幅変数ballWidthの値、高さ変数ballHeightの値の楕円を描画しろ
変数jの値を1増やせ
}
変数iの値を1増やせ
}
実行結果
授業内課題06-3
(1) プログラムの先頭で、整数型変数nを1以上10以下の整数で初期化し、nの階乗(= 1 2 3 ... n)の値を出力するプログラムを作成せよ。 (2) また、完成したプログラムの読み下し文を書け。
10の階乗の値は3628800である。
解答例
int n = 10;
int f = 1;
for (int i = 2; i <= n; ++i) {
f *= i;
}
println(f);
読み下し文
整数型の変数nを作成し、整数10で初期化しろ
整数型の変数fを作成し、整数1で初期化しろ
整数型の変数iを作成し、整数2で初期化しろ
変数iの値が変数nの値以下の真偽が真である限り以下を繰り返せ
{
変数fの値に変数iの値を掛けた結果を変数fに代入しろ
変数iの値を1増やせ
}
変数fの値を表示しろ
授業内課題06-4
(1) コインを投げた時の裏表を乱数で表し、100回コインを投げて表が出た回数を表示するプログラムを作成せよ。 (2) また、完成したプログラムの読み下し文を書け。
解答例
int count = 0;
for (int i = 0; i < 100; ++i) {
if (0.5 < random(1)) {
count++;
}
}
print(count);
読み下し文
整数型の変数countを作成し、整数0で初期化しろ
整数型の変数iを作成し、整数0で初期化しろ
変数iの値が整数100より小さいの真偽が真である限り以下を繰り返せ
{
もし実数0.5が0以上整数1未満の乱数より小さいの真偽が真ならば以下を実行しろ
{
変数countの値を1増やせ
}
変数iの値を1増やせ
}
変数countの値を表示しろ
授業内課題06-5
以下の3つのプログラムをfor文を用いて書き直せ。
float p = random(1);
while (p >= 0.1) {
println("外れ");
p = random(1);
}
println("当たり");
size(800, 400);
int x = 0;
int y = height / 2;
int w = 60;
while (x < width) {
ellipse(x + w / 2, y, w, w);
x += w;
}
size(400, 400);
int y = 0;
int d = 60;
while (y < height) {
int x = 0;
while (x < width) {
ellipse(x + d / 2, y + d / 2, d, d);
x += d;
}
y += d;
}
解答例
for (float p = random(1); p >= 0.1; p = random(1)) {
println("外れ");
}
println("当たり");
size(800, 400);
int y = height / 2;
int w = 60;
for (int x = 0; x < width; x += w) {
ellipse(x + w / 2, y, w, w);
}
size(400, 400);
int d = 60;
for (int y = 0; y < height; y += d) {
for (int x = 0; x < width; x += d) {
ellipse(x + d / 2, y + d / 2, d, d);
}
}
授業内課題06-6
以下のプログラムを繰り返しを用いて書き直せ。
size(400, 400);
background(0, 0, 0);
fill(0, 0, 0);
stroke(255, 255, 0);
float cx = width / 2;
float cy = height / 2;
float r = width / 2;
ellipse(cx, cy, 2 * r, 2 * r);
float theta = 270;
float dTheta = 360 / 5 * 2;
float x1, y1, x2, y2;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
解答例
size(400, 400);
background(0, 0, 0);
fill(0, 0, 0);
stroke(255, 255, 0);
float cx = width / 2;
float cy = height / 2;
float r = width / 2;
ellipse(cx, cy, 2 * r, 2 * r);
int n = 5;
float theta = 270;
float dTheta = 360 / n * 2;
float x1, y1, x2, y2;
for (int i = 0; i < n; ++i) {
x1 = cx + r * cos(radians(theta));
y1 = cy + r * sin(radians(theta));
x2 = cx + r * cos(radians(theta + dTheta));
y2 = cy + r * sin(radians(theta + dTheta));
line(x1, y1, x2, y2);
theta += dTheta;
}
授業外課題
授業外課題06-1
寿司打( http://neutral.x0.com/home/sushida/play2.html )「5000円コース」をプレイし、以下のスコアを報告せよ(スピードは任意)
- 成績(xxx円分得 or 損した)
- 正しく打ったキーの数
- 平均キータイプ数(回 / 秒)
- ミスタイプ数
授業外課題06-2
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。 また、(3) 何をしているプログラムか説明せよ。
int n = 504;
for (int i = 2; n != 1; i++) {
while (n % i == 0) {
println(i);
n /= i;
}
}
授業外課題06-3
以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。
size(400, 400);
int h = height / 2;
float d = TWO_PI / width;
for (int x = 1; x < width; x++) {
int x0 = x - 1;
int y0 = int(sin((x - 1) * d) * h + h);
int y = int(sin(x * d) * h + h);
line(x0, y0, x, y);
}
授業外課題06-4
プログラムの先頭で整数型の変数cを1以上の値(自然数)で初期化し、a * a + b * b = c * cとなる自然数a, b(a <= b)を全て出力せよ。c = 325の時の出力例は以下の通りである。出力順は問わない。
204 253
195 260
165 280
125 300
91 312
80 315
36 323
授業外課題06-5
下図のように、画面内を同じ大きさの正方形で敷き詰め、下図のような模様が現れるように描画するプログラムを作成せよ。i行j列目の色のパターンに注目すること。
画面幅400、高さ400、正方形の一辺40の結果
画面幅400、高さ400、正方形の一辺10の結果
画面幅800、高さ400、正方形の一辺40の結果