cp
-
5.
繰り返し計算
(
C
プログラミング入門)
URL
:
https://www
.kkaneko.jp/pro/adp/index.html
1
金子邦彦
内容
例題1.最大公約数
の計算
例題2.自然数の和
while
文
例題3.フィボナッチ数列
例題4.自然数の和
for
文
例題5.九九の表
繰り返しの
入れ子
2
目標
•
繰り返し
(
while
文
, for
文)
を使って,繰り返
し計算を行える
よ
う
になること
•
ループカ
ウ
ンタと
して,整数の
変数を
使
う
こ
と
•
今回も,見やすいプ
ログラムを書く
ために,
ブロック単位での字
下げを行
う
3
繰り返しとは
•
繰り返しとは,ある条件が満たされるまで,
同じことを繰り返す
こと.
•
繰り返しを行
う
ための文として
while
文
, for
文
などがある.
条件
4
繰り返しの例
•
ユークリッドの互
助法
•
m
と
n
の
最大公約数を求めるため
に,「割った余りを
求めること」
を,余りが0にな
るまで繰り返す
.
•
九九の表
•
九九の表を求
めるために,掛け
算を81回繰り
返す
•
フィボナッチ数
•
フィボナッチ数を求
めるため
に,
f(n)=f(n-1)+f(n-
2)
を,
n
に達するまで
繰り返す
など
5
例題1.最大公約数の計算
•
2つの整数データを読み込んで,最大公約数を求
めるプログラムを作
る.
•
ユークリッドの互助法を用いること
•
ユークリッドの互助法を行
う
ために
wh
ile
文を書く
例)
20, 12
のとき:
4
6
ユークリッドの互助法
•
最大公約数を求める
ための手続き
•
m,n
の最大公約数は,
•
m
≧
n
とすると,
•
「
m
を
n
で割った余り」
= 0
なら
,最大公約数は
n
•
「
m
を
n
で割った余り」
≠
0
なら
,
m
と
n
の最大公約
数は,
「
m
を
n
で割った余り」
と
n
の最大公約数に
等しい
(
なお,
n
>
「
m
を
n
で割った余り」
が成り
立つ)
7
#include <stdio.h>
#pragma warning(disable:4996)
int
main()
{
int
r;
int
m;
int
n;
printf("m=");
scanf("%d", &m);
printf("n=");
scanf("%d", &n
);
r = m
% n;
while( r != 0 ){
m = n;
n = r;
r = m % n;
}
printf
("
GCD
=%d
\n",
n);
return 0;
}
条件が成り立つ限り,
実行されつづける部分
条件式
8
ユークリッド
の互助法
実行結果の例
m=12
n=8
GCD
=4
9
プログラム実行順
r = m % n;
r != 0
m = n;
n = r;
r = m % n;
Y
es
No
10
ユークリッドの互助法
最初の「
r = m %
n;
」で,
m = 80,
n = 35
とすると
,
r = 10
になる
r != 0
が成立する
m = 35
n = 10
r = 5
r != 0
が成立する
m = 10
n = 5
r = 0
r != 0
が成立しない
繰り返し
1回目
繰り返し
2回目
繰り返し
3回目
m
の値
n
の値
r
の値
11
while
文
•
何かの処理の繰り返
し
•
繰り返しのたびに
while
文で書かれた
条件式
の真偽が判定
され,
真である限り
,
while
の
あとに続く文が実行
され続ける.
while (
条件式
) {
式
1;
式
2;
..
.
}
条件式
式
1
式
2
...
Y
es
No
12
例題2.自然数の和
•
整数データ(Nとする)を読み込んで,1からN
までの和を求めるプ
ログラムを作る
•
ここでは,練習のた
め,自然数の和の公式は使
わ
ずに,
while
文を用いる
例)
100 → 5050
13
自然数の和
#include <stdio.h>
#pragma
warning(disable:4996)
int
main()
{
int
i;
int
n;
int
sum;
printf("n=");
scanf("%d",
&n);
sum =
0;
i
= 1;
while( i<=n )
{
sum =
sum
+ i;
i
=
i
+ 1;
}
printf("n=%d,
sum=%d\n",
n,
sum);
return 0;
}
条件が成り立つ限り,
実行されつづける部分
条件式
14
自然数の和
実行結果の例
n=100
n=100,
sum=5050
15
プログラム実行順
i
= 1;
i
<= n
sum = sum + 1;
i
=
i
+ 1;
Y
es
No
16
自然数の和
n = 7
とすると
i
<= 7
が成立する
sum
= 0 + 1
i
<= 7
が成立する
sum
= 1 + 2
i
<= 7
が成立する
sum
= 3 + 3
i
<= 7
が成立する
sum
= 6 + 4
i
<= 7
が成立する
sum
= 10 + 5
i
<= 7
が成立する
sum
= 15 + 6
i
<= 7
が成立する
sum
= 21 + 7
i
<= 7
が成立しない
1から
「繰り返し
数」の和
i
= 2
i
= 3
i
= 4
i
= 5
i
= 6
i
= 7
i
= 8
「繰り返し数」+
1
繰り返し
1回目
繰り返し
2回目
繰り返し
3回目
繰り返し
4回目
繰り返し
5回目
繰り返し
6回目
繰り返し
7回目
繰り返し
8回目
sum
の値
i
の値
17
•
整数(Nとする)を
読み込んで,1からNま
でのフィボナッチ数列を求めるプログラムを
作る.
•
フィボナッチ数列
f(n)
とは
f(0)=1, f(1)=1,
f(n)=f(n-1)+f(n-
2)
•
フィボナッチ数列を求めるために
for
文を使
う
例)
1,1,2,3,5,8,13,21,34,55,89,144,...
.
18
例題3.フィ
ボナッ
チ数列
#include <stdio.h>
#pragma
warning(disable:4996)
int
main()
{
int
i;
int
n;
int
fn
;
int
fn1
;
int
fn2;
printf("n=");
scanf("%d",
&n);
fn1
=
1;
fn2
=
1;
for (i=2;
i<=n;
i++)
{
fn
=fn1+fn2;
fn2=fn1
;
fn1=
fn
;
printf("f(%d)
= %d\
n", i
, fn
);
}
return 0;
}
順番に意味がある.
fn1
=
fn
;
fn2=fn1
;
とはしないこと
条件が成り立つ限り,
実行されつづける部分
条件式
19
フィボナッチ
数列
実行結果の例
n=6
f(2) = 2
f(3) = 3
f(4) = 5
f(5) = 8
f(6) = 13
20
フィボナッチ数列
i
= 2
i
<= n
fn=fn1+fn2;
fn2=fn1
;
fn1
=
fn
;
printf("f(%d) = %d\n", i,
fn
);
i
++
Y
es
No
21
フィボナッチ数列
n = 5
とすると
i
= 2
i
<= 5
が成立する
fn
= 1 + 1; fn2
= 1; fn1
= 2
i
= 3
i
<= 5
が成立する
fn
= 2 + 1; fn2
= 2; fn1
= 3
i
= 4
i
<= 5
が成立する
fn
= 3 + 2;
fn2
= 3;
fn1
= 5
i
= 5
i
<= 5
が成立する
fn
= 5 + 3; fn2
= 5; fn1
= 8
i
= 6
i
<= 5
が成立しない
f
i
が入る
f
i-
1
が入る
f
i
が入る
fn
の値
fn2
の値
fn1
の値
22
++,
--
の意味
++
•
インクリメントを行
う
演算子.
•
インクリメントとは1足すこと.
オペランドに1を足
して,オペランドに格納する.
-
-
-
デクリメント演算子.
-
デクリメントとは1引くこと.
オペランドから1を引
いて,オペランドに格納する.
23
for
文
•
初期式
:繰り返しの最初に1回だけ実行される.
•
条件式
:繰り返しのたびに,真偽が判定される(偽な
らば繰り返しが終わる).
•
再設定式
:
繰り返しのたびに実行される.
f
or (
初期式
;
条件式
;
再設定式
) {
式
1;
式
2;
...
}
24
for
文による繰り返し
初期式
条件式
再設定式
Y
es
No
1.まず,「初期式」を実行
2.次に,「条件式」を実行.条件式が成立すれば,
式と「再設定式」を実行し,「条件式」に戻る
式
25
例題4.自然数の和
•
数(Nとする)を読み込んで,1からNまで
の和を求めるプログ
ラムを作る
•
ここでは,練習のた
め,自然数の和の公式は
使わずに,
for
文を用いる
例)
100 → 5050
26
自然数の和
実行結果の例
n=100
n=100,
sum=5050
27
自然数の和
#include <stdio.h>
#pragma
wa
rning(dis
able:4996)
int
main()
{
int
i;
int
n;
int
sum;
printf("n=");
scanf("%d",
&n);
sum =
0;
for (i=1;
i<=
n;
i++
)
{
sum
= sum
+ i;
}
printf("n=%d,
sum=%d\n",
n, sum);
return 0;
}
条件が成り立つ限り,
実行されつづける部分
条件式
28
プログラム実行順
i
= 1;
i
<= n
sum = sum + 1;
i
=
i
+ 1;
Y
es
No
29
自然数の和
n = 7
とすると
i
= 1
i
<= 7
が成立する
sum
= 0 + 1
i
= 2
i
<= 7
が成立する
sum
= 1 + 2
i
= 3
i
<= 7
が成立する
sum
= 3 + 3
i
= 4
i
<= 7
が成立する
sum
= 6 + 4
i
= 5
i
<= 7
が成立する
sum
= 10 + 5
i
= 6
i
<= 7
が成立する
sum
= 15 + 6
i
= 7
i
<= 7
が成立する
sum
= 21 + 7
i
= 8
i
<= 7
が成立しない
sum
には1から
i
までの
和が入る
sum
の値
30
for
文と
whil
e
文
f
or (
初期式
;
条件式
;
再設定式
) {
式
1;
式
2;
...
}
初期式
while (
条件式
) {
式
1;
式
2;
...
再設定式
}
f
or
文と
while
文の能力は
同じ.自分にとって
分かり
やすい方と使
う
べし
31
例題5.九九の表
•
九九の表を表示する
プログラムを作成する
•
九九の表を表示するために,
繰り返しの入れ子
を使
う
32
九九の表
#include <stdio.h>
int main()
{
int i;
int j;
for
(i=1; i<=9; i++) {
for(j=1; j<=9;
j++) {
printf("%d, ", i*j);
}
printf("\n");
}
return 0;
}
内側
外側
33
繰り返しの入れ子
34
九九の表
i
= 1
i
<= 9
Y
es
No
j = 1
j <=
9
Y
es
printf("%d, ", i*j);
j+
+
No
i
++
35
課題1
•
「例題1.最大公約
数の計算」のプログラ
ムを書き換えて,
m,n
を
何度も入力し
て計算
できるよ
う
にせよ
36
課題1のヒント
「
m,n
を何度も入力して計
算できる」と
は
繰り返し続けるプロ
グラム
while
(1) {
式1
;
式2
;
...
}
1
式
1
式
2
...
Y
es
この「1」は,「常に真である」
ことを示す特別な数
*後述する
do while
文を使っても「繰り返し続ける」ことは可
能
37
条件式での「1」の意味
値
意味
1
真
(true)
0
偽
(f
alse)
38
課題1のヒント
•
x
と
y
を入れ
替えるプログ
ラム
int x;
int y;
int z;
z = x;
x = y;
y = z;
z
は入れ替えのためだけ
に
使
う
変数
39
課題2
1.
ベクトルの値
(x
1
, x
2
,
... x
k
)を
1つづつ読
み込
んで,
1つ読み込
むごとに,次の計算
を行
う
プログラム
を作成し
なさい.
•
ベクトル
(x
1
, x
2
, ... x
k
)の長さ
2.
2つのベクトルの値
(x
1
,
x
2
, ...
)
, (y
1
,
y
2
, ...)
を
交互に読み込んで,
1
組読み込むことに次の計
算を行
う
プログラムを作
成しなさい.
•
2つのベクトルの内積
40
課題2のヒント
•
k回め
の繰
り返しにおい
て,長
さ
k
のベクトル
(
x1
,
x2
, ...
xk
)
の二乗和を求めるプログラム
sum = 0;
while (1
) {
scanf
( "%lf", x );
sum = su
m + ( x * x );
printf( "
sum = %f\n", su
m );
}
41
課題3.三角関数
•
θ
を読み込んで,
(cosθ+
i
sinθ)
n
を
計算するプログラムを作りなさい
•
なお,
i
は虚
数単位
•
n
は
1
から
100
まで
繰り返すこと(つ
まり,計算は
100
回行
う
)
42
複素数の積
z
1
=
x
1
+
i
y
1
z
2
=
x
2
+
i
y
2
のとき
z
1
z
2
= (x
1
+
i
y
1
)
(x
2
+
i
y
2
)
=
x
1
x
2
+ x
1
i
y
2
+
i
y
1
x
2
+
i
y
1
i
y
2
=
x
1
x
2
-
y
1
y
2
+
i
(x
1
y
2
+
y
1
x
2
)
実数部
虚数部
43
(
cosθ
+
i
sinθ
)
n
= cos
n
θ
+
i
sin
n
θ
(
cosθ
+
i
sinθ
)
2
=
cos
2
θ
-
sin
2
θ
+
2
i
cosθsi
n
θ
=
cos2θ
+
i
sin2
θ
(
cosθ
+
i
sinθ
)
3
= (
cosθ
+
i
sinθ
)
2
(
cosθ
+
i
sinθ
)
= (
cos2θ+
i
sin2θ
) (
cosθ
+
i
sinθ
)
=
cos2θcosθ
-
sin2θsinθ
+
i
(
cos2θs
inθ
-
sin2θc
osθ
)
= cos (
2θ+θ
)
+
i
sin (
2θ+θ
)
=
cos3θ
+
i
sin3θ
(
以下同
様に
考える.数学
的帰納
法で証明でき
る)
44
課題4
•
あるクラスの試験の点数から,その平均値
と,標準偏差を計算
するプログラムを作成
しなさい.
45
より勉強したい人
への付録
46
do whi
le
文による繰り返し
while
文との違い:
必ず最初に1回は実行される
47
do while
文
do {
式
1;
...
式
n;
} while
(
条件式
);
48
do while
文が役に立つ場合
•
読み込み値のチェック
•
0点以上,100点以下のデータの読み込み
•
間違いがあったら,読み込みを繰り返す
do {
prin
tf("
t
ensu=");
scan
f("%d",
&tensu
);
} while( ( tensu
< 0
) || (
tensu
> 100
) );
49
break
文
•
繰り返しを中断
•
break
を含む最も内側の
switch
文あるいは繰り返
し文(
while, for
文など)から抜け出す.
50
break
文
while
(
条件
1){
式
;
if (
条件
2){
式
;
break; /*
while
の外へ
*
/
}
printf("
条件2が成
り立てば実行されない.
");
}
printf
("whi
le
の外
\n");
条件1の結果が成り立たない
条件2の結果が成り立つ
51
continue
文
•
次の繰り返
し実行を行
う
ための文.
•
continu
e
を
含む最
も内側の繰り返し
文(
while
文
,
for
文など
)につ
いて,繰り返しの本
体の残りを飛
ばして,次
の繰り返しを始める.
52
continue
文
while (
条件
1){
式
;
if (
条件
2){
式
;
continue; /* while
の先頭へ
*/
}
printf
(“
条件2が成り立たなければ実行される.
");
}
printf("while
の外
\
n");
53
break
文
,
con
tinue
文のまとめ
•
break
文
•
while
文
, for
文での繰り返しから抜け出す
•
continue
文
•
繰り返し途中で,残りの処理を飛ばす
54