[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIB(Javaプログラミング入門)第6回

目次
6.1 データの入出力(2)
6.1.1 文字列の連結
6.2 配列(1)
6.2.1 配列とは
6.2.2 配列の使い方
6.2.3 配列の初期化
6.2.4 配列と繰返し
6.2.5 配列の使用例
6.3 演習6
6.4 レポート課題
6.5 参考文献
索引
インデックス   初期化(配列の)   添字   配列   配列要素  

6.1 データの入出力(2)

6.1.1 文字列の連結

データの出力で使う System.out.println( data );System.out.print( data );data の所では、文字列や変数などを演算子 + で結ぶことができます。

/*  1*/ class IntToString { // 整数を文字列にする
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100;
/*  4*/         System.out.println("x");
/*  5*/         System.out.println(x);
/*  6*/         System.out.println("x = " + x); // 連結
/*  7*/     }
/*  8*/ }
asiaa1:~/comp2b b08a001$ java IntToString
x
100
x = 100
asiaa1:~/comp2b b08a001$

実は、この演算子 + は文字列の連結です。 一方だけが文字列のときは、他方を文字列に変換して連結するという約束になっています。 整数と整数の足し算も + なので、混乱しそうなら、括弧を使ってください。


6.2 配列(1)

6.2.1 配列とは

変数を用いるとデータを一つ格納できることは、すでに学びました。 たくさんのデータを格納するには、データの個数だけ変数を用意すれば可能です。 しかし、それらのデータを系統的に取り扱うことは困難です。

配列array ) というものを用いると、たくさんのデータを系統的に格納することができます。 配列とは、データの「入れ物」が並んだものと考えてください。 次の図は、配列のイメージです。

配列のイメージ
図 6.1  配列のイメージ

「入れ物」の一つ一つを 配列要素array element ) とよびます。 配列には次のような特徴があります。

6.2.2 配列の使い方

変数を使うためには、変数の宣言が必要でした。 int x; のように変数を宣言すると、変数 x に整数( int 型)が一つ格納できました。

配列を使うためには、配列の宣言と配列の生成という二段階の手続きが必要です。 次のプログラムは、配列を宣言し、生成し、その3番目に整数72を格納し、それを出力するものです。

/*  1*/ class ArrayTest { // 配列のテスト
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] a; // 宣言
/*  4*/         a = new int[10]; // 10個生成
/*  5*/         a[3] = 72; // 3番目に格納
/*  6*/         System.out.println(a[3]); // 3番目を出力
/*  7*/     }
/*  8*/ }
asiaa1:~/comp2b b08a001$ java ArrayTest
72
asiaa1:~/comp2b b08a001$

整数( int 型)の場合、配列の宣言は次のように書きます。

int[] arrayname;

ここで、 arrayname は配列の変数名です。 配列の生成は、

arrayname = new int[size];

と書きます。 ここで、 size は配列の要素数です。

上記のプログラムでは、3行目で変数名が a である配列を宣言しています。 また、4行目で要素数が10である配列を生成しています。

配列要素にデータを格納するには、

arrayname[index] = expression;

と書きます。 index 番目の要素に式 expression の値を格納します。 ここで、 index は数そのものである必要はありません。 数を値に持つならば、変数や式でもかまいません。 例えば、変数 i の値が3で x の値が100ならば、 b[i - 1] = x + 1; によって配列 b の2番目の要素に101が格納されます。 式

arrayname[index]

で、配列の index 番目の要素が取り出せます。 なお、配列の何番目の要素かを表すこの式 index を、配列の 添字subscript ) 、または インデックスindex ) とよびます。

上記のプログラムでは、5行目で配列の3番目の要素にデータ72を格納しています。 また、6行目ではそのデータを取り出して出力しています。

上記のプログラムにおいて、 a [10] は存在しないことに注意してください。 このような、存在しない要素にデータを格納しようとしたり、データを取り出そうとすると、エラーが発生します。

/*  1*/ class ArrayError { // 配列のエラー
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] a;
/*  4*/         a = new int[10]; // 0番目から9番目まで
/*  5*/         a[10] = 100; // 10番目は存在しない
/*  6*/         System.out.println(100);
/*  7*/     }
/*  8*/ }
asiaa1:~/comp2b b08a001$ java ArrayError
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
        at ArrayError.main(ArrayError.java:5)
asiaa1:~/comp2b b08a001$

なお、配列の要素数をどこかに記録しておく必要はありません。 これは、式

arrayname.length

によっていつでも取り出せます。

注意: 教科書によっては、配列の宣言は

int a[];

などと書くと説明しています。 Javaでは、 int[] a;int a[]; は同じ意味です。 ただし、これらを混在させるのは混乱のもとですので、この授業では前者に統一します。

6.2.3 配列の初期化

上記のイメージの通り、配列にデータを格納しましょう。 これは、配列の宣言、配列の生成、配列要素への代入という手順を踏むとできます。 以下はそのようなプログラム(部分)です。

int[] a;
a = new int[10];
a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63;
a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;

次のように書くと、配列の宣言と生成が同時に行えます。

int[] a = new int[10]; // 宣言と生成
a[0] = 99; a[1] = 90; a[2] = 81; a[3] = 72; a[4] = 63;
a[5] = 54; a[6] = 45; a[7] = 36; a[8] = 27; a[9] = 18;

さらに、データの格納も同時に行うことができます。 これは次のように書きます。

int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18};

このことを、配列の 初期化initialization ) とよびます。 配列の初期化では、キーワード new や配列の要素数は書きません。

6.2.4 配列と繰返し

配列のプログラムでは、繰返しを利用するのが普通です。 つまり、ループ制御変数 i を用意し、 for 文などの繰返しの中で、配列要素 a [ i ]からデータを取り出したり、 a [ i ]にデータを格納したりします。

次のプログラムは、配列 a の要素をすべて出力するものです。

/*  1*/ class ArrayPrint { // 配列の出力
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18}; // 初期化
/*  5*/         for (i = 0; i < a.length; i++) { // aの要素数回繰り返す
/*  6*/             System.out.println("a[" + i + "] = " + a[i]);
/*  7*/         }
/*  8*/     }
/*  9*/ }
asiaa1:~/comp2b b08a001$ java ArrayPrint
a[0] = 99
a[1] = 90
a[2] = 81
a[3] = 72
a[4] = 63
a[5] = 54
a[6] = 45
a[7] = 36
a[8] = 27
a[9] = 18
asiaa1:~/comp2b b08a001$

4行目で配列 a を初期化します。 式 a . length の値は10なので、5行目の for 文では変数 i は0から9まで動きます。 6行目で配列要素 a [ i ]の値を詳しく出力します。

6.2.5 配列の使用例

配列の使用例として、はじめに配列要素の総和を求めます。

{100, 200, 100, 300, 200}

で表される配列の要素の合計を、レジの計算の要領で算出します。 つまり、

sum = sum + a[0];
sum = sum + a[1];
sum = sum + a[2];
...

のように計算します。 プログラムは次の通りです。

/*  1*/ class ArraySummation { // 配列の総和
/*  2*/     public static void main (String[] args) {
/*  3*/         int i, sum = 0;
/*  4*/         int[] a = {100, 200, 100, 300, 200};
/*  5*/         for (i = 0; i < a.length; i++) {
/*  6*/             sum = sum + a[i];
/*  7*/         }
/*  8*/         System.out.println("合計は" + sum);
/*  9*/     }
/* 10*/ }
asiaa1:~/comp2b b08a001$ java ArraySummation
合計は900
asiaa1:~/comp2b b08a001$

次の例は、配列要素の最大値を求めるものです。

{100, 200, 100, 300, 200}

で表される配列の要素の最大値は、人間が見れば 300 だと分かります。

この問題をコンピュータで解決するのに、勝ち抜き方式を使うことにします。 これは、はじめに最初の要素をとりあえずチャンピオンにします。 続いて、次の要素とチャンピオンが勝負をし、チャンピオンが負けたら勝者を新たにチャンピオンにします。 これを要素がなくなるまで繰り返します。 最後のチャンピオンが全体のチャンピオンであるというわけです。

具体的には、

max = a[0];
if (a[1] > max) {
    max = a[1];
}
if (a[2] > max) {
    max = a[2];
}
...

のようにして、最大値を求めます。 プログラムは次の通りです。

/*  1*/ class ArrayMaximum { // 配列の最大値
/*  2*/     public static void main (String[] args) {
/*  3*/         int i, max;
/*  4*/         int[] a = {100, 200, 100, 300, 200};
/*  5*/         max = a[0]; // とりあえずチャンピオンにする
/*  6*/         for (i = 1; i < a.length; i++) {
/*  7*/             if (a[i] > max) { // チャンピオンが負けたら
/*  8*/                 max = a[i]; // 勝者をチャンピオンにする
/*  9*/             }
/* 10*/         }
/* 11*/         System.out.println("最大値は" + max);
/* 12*/     }
/* 13*/ }
asiaa1:~/comp2b b08a001$ java ArrayMaximum
最大値は300
asiaa1:~/comp2b b08a001$

最後の例は、棒グラフを描くアプレットです。 グラフにするデータは、架空のクラスの、出席番号1番から8番までの成績です。

表 6.1  架空のクラスの成績
出席番号 1 2 3 4 5 6 7 8
成績 80 60 60 80 90 70 60 60

プログラムは次の通りです。

/*  1*/ import java.applet.*;
/*  2*/ import java.awt.*;
/*  3*/ 
/*  4*/ public class HorizontalBarGraph extends Applet { // 横の棒グラフ
/*  5*/     public void paint (Graphics g) {
/*  6*/         int i;
/*  7*/         int[] a = {0, 80, 60, 60, 80, 90, 70, 60, 60}; // a[0]は使わない
/*  8*/         for (i = 1; i < a.length; i++) {
/*  9*/             g.drawString("" + i, 10, 20 * i); // 数
/* 10*/             g.fillRect(30, -10 + 20 * i, a[i], 10); // 棒
/* 11*/         }
/* 12*/     }
/* 13*/ }
横の棒グラフ
図 6.2  横の棒グラフ

まず、 a [0]を使わないようにして、配列の添字と出席番号を一致させます。

9行目の g.drawString( str , x , y ); は、文字列 str を座標 ( x , y ) に描く文です。 この座標が文字列の左下になるような位置関係です。 整数 i を描く場合、 i は文字列でないので、 "" + i と連結して文字列にしています。 文字列の左下の座標は、(10, 20), (10, 40), (10, 60), ... となるような数式にしています。

10行目では、幅が成績と同じで高さが10の長方形を描いています。 長方形の左上の座標は、(30, 10), (30, 30), (30, 50), ... となるような数式にしています。


6.3 演習6

上記の横の棒グラフを、縦の棒グラフにしてください。 (ヒント: 長方形の左下の座標を考え、そこから左上の座標を逆算してください。)

縦の棒グラフ(VerticalBarGraph)
図 6.3  縦の棒グラフ(VerticalBarGraph)

余力のある人は、例を参考にして、枠を付けるなどしてグラフを見やすくしてください。

縦の棒グラフ(VerticalBarGraph2)
図 6.4  縦の棒グラフ(VerticalBarGraph2)

6.4 レポート課題

今日の演習6の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(5月29日)を明記してください。


6.5 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2009年5月29日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2009 Zenjiro Konishi. All rights reserved.