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つの整数データを読み込んで,最大公約数を求
めるプログラムを作る.
ユークリッドの互助法を用いること
ユークリッドの互助法を行ために while 文を書く
例) 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;
Yes
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
...
Yes
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;
Yes
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回目
繰り返し
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++
Yes
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回だけ実行される.
条件式:繰り返しのたびに,真偽が判定される(偽な
らば繰り返しが終わる).
再設定式繰り返しのたびに実行される.
for ( 初期式; 条件式; 再設定式 ) {
1;
2;
...
}
24
for 文による繰り返し
初期式
条件式
再設定式
Yes
No
1.まず,「初期式」を実行
2.次に,「条件式」を実行.条件式が成立すれば,
式と「再設定式」を実行し,「条件式」に戻る
25
例題4.自然数の和
数(Nとする)を読み込んで,1からNまで
の和を求めるプログラムを作る
ここでは,練習のため,自然数の和の公式は
使わずに,for文を用いる
例) 100 → 5050
26
自然数の和
実行結果の例
n=100
n=100, sum=5050
27
自然数の和
#include <stdio.h>
#pragma warning(disable: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;
Yes
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 文と while
for ( 初期式; 条件式; 再設定式 ) {
1;
2;
...
}
初期式
while ( 条件式 ) {
1;
2;
...
再設定式
}
for 文と 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 Yes
No j = 1
j <= 9 Yes
printf("%d, ", i*j);
j++
No
i++
35
課題1
「例題1.最大公約数の計算」のプログラ
ムを書き換えて,m,n何度も入力して計算
できるよにせよ
36
課題1のヒント
m,nを何度も入力して計算できる」と
繰り返し続けるプログラム
while (1) {
式1;
式2;
...
}
1
2
...
Yes
この「1」は,「常に真である」
ことを示す特別な数
*後述する do while 文を使っても「繰り返し続ける」ことは可
37
条件式での「1」の意味
意味
(true)
(false)
38
課題1のヒント
を入れ替えるプログ
ラム
int x;
int y;
int z;
z = x;
x = y;
y = z; z は入れ替えのためだけ
使変数
39
課題2
1. ベクトルの値 (x1, x2, ... xk)を1つづつ読み込
んで,1つ読み込むごとに,次の計算を行
プログラムを作成しなさい.
ベクトル(x1, x2, ... xk)の長さ
2. 2つのベクトルの値(x1, x2, ... , (y1, y2, ...)
交互に読み込んで,1組読み込むことに次の計
算を行プログラムを作成しなさい.
2つのベクトルの内積
40
課題2のヒント
k回めの繰り返しにおいて,長kのベクトル (x1,
x2, ... xk) の二乗和を求めるプログラム
sum = 0;
while (1) {
scanf( "%lf", x );
sum = sum + ( x * x );
printf( "sum = %f\n", sum );
}
41
課題3.三角関数
θを読み込んで,(cosθ+ i sinθ)n
計算するプログラムを作りなさい
なお,i は虚数単位
n 1から100 まで繰り返すこと(つ
まり,計算は100回行
42
複素数の積
z1= x1+ iy1
z2= x2+ iy2のとき
z1z2= (x1+ iy1) (x2+ iy2)
= x1x2+ x1iy2+ iy1x2+ iy1iy2
= x1x2- y1y2+ i(x1y2+ y1x2)
実数部 虚数部 43
(cosθ+ isinθ)n = cos nθ+ isin nθ
(cosθ+ isinθ)2= cos2θ- sin2θ+ 2icosθsin θ
= cos2θ+ isin2θ
(cosθ+ isinθ)3= (cosθ+ isinθ)2(cosθ+ isinθ)
= (cos2θ+isin2θ) (cosθ+ isinθ)
= cos2θcosθ-sin2θsinθ
+ i(cos2θsinθ-sin2θcosθ)
= cos (2θ+θ) + isin (2θ+θ)
= cos3θ+ isin3θ
(以下同様に考える.数学的帰納法で証明できる)
44
課題4
あるクラスの試験の点数から,その平均値
と,標準偏差を計算するプログラムを作成
しなさい.
45
より勉強したい人への付録
46
do while 文による繰り返し
while 文との違い: 必ず最初に1回は実行される
47
do while
do {
1;
...
n;
} while (条件式);
48
do while 文が役に立つ場合
読み込み値のチェック
0点以上,100点以下のデータの読み込み
間違いがあったら,読み込みを繰り返す
do {
printf(" tensu=");
scanf("%d", &tensu);
} while( ( tensu < 0 ) || ( tensu > 100 ) );
49
break
繰り返しを中断
break を含む最も内側の switch文あるいは繰り返
し文(while, for 文など)から抜け出す.
50
break
while (条件1){
;
if (条件2){
;
break; /* whileの外へ*/
}
printf("条件2が成り立てば実行されない.");
}
printf("whileの外\n");
条件1の結果が成り立たない
条件2の結果が成り立つ
51
continue
次の繰り返し実行を行ための文.
continue 含む最も内側の繰り返し文(while,
for 文など)について,繰り返しの本体の残りを飛
ばして,次の繰り返しを始める.
52
continue
while (条件1){
;
if (条件2){
;
continue; /* whileの先頭へ*/
}
printf(“条件2が成り立たなければ実行される.");
}
printf("whileの外\n");
53
break , continue 文のまとめ
break
while , for 文での繰り返しから抜け出す
continue
繰り返し途中で,残りの処理を飛ばす
54