プログラミング入門2 第5回 配列 変数宣言、初期化について 情報工学科 篠埜 功 今日の内容 • 配列 配列とは、同じ型のデータを格納する箱(領域)を一列 に並べて添え字でアクセスできるようにしたもの。 配列の必要性 M学科に、3人の学生(学籍番号M09001, M09002, M09003)が いたとする。M学科のある科目の成績を入力し、平均点を計算 したいとする。 #include <stdio.h> int main (void) { int m09001; int m09002; int m09003; double average; scanf (“%d”, &m09001); scanf (“%d”, &m09002); scanf (“%d”, &m09003); average = (double) (m09001 + m09002 + m09003) / 3; printf (“平均点は%f点です。\n”, average); return 0; } 配列の必要性 学生が100人いた場合、これまでに講義で説明した範囲だ と、100個の変数を宣言しなければならない。 一度にまとめて宣言したい。 配列を使うと、 int m [100]; のように宣言することにより、100人分のint型のデータ格納 場所が用意される。 m[0], m[1], m[2], … m[99] の100個分のデータ格納場所が用意される。 添え字が0から始まることに注意。 プログラム例1(打ち込んで確認) /* 長さ3の配列に数値を代入して表示 */ #include <stdio.h> int main (void) { int m[3]; m[0] = 10; m[1] = 5; m[2] = 7; printf (“m[0] = %d\n”, m[0]); printf (“m[1] = %d\n”, m[1]); printf (“m[2] = %d\n”, m[2]); return 0; } 配列の宣言 • 3人分の点数を格納するint型の変数を用意したい場合 int型の変数の宣言 型名 変数名 int x ; x int型のデータの格納場 所が1つ用意される。 int型を要素とする配列の宣言 要素の型名 変数名 [ 要素数 ] int a [3] ; a [0] a [1] a [2] a[0] ~a[2]までの3個 のint型のデータの格 納場所が用意される。 [ ]内に書く番号(添え字という) は0から始まる。 配列の各要素へのアクセス 変数の場合の例 配列の場合の例 int x; x = 3; printf (“%d\n”, x + 2); int x [10]; x[0] = 3; printf (“%d\n”, x[0] + 2); 配列の各要素は、x[0]のように、配列名に続けて添え字を[ ]内 に入れて表す。添え字は数字でなくても変数などの式でも構 わない。ポインタの回にもう一度説明する。 変数の場合と同様に、配列の各要素がint型やdouble型の場 合には、そこへ値を代入したり、そこに格納されている値を参 照したりできる。 変数宣言の記法について(1) これまで変数宣言は1つずつ書いてきたが、同じ型 の変数はまとめて宣言することができる。 (例) int x; int y; int z; double a; double b; は、 int x,y,z; double a, b; のように、コンマで区切って一度に宣言してよい。 変数宣言の記法について(2) 配列の宣言もまとめて書いてよい。 (例) int x; int a[3]; int b[10]; double y; double c[20]; は、 int x, a[3], b[10]; double y, c[20]; のようにコンマで区切って一度に宣言してよい。 変数宣言と初期化 変数宣言時に、変数の初期値を書くことができる。 (例) int x; int y; x=3; y=10; は、 int x=3, y=10; のようにまとめて書いてよい。 変数宣言時に初期化をすることによって、その変数の 値を代入前に参照するという状況が起こらなくなる。 配列の初期化(1) 変数と同様、配列も宣言時に初期化できる。 宣言時に、右辺に中括弧で囲んで値を並べる。 例えば、 int a[3]; a[0] = 10; a[1] = 5; a[2] = 7; は、 int a [3] = {10, 5, 7}; のようにまとめて書くことができる。 配列の要素数について 配列を宣言する際、要素数は定数でなければならない。 (教科書 p. 89 参照) 例えば、 int n = 5; int a[n]; のように要素数を変数で指定することは(1990年のISO規 格では)許されていない。 ただし、1999年のISO規格(C99)では定数でなくてもよく なったので、上記のような宣言は許されている。 講義では1990年のISO規格に従うが、試験ではどちらで もよいことにする。 プログラム例2(打ち込んで確認) /* 長さ10のint型配列の各要素に0を代入 */ #include <stdio.h> int main (void) { int a[10]; int i=0; while (i<10) { a[i] = 0; a[i]においては、変数式 i が i=i+1; 添え字になっている。 } i=0; while (i<10) { printf ("a[%d] = %d\n", i, a[i]); i=i+1; } return 0; } プログラム例3(打ち込んで確認) /* 配列にキーボードからの入力値を格納 */ #include <stdio.h> 変数と同じように、&を左側につける。詳し くはポインタの回に説明する。 &(m[0])を int main (void) { &m[0]のように括弧を省略して書いている。 int m[3]; double average; printf (“M09001の成績を入力してください: “); scanf (“%d”, &m[0]); printf (“M09002の成績を入力してください: “); scanf (“%d”, &m[1]); printf (“M09003の成績を入力してください: “); scanf (“%d”, &m[2]); average = (double) (m[0] + m[1] + m[2]) / 3; printf (“平均点は%f点です。\n”, average); return 0; } プログラム例4(打ち込んで確認) /* M学科10人分の点数をキーボードから入力し、平均点を出力する */ #include <stdio.h> int main (void) { int m[10], i=0, sum=0; %02dの場合、表示する数が2桁未満 while (i<10) { のとき、左側に0を埋めて表示する。 printf (“M090%02d: “, i+1); %2dの場合は、0ではなく空白を埋め scanf (“%d”, &m[i] ); て表示する。 i=i+1; } i=0; while (i<10) { sum = sum + m[i]; i=i+1; } printf (“平均点は%f点です。\n”, (double) sum / 10); return 0; } 配列の初期化(2) 配列の初期化において、右辺の要素数が少ないとき は、足りない部分は0 (double型の場合は0.0) で初期 化される。たとえば、 int a [3] = {10, 5}; のように書くと、a[0]が10, a[1]が5, a[2]が0で初期化さ れる。 プログラム例5(打ち込んで確認) /* 長さ10のint型配列の各要素を0で初期化 */ #include <stdio.h> int main (void) { a[0]が0で初期化され、 int a[10] = {0}; a[1]からa[9]も0で初期化 int i=0; される。 while (i<10) { printf ("a[%d] = %d\n", i, a[i]); i=i+1; } return 0; } 配列の初期化(3) 配列の初期化において、右辺に初期化子がある場合、 要素数を省略できる。例えば、 int a [ ] = {10, 5, 7}; のように書くと、 int a [3] = {10, 5, 7}; と書いたのと同じ意味になる。 配列のコピー 配列のコピーを行う場合は、各要素をコ ピーする必要がある。 間違った例 int a[3] = {10, 5, 7}; int b[3]; b=a; b=aの代入式はコンパイル時にエラーになる。 詳しくはポインタの回に説明する。 配列のコピー(打ち込んで確認) #include <stdio.h> int main (void) { int a[5] = {3,4,5,6,7}; int b[5]; int i=0; while (i<5) { b[i] = a[i]の代入式によって各 b[i] = a[i]; 要素ごとに代入を行っている。 i=i+1; } i=0; while (i<5) { printf (“a[%d]=%d, b[%d]=%d\n”, i, a[i], i, b[i]); i=i+1; } return 0; } 多次元配列 配列の要素は配列でもよい。 例えば、int型を要素にもつ長さ3の配列を要素に もつ長さ2の配列は、 int a [2] [3] ; のように宣言する。これは2次元配列である。(3 次元以上も同様に宣言できる。2次元以上の配 列を多次元配列と呼ぶ。) 各要素は、a[0][1]のように、[ ] を並べて書くことに よって表す。これは(a[0])[1]を括弧を省略して書 いたものである。a[0]はaの0番目の要素(int型を 要素にもつ長さ3の配列)を表し、a[0][1]は、配列 a[0]の1番目の要素を表す。 多次元配列のメモリ上での配置 int a [2] [3] ; のように宣言された2次元配列の各要素は以下の ようにメモリ上に配置される。 配列 a[0] 配列 a[1] a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 多次元配列の例(打ち込んで確認) /* 2*3の配列の各要素に1を 代入し、各要素の値を表示 */ #include <stdio.h> int main (void) { int i, j; int a[2][3]; i=0; while ( i < 2 ) { j=0; while ( j < 3 ) { a[i][j] = 1; j = j + 1; } i = i + 1; } /* 左の続き */ i=0; while ( i < 2 ) { j=0; while ( j < 3 ) { printf ("a[%d][%d] = %d\n", i, j, a[i][j] ); j = j + 1; } i = i + 1; } return 0; } 初期化 1次元配列と同様に初期化できる。 (例) int a [2][3] = { {1,2,3}, {4,5,6} }; のように宣言、初期化すると、配列 a[0] が{1,2,3}で 初期化され、配列 a[1] が{4,5,6}で初期化される。 プログラム例(打ち込んで確認) /* 初期化した値を表示して確認 */ #include <stdio.h> int main (void) { int a[2][3] = { {1,2,3}, {4,5,6} }; int i, j; i=0; while ( i < 2 ) { j=0; while ( j < 3 ) { printf ("a[%d][%d] = %d\n", i, j, a[i][j]); j = j + 1; } i = i + 1; } return 0; } 基本課題1 長さ5のint型の配列の各要素にキーボードから入力した整 数値を格納し、それらの最大値、最小値、平均値を表示する プログラムを書け。平均値はdouble型で計算し、表示せよ。 [実行例] $ ./kihon5-1 整数を5個入力してください: a[0] = 30 a[1] = 55 a[2] = 7 a[3] = 40 a[4] = 90 最大値は90、最小値は7、平均値は44.4です。 基本課題2 長さ5のint型の配列の各要素にキーボードから入力した値を格納し、その 配列を左に1回転したものを別の配列に格納して表示せよ。 [実行例] $ ./kihon5-1 整数を5個入力してください: a[0] = 30 a[1] = 55 a[2] = 7 a[3] = 40 a[4] = 90 左に1回転した配列は、 b[0] = 55 b[1] = 7 b[2] = 40 b[3] = 90 b[4] = 30 です。 発展課題1 2次元配列を3つ使って、2*2の行列の積を計算して表示す るプログラムを書け。行列の各要素の値はint型とし、キー ボードから読み込むようにせよ。 [実行例] $ ./hatten5-1 行列aを入力してください: a[0][0] = 1 a[0][1] = 2 a[1][0] = 3 a[1][1] = 4 行列bを入力してください: b[0][0] = 1 b[0][1] = 1 b[1][0] = 1 b[1][1] = 1 行列a,bの積は p[0][0] = 3 p[0][1] = 3 p[1][0] = 7 p[1][1] = 7 です。 発展課題2 2*2のint型の行列のn乗を計算し、表示するプログラム を書け。行列の値およびnはキーボードから読み込むよ うにせよ。 [実行例] $ ./hatten5-2 行列aを入力してください: a[0][0] = 1 a[0][1] = 2 a[1][0] = 3 a[1][1] = 4 何乗しますか: 3 行列aの3乗は p[0][0] = 37 p[0][1] = 54 p[1][0] = 81 p[1][1] = 118 です。
© Copyright 2024 ExpyDoc