JAVAの序章


はじめに

この文書は変数や分岐などJAVAの本当に基礎な部分を扱います。質問などがあったらにメールなどで教えてください。コンパイルができないなどの開発環境に関する質問はサポートしきれないかもしれないのでご了承ください。

とりあえずこの辺は既に理解していると思うので今はさっさと作って後で詳しく説明を加えていきたいと思います。なお、急いで作っているため説明用のプログラムはデバッグしていません。そのため、もしプログラムにミスがあったら教えてくださるようお願い申し上げます。

目次


JAVAを始めるにあたって


プログラムとはコンピュータにさせる仕事を既述した文書です。コンピュータはそれに従って処理を行います。まずはプログラムというものがどういうものなのか、実際に見てみることにしましょう。
class Js_1_1{
    public static void main(String[] args){
        System.out.println("Hello World!");
        System.out.println("This is a program.");
    }
}
次のプログラムは画面にHello World! This is a program.と表示するプログラムです。ここではこのプログラムの動かし方について説明します。まず、このプログラムをJs_1_1.javaとしてセーブします。ファイル名はこれでなければなりません。ファイル名は1行目のclassの後にくる名前(ここは自分の好きな名前で良い)に.javaを後ろに付け加えたものになります。
次にこのファイルをコンパイルします。コンパイルというのはJAVAファイルをコンピュータの認識できるCLASSファイルに変換する処理のことを指します。また、このような処理を行うソフトのことをコンパイラと呼びます。コンパイルの仕方は開発環境によって異なりますが、コマンド入力式では
javac Js_1_1.java
と入力してください。もし大量にErrorなどのメッセージが表示されたらそれはプログラムが正しい記述を行っていないため、変換の処理が行われなかったことを意味します。ここで表示されるメッセージのことをエラーメッセージとかwarningとか言うことが多いです。このメッセージはプログラムのどの部分がどのような過ちを犯している可能性があるのか指摘してくれるので、このメッセージを解釈できるようになるのがプログラミング技術修得の上で非常に重要になってきます。一流のプログラマーなら、エラーメッセージが現れた瞬間に自分の犯したミスを一瞬で見抜いてあっという間にプログラムを直してしまいます。ですから、もし誤ったプログラムを書いてしまった場合は自分がどのような過ちを犯したことによってどのようなエラーメッセージが表示されたのかよく覚えておくと次からのプログラム修正の速度が速くなるでしょう。また、このような状態になることをコンパイルエラーと言います。もし正しくプログラムが書けていたらJs_1_1.classが生成されます。そしてプログラムを実行するときは
java Js_1_1
と入力して下さい。画面に文字が表示されたはずです。
さて、ここで先ほどのプログラムの解説をしましょう。
最初の2行は、今の時点ではプログラムを開始する“おまじない”だと思ってください。{と}はまとまりを表す記号で、ここではclass Js_1_1の後の{と一番最後の}で囲まれた中に、mainというものがあってさらに{と}の内側に処理を書いていくものだ と思ってください。つまり、実際に画面に表示するという処理にかかわってくるのは3,4行目です。
System.out.println()というのは、画面に文字を表示するメソッドの一種です。メソッドについては次の文書で説明しますが、ここではコンピュータに対して行う命令だと思ってください。printlnの中の半角の"で囲まれた中の文(文字の塊と考え、これを文字列と呼びます)が表示されます。System.out.print()というのもありますが、こちらは改行を行いません。
では、行の最後についているセミコロンは一体なんでしょう?これは命令と命令を区切る記号なのです。最初のうちは入れ忘れがちですがこれを入れないとコンパイルエラーが起こるので気をつけてください。なお、改行はプログラム解釈の上では意味を持たないので、1行内で複数のセミコロンで区切ることもできるし、1つの命令を数行に渡って記述することもできます。つまり次のようなプログラムでもよいのです。
class Js_1_1{
	public static void main(String[] args){System.out.println("Hello World!");System.out.println("This is a program.");}
}
しかし、このようなプログラムはみにくくて後で見返すときに解釈が困難になります。プログラムは長くなれば長くなるほど自分の作ったプログラムでさえ、理解が困難になってきます。そのためプログラムの見易さは非常に重要になってきます。自分でプログラムに注釈をつけることもできます。
/*
Hello Worldと表示するプログラム。
*/
class Js_1_1{
    public static void main(String[] args){//メインのプログラム部分
	System.out.println("Hello World!");
	System.out.println("This is a program.");
    }
}
/*と*/で囲まれた部分は注釈と呼ばれ、プログラムの説明などによく使われます。もし/*、*/がないとその部分が処理の上で何か意味をもつ命令なのではないかとコンパイラ側が解釈し、コンパイルエラーを起こしてしまいます。なので/*と*/で囲み、この部分が意味を持たない文字列であることをアピールする必要があるわけです。また、//とすればそこから行末までが注釈文になります。

Go to Index

変数の使い方


変数とはコンピュータに数値や文字列などの情報を記憶させておく場所のことを言います。まずは次のプログラムを見て下さい。
class Js_1_2{
	public static void main(String[] args){
		int a,b,c;//説明の都合上ここを1行目とする。
		a=1;b=2;
		c=a+b;
		System.out.println("cの値は"+c);
		a=a-b;
		System.out.println("aの値は"+a);
	}
}
これを実行すると3が表示されます。このプログラムの意味を説明していきましょう。 1行目は変数の宣言と呼ばれます。int a,b;というのは、aとbを整数として扱われる変数として定義する、という意味になります。実数として扱いたかったらdoubleとしてください。この文がないとそれ以降の行で変数を使ってもコンパイラ側はaやbを正体不明の文字として解釈し、コンパイルエラーとなってしまいますので気をつけましょう。 2行目は代入と呼ばれます。=は代入を行う演算子で、a=1;は変数aに1という値を代入することを意味します。a=b;という文ならaにbの値を代入することを意味します。ちなみに先ほどの変数の宣言と代入を同時に行うこともできます。これは変数の初期化と呼ばれこのように記述するだけです。
int a=1,b=2;
3行目では足し算という演算を行い、その結果を変数cに代入しています。+は算術演算子の一種です。
ところで5行目の式は数学的には不可解な式に見えてしまうかもしれません。しかしこの式は正しい式です。この式の意味は「aの値からbの値を引き、その値を改めてaの値としてセットする」となります。
4行目のSystem.out.printlnの中身、「"cの値は"+c」について説明をしておきましょう。これは文字列"cの値は"と変数cの値を連結し、連結した文字列を表示するという意味です。ここで+"c"としてしまうとcという文字が表示されてしまうし、"を省略するとコンパイラが「cの値は」という変数として解釈してしまうのでコンパイルエラーとなります。"の記号は、その中の文が変数名ではなくて文字列であることを示す記号だったのです。

Go to Index

条件分岐、繰り返し


プログラムに欠かせないのは条件分岐、繰り返しです。
import java.io.*;

class Js_1_3{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		System.out.print("A=?");
		int a=Ineteger.parseInt(bf.readLine());
		System.out.print("B=?");
		int b=Ineteger.parseInt(bf.readLine());
		if(a==b){
			System.out.println("AとBは等しい");
		}else{
			System.out.println("AとBは異なる");
		}
	}
}
1行目はキーボードからの入力を可能にするためのおまじないだと思ってください。import java.io.*;も同様です。
3,5行目はキーボードから入力された数値を変数に代入する部分だと思ってください。もうすこし性格に言うと、bf.readLine()で入力された文字列を受け取り、それを数値に変換して変数に代入している、と思ってください。
さて、メインの条件分岐について説明しましょう。ここではif文を説明します。構造は次のようになっています。
if(条件文){
	条件文が真の場合の処理
}else{
	条件文が偽の場合の処理
}
上の例で言えば、a==bが条件文になります。==の記号は比較演算子と呼ばれるものの1つで、aとbが等しければ真(true)、そうでなければ偽(false)となります。=が2つなのは代入の演算子=と区別するためです。
{と}で囲まれた部分は処理を1つのまとまりとして捉えるときに用いる記号で、上の場合は真の場合の処理・偽の場合の処理をまとめるために用いています。まとまりがはっきりするようにインデントを下げるのが習慣です。Muleでは編集しているファイルの拡張子が.javaならTABを押すことで自動的にインデントを調節してくれるので活用してください。
キーボードから入力された文字が数値で無いかもしれません。このような時、Integer.parseIntという文字列を数値に変換するメソッド(関数のようなものだとここでは思って下さい)は困ってしまいます。このような場合、例外というものが発生します。ここでは詳しく説明しませんが、mainの語尾にくっついたthrows Exceptionは例外が発生するかもしれませんよ〜ということを意味するものだと思っておけばいいです。

次に、繰り返しを説明します。
import java.io.*;

class Js_1_4{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		System.out.print("N=?");
		int n=Integer.parseInt(bf.readLine());
		int sum,i;
		i=1;
		while(i<n){
			sum+=i;
			i++;
		}
		System.out.println(sum);
	}
}
このプログラムは1からn-1までの和を計算するプログラムです。sum+=iはsum=sum+iと同じです。i++はi=i+1と同じで、iの値を1増やすという意味です。ここで注目すべきはwhile文です。while文の構造は次のようになっています。
while(条件文){
	条件文が真の間繰り返す
}
上の場合、i小なりnの間文のなかを繰り返すわけですからi=1,…n-1のすべてについてwhile文の中が実行されるわけです。結果としてsumに1からn-1までのすべての値が足され、我が求まるというわけです。
また。1回目で既に条件文が偽なら{}の中は1度も実行されないということを覚えておきましょう。
他に便利な繰り返しにforがあります。構造は次のようになります。
for(文1;条件文;文2){
	処理
}
これは次の文と同値です。
文1;
while(条件文){
	処理
	文2;
}
これを用いると先程のプログラムは次のようになります。
class Js_1_4{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		int n=Integer.parseInt(bf.readLine());
		int sum,i;
		for(i=1;i<n;i++){
			sum+=i;
		}
		System.out.println(sum);
	}
}
なんとなくさっきよりi=1,2,…,n-1を繰り返すというこのプログラムの目的がはっきりしたような気がしませんか?
ループを抜けるbreak文も説明します。
import java.io.*;

class Js_1_5{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		System.out.print("n=?");
		int n=Integer.parseInt(bf.readLine());
		int sum,i;
		for(i=2;i<n;i++){
			if(n%i==0){
				break;
			}
		}
		if(i==n){
			System.out.println("nは素数");
		}
	}
}
これはnが素数かどうか判定するプログラムです。n%iは余りを求める演算子で、それが0と等しい場合、ということはnがiで割り切れる場合、ということになります。また、上のように{}の中にさらに条件分岐や繰り返しを持ってくることが可能でこのような構造のことを入れ子構造と言います。
break文は、繰り返しを抜ける文です。ここではi<nが満たされているかどうかに関わらずbreak文が実行されると繰り返しを抜けます。結局if(i==n){の行に飛ぶわけです。ここで注目しておきたいのは、break文で抜けた場合iは2,3,…n-1のいずれかであるという点です。それに対し、最後までbreak文が実行されない場合(つまり、nが2以上n未満の数で割り切れない場合)はi<nが偽になって初めてループを抜けるので、この場合iはnになります。よってiがnの場合が素数なので上のようなプログラムになるわけです。

Go to Index

変数の型、型変換


そもそもパソコンは0と1の2進数でデータを表現します。変数も何桁の2進数で表されるということで分類されます。2進数の桁数はビットという単位であらわされ、8ビットを1バイトと呼びます。
ここでは様々な変数の型を挙げることにします。
char半角1文字を扱う変数の型。1バイトデータ。
byte1バイトの整数型。-128〜127
short2バイトの整数型。-32768〜32767
int4バイトの整数型。-2^31〜2^31-1
long8バイトの整数型。-2^63〜2^63-1
float4バイトの実数型。小数×10の何乗の形であらわされるので浮動小数点とも言われる。
double8バイトの実数型。
boolean真偽値を扱う変数の型。値はtrue,falseのいずれか
ここでbooleanに注目してください。実はこれ、先程の条件文と呼ばれるものの正体なのです。a==bという文はaとbが等しければtrueという値をもち、異なればfalseと言う値を持つのです。これを活用すれば例えば
while(true){
	処理
}
これは無限ループを意味します。
異なる変数を扱うときには型変換という作業が必要になります。次の文を見て下さい
import java.io.*;

class Js_1_5{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		System.out.print("n=?");
		int n=Integer.parseInt(bf.readLine());
		double a=(double)n;
		double b=Math.sqrt(a);
		int c=(int)b;
		System.out.println("Aの平方根を整数で表すと"+b);
	}
}
Math.sqrtは平方根を求めるメソッドです。このメソッドはデータをdouble型で扱います。ここで、int型のdouble型という異なるデータの型に変換するときは型変換という処理が必要になります。(int)と書くとint型のデータに変換され、(double)と書くとdouble型のデータに変換されます。これを明記しないと原則的にはコンパイルエラーになります。
しかし、上の()ではさまれた文はサイズが大きくなるときは基本的には不必要です。例えば(double)は必要ありません。でも気になるなら書いておくのが無難でしょう

Go to Index

様々な演算子


最後に様々な演算子を挙げて置くことにします。
算術演算子
A+BAとBの和を計算する演算子
A-BAからBを引く演算子
A*BAとBの積を計算する演算子
A/BAとBが整数型ならAとBの商を計算し、A・Bのいずれかが実数型なら割り算を行う演算子
A%BAとBの余りを求める演算子
A++A=A+1と同じだがこちらの方が速い
A--A=A-1と同じだがこちらの方が速い
A(演算子)=BA=A(演算子)Bと同じ。例えばA+=3はA=A+3と同じである。

比較演算子・論理演算子(演算の結果がboolean型、つまりtrue・falseのいずれかになる演算子。IF文の条件文とかに使われる。)
A==BAとBを比較し、等しければ値はtrueに、そうでなければfalseとなる。(以下わかりやすいようにtrueを真と呼ぶ。以下の表現はA⇒trueだが、すべて¬Aならfalseとなる。)
A!=BAとBが異なれば真
A<BA小なりBなら真
A>BA大なりBなら真
A<=BAがB以下なら真
A>=BAがB以上なら真
!Aboolean型のAがfalseなら真。その意味でA==falseに同じ。
A && Bboolean型のA,Bが共にtrueなら真
A || Bboolean型A,Bのいずれかがtrueなら真

Go to Index

配列


配列変数とは数学で言う数列のようなものです。具体的に使ったプログラムを見てみましょう。
import java.io.*;

class Js_1_6{
	public static void main(String[] args) throws Exception{
		BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));//ここを1行目とする。
		System.out.print("n=?");
		int n=Integer.parseInt(bf.readLine());
		int i;
		int[] a=new int[n];
		a[0]=1;a[1]=1;
		for(i=2;i<n;i++)
			a[i]=a[i-1]+a[i-2];
		for(i=0;i<n;i++)
			System.out.println("数列の第"+(i+1)+"項は"+a[i]);
	}
}
上のプログラムはフィボナッチ数列の各項を求めるプログラムです。
まず、for文の後の{}が抜けていますが、{}文の中身が1つの文である場合、{}を省略できるので覚えておきましょう。ただ、if文とかは構造がわかりにくくなる原因となるので文が1つでも{}をつけたほうがいいです。
さて、本題に入ります。配列は、 変数[添え字] の形で使用します。しかし、その前にまず配列変数を使うための準備が必要です。あらかじめ配列はその添え字がどのくらいの大きさになりうるかを教えてあげなければなりません。その、大きさを教える作業と宣言の仕方を以下に示します。
・宣言の仕方
(変数の型)[] 変数名;
または
(変数の型) 変数名[];

・配列の大きさの指定の仕方
変数名=new 変数の型[大きさ(int型であること)];

これらをまとめてやると

(変数の型)[] 変数名=new 変数の型[大きさ(int型であること)];

となります。宣言だけして配列の大きさの指定を忘れると、実行時にエラーが発生するので気をつけてください。
さて、大きさの指定が終わったら早速使用が可能になります。int a=new int[n];と宣言したなら、使えるようになる変数はa[0],a[1],…,a[n-1]です。a[n]は使用できません。添え字が負になったりn以上になったりすると配列オーバーというよく発生しがちなエラーが生じるので配列を使うときは添え字の値に十分注意しましょう。この性質上、上のJs_1_6.javaでは数列の第1項から第n項を表すのに添え字を1減らしたa[0]〜a[n-1]を対応させています。これらの性質さえ理解していれば、後は普通の変数と扱い方は同じなので特にこれ以上説明はしません。サンプルプログラムをよく見てどのような処理を行っているのか理解してください。
今は不必要ですがメソッドなどを使い出すと、配列を使っている途中でその配列の大きさを知りたくなることがあります。配列の大きさは次のような文で得ることができるので覚えておきましょう。

配列変数名.length

なお、配列の大きさをあまりに大きくしすぎるとコンピュータ側はそんなたくさんの変数を用意できないといってエラーを起こしてしまいます。このようなエラーをメモリーオーバーと言います。

さて、配列は実は2次元3次元の添え字をもたせた配列も存在します。覚えておきましょう。

2次元の場合
(変数の型)[][] 変数名=new 変数の型[大きさ][大きさ];
多次元の場合
(変数の型)[][]… 変数名=new 変数の型[大きさ][大きさ]…;

Go to Index