以下に示すプログラムで static 変数の意味を確認してみましょう.複数回実行して様子を見てください.
#include <stdio.h> int main(void) { int var_auto = 1; static int var_static = 1; printf("var_auto: %p\n", &var_auto); printf("var_static: %p\n", &var_static); return 0; } |
%p はポインタのアドレスを表示させる記法でした.また,変数名の前に & をつけるのは変数の値ではなく,変数のアドレスを表します.
初項が aで,公比が r の等比数列 gn は以下のように漸化式で表現できるので,再帰により各項の値を求めることができます.
n = 1: g1 = a
n > 1: gn = gn-1 * r
乱数を用いて初項が2から4のどれかの整数,公比が2から6のどれかの整数の等比数列を用意し,第10項までの値を順に表示するプログラムを作成しましょう.
Geometric progression: a=4, r=6 4 24 144 864 5184 31104 186624 1119744 6718464 40310784 |
各項の値を計算する部分を再帰関数にしますが,再帰の場合は渡せる変数が項番号一つだけなので,初項や公比は外部変数で用意しないと扱うことができません.
2桁の正の偶数を乱数により2つ発生させ m と n します.分数表記 m / n を既約分数に変換するプログラムを作成しましょう.このとき,教科書p.78で出てきた最大公約数を求める関数を別モジュールとして用意しましょう.
44/64 -> 11/16 |
昨年度のプログラミング入門Iの中で, if - else 文と switch 文の速度の違いを見るための時間計測の処理をさり気なく入れていました.今回それを活用して,レジスタ変数を使用すると実際に処理速度が上がるのかを見てみましょう.
clock_t t1, t2; t1 = clock(); //ここに書かれた処理にかかる時間が計測されます t2 = clock(); printf("Process time: %f sec\n\n", (double)(t2 - t1) / CLOCKS_PER_SEC); |
上の処理を利用して,9999以下の完全数を全て求めるプログラムを各変数を自動変数で用意する場合とレジスタ変数で行う場合の2種類用意して時間の違いを見てみましょう.
6 28 496 8128 Process time of auto: 0.317 sec 6 28 496 8128 Process time of register: 0.226 sec |
自分自身を除く約数の和が自分自身と一致するときにその数を完全数と言いましたが,ある整数 m の自分自身を除く約数の和が n で, n の自分自身を除く約数の和が m となるとき,2つの数 m と n を友愛数と言います.例えば,220と284では,
220: 1+2+4+5+10+11+20+22+44+55+110=284
284: 1+2+4+71+142=220
となり,友愛数です.
4桁の友愛数は全部で4組あるのですが,それらの探索にかかる時間がレジスタ変数を用いることで短くなるかどうかを確認しましょう.
1184 1210 2620 2924 5020 5564 6232 6368 Process time of auto: 0.451 sec 1184 1210 2620 2924 5020 5564 6232 6368 Process time of register: 0.369 sec |
配列を使用しないで友愛数を探すと,そのままでは
1184 1210 1210 1184
のように同じ組を2回検出してしまうので,私の作ったサンプルプログラムはそうならないように少し工夫しています.