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

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

目次 索引
6.1 データの入出力(2)
6.1.1 文字列の連結
6.1.2 エスケープ・シーケンス
6.2 配列
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 is " + x);
/*  7*/     }
/*  8*/ }
b04a001@AsiaA1:~/comp2b% java IntToString
x
100
x is 100
b04a001@AsiaA1:~/comp2b%

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

6.1.2 エスケープ・シーケンス

「ターミナル」に"Good afternoon!"と出力するには、

System.out.println("Good afternoon!");

と書きました。 では、ダブルクオートも出力するにはどうすればよいでしょうか。 正解は、

System.out.println("\"Good afternoon!\"");

です。

文字列"\""がダブルクオートの代りになるように、直接扱いにくい文字の代りとなる文字列を、 エスケープ・シーケンスescape sequence ) とよびます。 Javaのエスケープ・シーケンスは以下の通りです。 ここで、タブとは一定のきざみ(たいていは8文字単位)の位置まで設けられる間隔のことです。 データを表のような形式で出力するときに役に立ちます。

表 6.1  エスケープ・シーケンス
\n 改行
\t タブ
\b バックスペース
\r 復帰
\f フォームフィード
\\ バックスラッシュ
\' シングルクオート
\" ダブルクオート

注意: 記号"\"は、場合によって円記号になったりバックスラッシュになったりします。 混乱を避けるため、プログラムでは円記号を入力し、ファイルの文字コードをシフトJISにして保存してください。 コピー・アンド・ペーストした場合は、バックスラッシュを円記号に置き換えてください。

注意: Jeditは文字コードを自動判定しますが、手掛かりが少ないと判定に失敗します。 この対策として、コメントに文字コードの差異が明らかな文字列を入れます。 1行目を"// 文字コード判定用コメント"などとしてシフトJISで保存しますと、文字コードの判定ミスがなくなります。


6.2 配列

6.2.1 配列とは

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

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

An image of an 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];
/*  5*/         a[3] = 72;
/*  6*/         System.out.println(a[3]);
/*  7*/     }
/*  8*/ }
b04a001@AsiaA1:~/comp2b% java ArrayTest
72
b04a001@AsiaA1:~/comp2b%

整数( 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];
/*  5*/         a[10] = 100;
/*  6*/         System.out.println(100);
/*  7*/     }
/*  8*/ }
b04a001@AsiaA1:~/comp2b% java ArrayError
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
        at ArrayError.main(ArrayError.java:5)
b04a001@AsiaA1:~/comp2b%

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

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 配列のコピー

整数( int 型)の変数 x から変数 y にコピーするには、代入文 y = x; でできます。 しかし、配列の変数 a の要素から変数 b の要素にコピーするには、 b = a; ではできません。 一つ一つ配列要素をコピーする必要があります。

次のプログラムは、配列 a の要素から配列 b の要素にコピーし、 b の要素を出力するものです。

/*  1*/ class ArrayCopy {
/*  2*/     public static void main (String[] args) {
/*  3*/         int i;
/*  4*/         int[] a = {99, 90, 81, 72, 63, 54, 45, 36, 27, 18};
/*  5*/         int[] b = new int[a.length];
/*  6*/         for (i = 0; i < a.length; i++) {
/*  7*/             b[i] = a[i];
/*  8*/         }
/*  9*/         for (i = 0; i < b.length; i++) {
/* 10*/             System.out.println("b[" + i + "] is " + b[i]);
/* 11*/         }
/* 12*/     }
/* 13*/ }
b04a001@AsiaA1:~/comp2b% java ArrayCopy
b[0] is 99
b[1] is 90
b[2] is 81
b[3] is 72
b[4] is 63
b[5] is 54
b[6] is 45
b[7] is 36
b[8] is 27
b[9] is 18
b04a001@AsiaA1:~/comp2b%

5行目で、配列 a と同じ要素数の配列 b を宣言し、生成します。 6行目から8行目でコピーが行われます。 式 a.length の値は10ですので、6行目の for 文では変数 i は0から9まで動きます。 これは、配列 a (および配列 b )の添字の範囲と一致します。 9行目から11行目で配列 b の要素を詳しく出力します。

6.2.5 配列の使用例

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

{100, 200, 100, 300, 200}

で表される配列の要素の合計を、レジの計算の要領で算出します。 プログラムは次の通りです。

/*  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("The sum is " + sum);
/*  9*/     }
/* 10*/ }
b04a001@AsiaA1:~/comp2b% java ArraySummation
The sum is 900
b04a001@AsiaA1:~/comp2b%

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

{100, 200, 100, 300, 200}

で表される配列の要素の最大値は、人間が見れば 300 だと分かります。 この問題をコンピュータで解決するのに、勝ち抜き方式を使うことにします。 これは、はじめに最初の要素をとりあえずチャンピオンにします。 続いて、次の要素とチャンピオンが勝負をし、チャンピオンが負けたら勝者を新たにチャンピオンにします。 これを要素がなくなるまで繰り返します。 最後のチャンピオンが全体のチャンピオンであるというわけです。 プログラムは次の通りです。

/*  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("The maximum value is " + max);
/* 12*/     }
/* 13*/ }
b04a001@AsiaA1:~/comp2b% java ArrayMaximum
The maximum value is 300
b04a001@AsiaA1:~/comp2b%

最後の例は、以下の長方形の総面積を計算するものです。

表 6.2  長方形の大きさ
No. 0 1 2 3 4
20 50 40 10 60
高さ 30 10 20 70 10

このような表で表されるデータは、配列を2つ用意し、添字を使って配列要素を結び付けるとうまく処理できます。 このように使われる配列を 並列配列parallel array )とよびます。 この場合ですと、長方形の幅を配列 width に格納し、高さを配列 height に格納します。 すると、0番目の長方形は、幅 width [0], 高さ height [0], 1番目の長方形は、幅 width [1], 高さ height [1], ... となるわけです。

総面積を計算するには、 i 番目の長方形の面積 areawidth [ i ] * height [ i ] で求め、 area の値を areaSum に足していきます。 プログラムは次の通りです。

/*  1*/ // 文字コード判定用コメント
/*  2*/ class RectangleArea {
/*  3*/     public static void main (String[] args) {
/*  4*/         int i, area, areaSum = 0;
/*  5*/         int[] width = {20, 50, 40, 10, 60};
/*  6*/         int[] height = {30, 10, 20, 70, 10};
/*  7*/         System.out.println("No.\tWidth\tHeight\tArea");
/*  8*/         for (i = 0; i < width.length; i++) {
/*  9*/             area = width[i] * height[i];
/* 10*/             areaSum = areaSum + area;
/* 11*/             System.out.print(i + "\t");
/* 12*/             System.out.print(width[i] + "\t");
/* 13*/             System.out.print(height[i] + "\t");
/* 14*/             System.out.println(area);
/* 15*/         }
/* 16*/         System.out.println("Total\t\t\t" + areaSum);
/* 17*/     }
/* 18*/ }
b04a001@AsiaA1:~/comp2b% java RectangleArea
No.     Width   Height  Area
0       20      30      600
1       50      10      500
2       40      20      800
3       10      70      700
4       60      10      600
Total                   3200
b04a001@AsiaA1:~/comp2b%

6.3 演習6

ある町で、前夜祭と4日間に渡るお祭りが行われたとします。 以下の来客数のデータを配列 male および female に格納して、一日ごとの来客数と全日程の来客数を計算してください。 ここで、前夜祭は0日目と考えます。

表 6.3  お祭りの来客数
日程 前夜祭 1日目 2日目 3日目 4日目
来客数(男) 50 90 70 60 50
来客数(女) 50 80 60 50 50

このデータを処理するアルゴリズムを考え、プログラムを作成してください。

b04a001@AsiaA1:~/comp2b% java FestivalGuest
Day     Male    Female  Total
0       50      50      100
1       90      80      170
2       70      60      130
3       60      50      110
4       50      50      100
Total                   610
b04a001@AsiaA1:~/comp2b%

余力のある人は、全日程の男性来客数と女性来客数も計算してください。

b04a001@AsiaA1:~/comp2b% java FestivalGuest
Day     Male    Female  Total
0       50      50      100
1       90      80      170
2       70      60      130
3       60      50      110
4       50      50      100
Total   320     290     610
b04a001@AsiaA1:~/comp2b%

6.4 レポート課題

今日の演習6の答案(Javaプログラム)をメールで提出してください。 メールの送信には学内のコンピュータ(メール・サーバ)を用い、送信先はkonishi@twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(5月20日)を明記してください。


6.5 参考文献


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

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