講義用資料

プログラムの設計と実現 I(第2回:2014/04/24)
◎平均点を求めるプログラム(教科書 List 5-1)
#include <stdio.h>
int main(void)
{
int uchida, satoh, sanaka, hiraki, masaki;
int sum = 0;
puts("点数を入力してください。");
printf("1 番:"); scanf("%d", &uchida);
printf("2 番:"); scanf("%d", &satoh);
printf("3 番:"); scanf("%d", &sanaka);
printf("4 番:"); scanf("%d", &hiraki);
printf("5 番:"); scanf("%d", &masaki);
sum
sum
sum
sum
sum
+=
+=
+=
+=
+=
uchida;
satoh;
sanaka;
hiraki;
masaki;
printf(“合計点:%5d\n”, sum);
printf(“平均点:%5.1f\n”, (double)sum / 5);
return 0;
}
◎上記プログラムで人数が増えたら……
もし 5 人でなく 300 人だったらどうする?
すべてを列挙するのは非効率
◎配列
ひとつの名前と添字によってたくさんのデータをまとめて使用
uchida → vc[0]
satoh → vc[1]
sanaka → vc[2]
hiraki → vc[3]
masaki → vc[4]
◎プログラム例(上記プログラムを配列を使って修正)
#include <stdio.h>
int main(void)
{
int vc[5];
int sum = 0;
int i;
puts(“点数を入力してください。”);
for (i=0; i<5; i++) {
printf(“%d 番:”, i+1);
scanf(“%d”, &vc[i]);
sum += vc[i];
}
printf(“合計点:%5d\n”, sum);
printf(“平均点:%5.1f\n”, (double)sum / 5);
return 0;
}
◎配列とは?
これまでの変数
int uchida, satoh, sanaka, hiraki, masaki
配列変数
int vc[5];
・配列では変数と添字で複数の変数をひとまとめにできる
・配列は定義時に大きさを決めなければならない
・配列の大きさを N とすると添字は 0~N-1 の範囲内になければならない
・代入演算子で配列全体を代入することはできない
(駄目な例)
int va[5], vb[5];
va = vb;
(正しい書き方)
int va[5], vb[5];
int i;
for (i=0; i<5; i++) {
va[i] = vb[i];
}
◎10 人の平均点を求めるプログラム例
#include <stdio.h>
#define NUM 10
/* 配列の大きさはこのように定数を用いると良い */
int main(void)
{
int soten[NUM]={84,95,60,100,83,72,93,85,65,98};
/* このように書くことによって、配列の値を初期化できる */
int goukei;
double heikin;
int i;
goukei = 0;
for (i=0; i<NUM; i++) {
goukei += soten[i];
}
/* 配列の全要素を使うときの定石! */
heikin = (double)goukei / NUM;
printf("平均は %5.2f 点です\n", heikin);
return 0;
}
◎多次元配列
行列などのデータを記憶できるデータ構造は?
通常の配列 → 一次元構造
例) 84,95,60,100,83,72,93,85,65,98
多次元配列
例)行列データ
 1 2 3


 4 5 6
◎一次元配列と二次元配列
・一次元配列
int vc[5];
・二次元配列
int ma[2][3];
◎コンピュータ上でのメモリ配置
配列は以下のようにコンピュータのメモリ上に記憶される。
・一次元配列
int vc[5];
・二次元配列
int ma[2][3];
※右側の括弧から順番に並ぶ
◎行列の足し算プログラム(教科書 List 5-14)
#include <stdio.h>
int main(void)
{
int i,j;
int ma[2][3] = { {1,2,3}, {4,5,6} };
int mb[2][3] = { {6,3,4}, {5,1,2} };
int mc[2][3];
for (i=0; i<2; i++) {
for (j=0; j<3; j++) {
mc[i][j] = ma[i][j] + mb[i][j];
}
}
for (i=0; i<2; i++) {
for (j=0; j<3; j++) {
printf("%3d", mc[i][j]);
}
printf("\n");
}
return 0;
}
◎素数の求め方 (p.104~p.111)
List5-15: no を 2~no-1 までの値で割り切れるかどうかチェック、割り切れた
ら素数ではない。割り切れた場合は break で内側のループを抜けるが、その場
合は必ず i<no である。no を 2~1000 までチェックする。
List5-16: 2 は素数であり、2 より大きい偶数は素数ではないので、List5-15
の no のチェックを 3~999 までの奇数とする。
List5-17: 3 以上の素数は偶数では割り切れないので、割り切れるかどうかを
チェックするのは 3~no-1 までの奇数だけでよい。List5-16 の割る数を 3~no-1
までの奇数に限定する。
List5-18:素数の条件は no より小さい素数で割り切れないことと言えるので、
割る数を no よりも小さい素数に限定する。
List5-19:割る数は no の平方根以下までで確認すれば良い。