配列


月を数字で入力して, 対応する英単語を答えるプログラムを書いてみよう.
import java.io.*;
class AnswerMonth{
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    System.out.print("月(1-12)を入力して下さい  ");
    // 入力をおこなう前に, バッファリングされていた出力を出してします
    System.out.flush();
    String s=d.readLine();
     // 文字列をint型に変換する. 
    int month=Integer.parseInt(s);
    // 入力した月が1より小さい時,12より大きい時は次の if 文を実行します
    if(month<1 || month>12) System.out.println(month+"月はありません");
    if(month==1) System.out.println("1月は January です. ");
    if(month==2) System.out.println("2月は Febrary です. ");
    if(month==3) System.out.println("3月は March です. ");
    if(month==4) System.out.println("4月は April です. ");
    if(month==5) System.out.println("5月は May です. ");
    if(month==6) System.out.println("6月は June です. ");
    if(month==7) System.out.println("7月は July です. ");
    if(month==8) System.out.println("8月は August です. ");
    if(month==9) System.out.println("9月は Sepember です. ");
    if(month==10) System.out.println("10月は October です. ");
    if(month==11) System.out.println("11月は November です. ");
    if(month==12) System.out.println("12月は December です. ");
  }
}
ここで,
    if(month<1 || month>12) System.out.println(month+"月はありません");
の「||」は複数の条件式の論理和をあらわす.(A||B)は「AまたはB」という意 味で,すなわち条件Aか条件Bのどちらかが真になると真になる.この条件式は 「monthの値が1より小さいとき,またはmonthの値が12より大きいとき」とい う意味である.

この逆が「&&」で論理積となる.(A&&B)は「AかつB」という意味で,条 件Aか条件Bの両方が真のときのみ真になる.

これで動くことは動くがあまりすっきりしないプログラムである. これを, ように書き直してみよう.
import java.io.*;
class AnswerMonthWithIf{
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    System.out.print("月(1-12)を入力して下さい  ");
    // 入力をおこなう前に, バッファリングされていた出力を出してします
    System.out.flush();
    String s=d.readLine();
     // 文字列をint型に変換する. 
    int month=Integer.parseInt(s);
    if(month<1 || month>12) System.out.println(month+"月はありません");
    else {
     String mname="";
     if(month==1) mname="January";
     else if(month==2) mname="Febrary";
     else if(month==3) mname="March";
     else if(month==4) mname="April";
     else if(month==5) mname="May";
     else if(month==6) mname="June";
     else if(month==7) mname="July";
     else if(month==8) mname="August";
     else if(month==9) mname="September";
     else if(month==10) mname="October";
     else if(month==11) mname="November";
     else if(month==12) mname="December";
     System.out.println(month+"月は "+mname+" です. ");
   }
  }
}
これで, すっきりとしたことはすっきりとしたが, else ifの繰り返しはまだ まだうっとおしい. 前のページのプログラムの
     else if(month==5) mname="May";
     else if(month==6) mname="June";
のような, 整数の値によって, 変数の値が変わるといったパターンを簡潔にプ ログラムするために, 多くのプログラム言語では配列が用意されている.
配列 を使ってプログラムを書き直すと次のようになる.
import java.io.*;
class AnswerMonthWithArray{
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    System.out.print("月(1-12)を入力して下さい  ");
    // 入力をおこなう前に, バッファリングされていた出力を出してします
    System.out.flush();
    String s=d.readLine();
     // 文字列をint型に変換する. 
    int month=Integer.parseInt(s);
    // 文字列の配列型の変数 mnames を宣言し,大きさ12を確保する.
    String mnames[]=new String[12];
    mnames[0]="January";
    mnames[1]="Febrary";
    mnames[2]="March";
    mnames[3]="April";
    mnames[4]="May";
    mnames[5]="June";
    mnames[6]="July";
    mnames[7]="August";
    mnames[8]="September";
    mnames[9]="October";
    mnames[10]="November";
    mnames[11]="December";
    if(1<=month && month<=12)
      System.out.println(month+"月は "+mnames[month-1]+" です. ");
    else 
      System.out.println(month+"月はありません");
  }
}

上のように
String mnames[]
と書くと文字列の配列を入れるmnames という名前の変数を宣言したことにな る. '='の右側のnew String(12)で大きさ12の配列を確保して初期化している.

配列型の変数の参照は 「変数名[添字]」のようにしておこなう. 添字は1で はなく0から始まることに注意しよう. 添字はint型でなくてはいけない.

これまでのように,箱のたとえで表したのが下の図である.mnamesという箱の中 から,同じ箱が12個並んだ配列への矢印が書いてある.一番左の箱は,mnames[0]で, 一番右の箱はmnames[11]で参照できるということになる.

配列の箱のたとえ

配列の宣言の際は,
  String mnames[];
のように,[]を変数名の後ろにつけても
  String[] mnames;
のように,型名の後ろにつけても同じ意味になる.ただし,複数の変数を宣言す る場合には注意が必要になる.
  String mnames0[],mnames1;
と書くと,mnames1はStringの配列ではなくStringであると宣言されるのに対して,
  String[] mnames0,mnames1;
と書くと,mnames1はStringの配列になる.
C言語やC++言語では,mnames自体が大きさ12個の箱になっている.そのため, 配列型の変数の代入をおこなう場合は,箱のサイズ分の繰り返しが必要となり, 重い操作になっている.それでは不便なので,ポインタや参照というJava 言語 におけるmnamesのような小さい箱が別に用意されているが,これがC言語やC++ 言語を複雑にしている原因にもなっている.
float型,double型の変数を添字に使うのはキャスト演算子「(型名)式」でint 型に変換すれば可能だが,そうする必要がある場合の多くはその変数は本来 int型にすべきである.特に,ループの繰り返しを判定する変数などを, float, doubleにすると誤差により,ループの回数が意図しない回数になる可 能性がある.この場合は大(double)は小(int)を兼ねない.

なお,上のプログラムではまだ配列を使う嬉しさが分からないかもしれないが, 配列の初期化を一度におこなう構文を使った.以下のプログラムになれば,嬉 しさがわかるだろう.

import java.io.*;
class AnswerMonthWithArray{
  public static void main(String[] args) throws IOException{
  // 入力をするためには,System.inからBufferedReaderを作らなくてはいけない
    BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
    System.out.print("月(1-12)を入力して下さい  ");
    // 入力をおこなう前に, バッファリングされていた出力を出してします
    System.out.flush();
    String s=d.readLine();
     // 文字列をint型に変換する. 
    int month=Integer.parseInt(s);
    // 文字列の配列型の変数 mnames を宣言し,{}の中身で初期化する.
    String mnames[]={"January","Febrary","March","April","May","June",
                     "July","August","September","October",
                     "November","December"};
    if(1<=month && month<=12)
      System.out.println(month+"月は "+mnames[month-1]+" です. ");
    else 
      System.out.println(month+"月はありません");
  }
}
なお,
    String mnames[]={"January","Febrary","March","April","May","June",
                     "July","August","September","October",
                     "November","December"};
    String mnames[];
    mnames={"January","Febrary","March","April","May","June",
            "July","August","September","October",
            "November","December"};
のように, 宣言と代入に分けて書くことはできない.
次に進む