import java.io.*;
class Test8{
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 Test9{
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 Test10{
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[]と書くと文字列の配列を入れるmnames という名前の変数を宣言したことにな る. '='の右側の内容で配列の内容を初期化している. 配列の要素数(大きさ)は この例では12である.
配列型の変数の参照は 「変数名[添字]」のようにしておこなう. 添字は1で はなく0から始まることに注意しよう. 添字はint型でなくてはいけない.
float型,double型の変数を添字に使うのはキャスト演算子「(型名)式」でint 型に変換すれば可能だが,そうする必要がある場合の多くはその変数は本来 int型にすべきである.特に,ループの繰り返しを判定する変数などを, float, doubleにすると誤差により,ループの回数が意図しない回数になる可 能性がある.この場合は大(double)は小(int)を兼ねない.
注意)
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"};
のように, 宣言と代入に分けて書くことはできない.
class Test11{
public static void main(String[] args){
int n=1000,i,k;
int p[]=new int[n+1];
for(i=2; i<=n; i++) p[i]=1; // i++はi=i+1と同じ意味
for(i=2; i<=n; i++)
if(p[i]==1){
System.out.print(i+" ");
for(k=2; i*k<=n; k++) p[i*k]=0;
}
}
}
このプログラムでは p という配列が使われている. iが素数の可能性がある
時はp[i]が1, 合成数の時はp[i]が0になるように計算していく. 配列の宣言と
作成は,
int p[]=new int[n+1];
の部分である. これは,
int p[];
p=new int[n+1];
という2つの文に分けて書いても良い(続けて書かなくても良い). newは配列や
オブジェクトの生成を表す予約語で, 次のintは要素の型を示す. [n+1]は作成
する配列の大きさ(要素数)が n+1 であることを示す. 配列の大きさを宣言時
に決定しなくてもよいのは, Javaの特徴の1つである.
上のプログラムで素数が求まる原理が分かりにくいかもしれない. は
いぱーワークブック「プログラミング」でも
配列によるチェックのページでほとんど同じプログラムを扱っているので,
分からない人はそちらの説明を見て欲しい.
注)上のプログラムでは int の配列を使っているが, よりJavaらしく書くなら
boolean(真偽値を表す型)の配列を使って
class Test12{
public static void main(String[] args){
int n=1000,i,k;
boolean p[]=new boolean[n+1];
for(i=2; i<p.length; i++) p[i]=true;
for(i=2; i<p.length; i++)
if(p[i]){
System.out.print(i+" ");
for(k=2; i*k<=n; k++) p[i*k]=false;
}
}
}
のように書く. なお配列型の変数に .lengthをつけて p.lengthのようにする
と, その配列の要素数を返す.
これまで, 呪文のように打ち込んできた
public static void main(String[] args){
の「String[] args」の部分は, 実は文字列の配列である引数(「ひきすう」と
読む. 外から値を渡すためのものだが, 中から見ると初期化済の変数と思って
良い)だとわかる. 実は, java を起動する時に
java プログラム名 a1 a2 .. an
のように後ろに空白で区切って文字列をいくつか書くと
args[0] <- "a1"
args[1] <- "a2"
..
args[n-1] <- "an"
のように配列argsの中に渡すことができる. この機能を利用して, 次の
プログラムを書いてみる.
class Test13{
public static void main(String[] args){
for(int i=args.length-1;i>0;i--)
System.out.println(args[0]+args[i]);
}
}
このプログラムをコンパイルして,
java Test13 I can read this file.
と実行すると,
ktanaka@ux019> java Test13 I can read this file.
Ifile.
Ithis
Iread
Ican
という出力が得られる.
次に進む