cp-7. 配列
C プログラミング入門)
URL: https://www.kkaneko.jp/pro/adp/index.html
1
金子邦彦
内容
例題1.月の日数
配列とは.配列の宣言.配列の添え字.
例題2.ベクトルの内積
例題3.合計点と平均点
例題4.棒グラフを描く
配列と繰り返し計算の関係
例題5. 行列の和
2次元配列
2
目標
配列とは何かを理解し,int, double を使った配列
の宣言と使用ができるよにな
配列と繰り返し文を組み合わせて,多量のデータ
を扱えるになる
3
配列
データの並びで,0から始まる番号(添字)
が付いている
添字
4
例題1.月の日数
年と月を読み込んで,日数を求めるプログラ
ムを作る
年の2月ならば29
日数を求めるために,サイズ12の配列を使
例) 2001 11 30
5
月の日数
#include <stdio.h>
#pragma warning(disable:4996)
int main()
{
int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int y;
int m;
printf( "y=" );
scanf( "%d", &y );
printf( "m=" );
scanf( "%d", &m );
if ( (m == 2) && (((y % 400) == 0) || (((y % 100) != 0) && ((y % 4) == 0)))){
printf( "number of days(%d) = 29\n", m );
}
else {
printf( "number of days(%d) = %d\n", m, num_days[m-1] );
}
return 0;
}
配列の宣言
配列からの
読み出し
「m-1」に意味がある 6
月の日数
実行結果の例
y=2001
m=11
number of days(11) = 30
7
プログラムとデータ
メモリ
num_days[0]
num_days[m-1];
配列からの値の
読み出し
num_days[1]
num_days[2]
num_days[3]
num_days[4]
num_days[5]
num_days[6]
num_days[7]
num_days[8]
num_days[9]
num_days[10]
num_days[11]
31
28
31
30
31
30
31
31
30
31
30
31 8
配列の宣言
配列には,名前(データの種類のこと)と
サイズがある
整数データ int
浮動小数データ double
配列を使には,配列の使用をコンピュータ
伝えること(宣言)が必要
int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
整数
データ 名前は
num_days 配列のサイズ
は12 9
配列の添字
配列の中身を読み書きすると
きには,配列の名前添字
書く
例) num_days[m-1]
添字は0から(サイズー1)
まで
例) サイズ12の配列の
添字は,0から11ま
添字
10
11
これが添字
10
配列の読み書き
添字を付けて,普通の変数と同じよに使
例)
v[0]=1.3;
a=v[1];
printf("%f", v[2]);
scanf("%lf", &v[3]);
11
例題2.ベクトルの内積
ベクトル(1.9, 2.8, 3.7)と,ベクトル(4.6,
5.5, 6.4)の内積を表示するプログラムを作る
2つのベクトルの内積の計算のために,サイズ3の
配列を2つ使
12
例題2.ベクトルの内積
#include <stdio.h>
int main()
{
double u[]={1.9, 2.8, 3.7};
double v[]={4.6, 5.5, 6.4};
int i;
double ip;
ip = 0;
for (i=0; i<3; i++) {
ip = ip + u[i]*v[i];
}
printf("内積=%f\n", ip);
return 0;
}
配列の宣言
配列からの
読み出し
13
ベクトルの内
実行結果の例
内積=47.820000
14
プログラムとデータ
メモリ
u[0]
ip = ip + u[i]*v[i];
配列からの値の
読み出し
u[1]
u[2]
1.9
2.8
3.7
v[0]
v[1]
v[2]
4.6
5.5
6.4
15
配列の宣言
double u[]={1.9, 2.8, 3.7};
double v[]={4.6, 5.5, 6.4};
浮動小数
データ
名前は
u v列のサイズ
は3
16
プログラム実行順
ip = 0.0;
i < 3 Yes
No
i = 0;
printf("内積=%f\n",ip);
ip = ip + u[i]*v[i];
i++;
17
ベクトルの内積
繰り返し
1回目 i= 0i < 3 が成り立つ ip = ip + u[0] * v[0];
繰り返し
2回目
繰り返し
3回目
繰り返し
4回目
i= 1i < 3 が成り立つ ip = ip + u[1] * v[1];
i= 2i < 3 が成り立つ ip = ip + u[2] * v[2];
i = 3 i < 3 が成り立たない
iの値 繰り返し条件式
が成り立つか ip の値
つまり ip の値は u[0]*v[0]
つまり ip の値は u[0]*v[0] + u[1]*v[1]
つまり ip の値は u[0]*v[0] + u[1]*v[1]
+u[2]*v[2]
18
例題3.合計点と平均点
点数を読み込んで,合計点と平均点を表示す
るプログラムを作る
平均点の計算では,小数点以下切捨て
プログラムは,点数を読み込み続けるが,読み込
んだ点数が「-1」のときには,合計点と平均点
を表示して終了する
読み込んだ点数は,いったんサイズ100の配列
に格納する(点数の数は100を超えないものと
仮定する)
例) 50, 85, 30, 20
合計点 185
平均点 46
19
#include <stdio.h>
#pragma warning(disable:4996)
int main()
{
int x[100];
int sum;
int i;
int n;
n = 0;
do {
printf( "x[%d]=", n );
scanf( "%d", &x[n]);
n++;
} while ( ( x[n-1] >= 0 ) && ( n < 100 ) );
sum = 0;
for (i=0; i<(n-1); i++) {
sum = sum + x[i];
}
printf("合計=%d, 平均=%d\n", sum, sum/(n-1) );
return 0;
}
配列の宣言
20
合計点と平均
実行結果の例
x[0]=50
x[1]=85
x[2]=30
x[3]=20
x[4]=-1
合計=185, 平均=46
21
プログラムとデータ
メモリ
scanf("%d",&x[n]);
整数データを
読み込み
x[0]
x[1]
x[2]
x[3]
x[4]
sum = sum + x[i];
合計値の計算
22
プログラム実行順
n = 0;
( x[n-1] >= 0 ) && ( n < 100 ) Yes
No
printf( "x[%d]=", n );
scanf( "%d", &x[n] );
n++;
sum = 0;
i = 0;
No
i < n - 1
sum = sum + x[i];
i++;
Yes
23
合計点と平均
(5回目で「-1」を読み込んだとき)
繰り返し
1回目 n = 1 (x[0] > 0 && n < 100)が成り立つ x[0]
繰り返し
2回目 n = 2 (x[1] > 0 && n < 100)が成り立つ x[1]
繰り返し
3回目 n = 3 (x[2] > 0 && n < 100)が成り立つ x[2]
繰り返し
4回目 n = 4 (x[3] > 0 && n < 100)が成り立つ x[3]
繰り返し
5回目 n = 5 (x[4] > 0 && n < 100)が成り立たない x[4]
n の値 繰り返し条件式
が成り立つか
読み込まれる
配列の要素
「-1」を読み込んだ
この部分が成り立たな 24
配列の宣言
1. 配列の宣言時にサイズを指定
例)
int x[100];
2. 配列の宣言時に初期値を設
例)
double u[]={1.9, 2.8, 3.7};
double v[]={4.6, 5.5, 6.4};
int a[]={6,4,7,1,5,3,2};
サイズとして「100」
を書いている
初期値を並べて
書いている
25
例題4.棒グラフを描
整数の配列から,その棒グラフを表示するプ
ログラムを作る.
ループの入れ子で,棒グラフの表示を行
26
棒グラフを描
#include <stdio.h>
int main()
{
int a[]={6,4,7,1,5,3,2};
int i;
int j;
for (i=0; i<7; i++) {
for (j=0; j<a[i]; j++) {
printf("*");
}
printf("\n");
}
return 0;
}
配列の宣言
配列からの
読み出し
27
棒グラフを書
実行結果の例
******
****
*******
*
*****
***
** 28
プログラムとデータ
メモリ
a[0]
for (j=0; j<a[i]; j++) {
配列からの値の
読み出し
a[1]
a[2]
6
a[3]
a[4]
a[5]
a[6]
4
7
1
5
3
2
29
配列の宣言
int a[]={6,4,7,1,5,3,2};
整数
データ名前は
a配列のサイズ
は7
30
プログラム実行順
j < a[i] Yes
No printf("*");
++;
printf("\n");
i < 7 Yes
i++;
= 0;
i = 0;
No
return 0;
31
ここまでのまとめ
配列の宣言
[] の中に,配列のサイズを書く.但し,配列の初期
値を設定するときには「空」にする.
配列の使用
[]の中に,使用したい配列の添字を書く
[] の意味
32
課題1
n次の多項式
f(x) = a0+ a1x + a2x + ・・・ +anx
について,次数 n と,係数 a0から anを読み込ん
で,f(x) を計算するプログラムを作りなさい
n は高々20までとする.(ユーザが20以上の数を n
として与えたら,メッセージを表示して止まること).
次ページで説明する Horner法を使こと
読み込んだ点数は,いったんサイズ21の配列に格納す
x を繰り返し入力できるよなプログラムであること
(つまり f(x) を何度も計算する)
33
Horner
f(x) = a0+ a1x + a2x + ・・・ +anx
= a0+ ( a1+ ( a2+ ・・・ + ( an-1 + an x ) x ・・・) x ) x
例えば, 5 + 6x + 3x
= 5 + ( 6 + 3x ) x
計算手順
an
an-1 + anx
an-2 + ( an-1 + anx ) x
・・・ anまで続ける)
2n
2
34
課題1のヒント
ここを考える
No
i >= 0
Yes
sum = a[n];
i = n - 1;
i--;
35
課題2.エラトステネスのふるい
「エラトステネスのふるい」の原理に基づ
いて100以下の素数を求め,結果を表示する
プログラムを作成せよ.
100以下の素数を求めるために,サイズ10
0の配列を使
添字が素数の要素に1,そでない要素に0を代
入する
36
エラトステネスのふるい (1/4)
2345678910 11 ・・・
×× ××
まず,2の倍数を消
37
エラトステネスのふるい (2/4)
2345678910 11 ・・・
×
次に,3の倍数を消
×
38
エラトステネスのふるい (3/4)
2345678910 11 ・・・
次に,5の倍数を消す
(「4の倍数」は考えない.
それは,「4」がすでに消えているから
×
39
エラトステネスのふるい (4/4)
2345678910 11 ・・・
以上のよに,2,3,5,7の倍数を消す.
10(これは100の平方根)を超えたら,この操作を止める
(100以下で,11,13・・・の倍数はすでに消えている)
40
例題5.行列の和
2行3列の行列の和を計算して表示するプロ
グラムを作る.
2つの行列を扱ために,2行3列の2次元配列
を2つ使
a 2行3列の2次元配列 浮動小数
b 2行3列の2次元配列 浮動小数
41
2次元配列とは
ary[0][0] ary[0][1]
ary[1][0]
ary[2][0]
...
42
行列の和
#include <stdio.h>
int main()
{int a[2][3]={{1,2,3},{4,5,6}};
int b[2][3]={{9,8,7},{6,5,4}};
int i;
int j;
for (i=0; i<2; i++) {
for (j=0; j<3; j++) {
printf("%d, ", a[i][j]+b[i][j]);
}
printf("\n");
}
return 0;
}
配列の宣言
配列からの
読み出し
43
行列の和
実行結果の例
10, 10, 10,
10, 10, 10,
44
2次元配列の宣言
2次元配列の宣言では,名前型,サイズを指
定することが必要
int a[2][3]={{1,2,3},{4,5,6}};
整数
データ
名前は
a配列のサイズ
は2×
2次元以上の配列の宣言では,サイズを書く
(省略できない)ことになっている 45
課題3
3×3行列の積を計算して表示するプログラムを
作成しなさ
2つの行列を扱ために,3行3列の2次元配列を2
つ使
46
多次元配列についての補足
多次元配列は,普通,最大7次元まで(処理系に
より異なる).
例) 整数型の3次元配列
int a[2][3][4];
47
変数の初期化
変数を宣言すると同時に,値の設定もできます.
int i;
i = 0; int i = 0;
同じ意味
48