Javaでプログラミングを行うということは、Javaという言語の文法規則に従ってプログラムを記述するということにほかなりません。そのJavaというプログラミング言語の基本的な規則を体験してみましょう。プログラムの中でデータを扱うもっとも基本的なやり方である「変数」について理解していただきます。また、処理結果を簡便に表示するJavaコンソールのプログラムでの使い方も説明しましょう。
この章で作るプログラムは、前の章とは別のプロジェクトに入れておくことにしましょう。復習を兼ねてもう一度手順を追って説明をします。JBuilderを起動してから以下の手順を行なって下さい。
1「ファイル」メニューの「新規」から「プロジェクト」を選択します。なお、「ファイル」メニューの「新規」は、ツールバーの「新規」ボタンと同じ機能です。
2「ウィザードを選択」と書かれたウインドウが表示されています。ここでは、リストから「Javaプロジェクト」を選択し、「次へ」ボタンをクリックします。
3「Javaプロジェクトを作成します。」と書かれたウインドウが表示されます。ここで、「プロジェクト名」の部分に「JavaBasic」とキータイプします。「次へ」ボタンをクリックします。
4「Java設定」と書かれたウインドウになりました。ここではいろいろな設定ができますが、通常はそのまま「終了」ボタンをクリックしてください。従って、通常は手順3で「終了」ボタンをクリックしてもかまいません。
5この章のプログラムを入れておくプロジェクトができあがりました。「JREシステム・ライブラリー」という項目が自動的に追加されますが、そのままでかまいません。
次に、作成したプロジェクトに、実際に動かすアプリケーションのひな形を追加します。次のように作成します。前の手順の続きで行なっているものとします。
1新たに作ったプロジェクトの「JavaBasic」をウインドウ左側のボックスで選択している状態で、ツールバーの「新規」ボタンの右側の▼をクリックします。そして、メニューから「クラス」を選択します。
2「新規Javaクラス」というタイトルが設定されたウインドウが表示されます。ここでは、パッケージのところに「javabasic」、クラス名として「JavaBasic」とキータイプします。また、「public static void main(String[] args)」のチェックボックスをオンにします。ほかは最初の設定から変更はしなくてもかまいません。「終了」ボタンをクリックします。
以上の作業で、プロジェクトにアプリケーションが加わり、実行するとアプリケーションが起動するようになります。アプリケーション本体のソースプログラムがJavaBasic.javaです。
アプリケーションを追加した後、最初から用意されているプログラムを少し目を通してください。しかしながら、すべてを理解しなくてもかまいません。たとえば、public static void mainって何だ? と思われるかもしれませんが、これらについても、今週はともかくこうするものだということで流してください。
JavaBasic.javaを左側のリストでダブルクリックするなどして中央でその内容が見えるようにして、その中身を読んでみましょう。前の章で説明したように、/* 〜 */は複数の行にわたって「コメント」と呼ばれるプログラムの実行には関係ない部分です。ファイルにメモや情報を残すために使われます。JBuilderはコメントは自動的に緑色の文字になるので、ぱっとみてわかりやすいでしょう。1つのポイントとして、プログラムの20行目に、
public class JavaBasic {
という記述があります。ここでの、{ から、ファイルいちばん最後の }までが1つのブロックであり、これが、アプリケーションの中核をなす部分です。とりあえず、JavaBasicというのがそのアプリケーションの名前なのですが、Javaでは通常、ファイル名と同じ名前のこうした宣言があるのが一般的です。
そして、少しだけプログラムを追うと、
public static void main(String[] args) {
という部分が見つかります。ここでの{ から }までの部分は、アプリケーションを実行した直後に自動的にこの部分のプログラムが呼び出されると思っていて下さい。なお、classの { } の中にこの { } が包含されています。こうした状況を「ネストしている」などと言われますが、プログラムではこうしたネストされた状況はよく見られます。何が何にネストされているのかをよく見極める必要も出てきます。
プログラム独特の表記は慣れないと難しいと思うかも知れませんが、これらは規則です。細かいところは無視して、とりあえずはこのファイルでアプリケーションが1つ定義されているということがまず1つのポイントです。そして、そのアプリケーションは、mainという名前の部分が起動直後に自動的に呼び出されるという予備知識で以下の作業にあたってください。
それでは、アプリケーションウィザードが用意したアプリケーションのソースJavaBasic.javaにプログラムを追加して、この章の核心に入って行くことにしましょう。
プログラムを追っていくと、public static void main(String[] args)と書かれた一連のブロックがあります。ここの部分はアプリケーションとして実行したときに最初に実行される箇所です。この中の { } の間にプログラムを追加します。追加するプログラムは、画面ショットだけでなく、テキストでも示しておきます。
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
//ここから追加
int a;
int b,c;
a = 100;
b = 120;
c = ( a + b ) * b * 100000000;
System.out.println(a);
System.out.println(b);
System.out.println(c);
//ここまでを追加
}
プログラムをこの通りにキータイプして打ち込んで行って下さい。このとき、System.out.printlnの部分を打ち込むときに、勝手にポップアップメニューが出てきます。これは慣れてくると便利な機能で、Javaの文法や各種機能から判断して、この場所に来るべき単語を自動的に割り出し、それをABC順に候補として表示するのです。だから、リストで選択して、EnterやTabキーを押せばそれが確定します。従って、キータイプすべてを行なう必要もなく、また、キータイプミスも減らすことができます。ただし、あまりJavaの知識がない状態でこの機能を使うと、意図しない単語が入力されてしまうこともありそうなので、自信がない方は、とにかくその通りにキータイプして行ってください。ポップアップメニューは無視してキータイプしてかまいません。
プログラムには、半角のスペースが随所にありますが、必要なスペースとなくてもよいスペースがあります。たとえば、publicで始まる行のpublicやclassなどの単語を区切るスペースは絶対に1つ以上必要になります。一方「a = 100;」のように、イコールの前後に半角の空白を入れていますが、これはスペースなしの「a=100;」でもかまいません。ただ、イコールの前後に空白を入れた方が見やすくなるということから、このように記述しています。
一方、printlnという単語の途中にスペースを入れると正しくなくなりエラーとなります。スペースが必要かどうかという厳密な定義はあるのですが、それを説明するとかえって難しくなります。とりあえずは、いろいろプログラムを打ち込むときにちょっと変化をさせてみて、うまくコンパイルできない場合には理由を考えるという具合にすすめていけばよいでしょう。
プログラムは、1字1句間違えないように入力するのが基本ですが、どうしても間違えやすい文字があります。それらをまとめておくと以下の通りです。
前述のプログラムを追加したら、実際にプログラムを実行させてみます。実行する場合、ツールバーのボタンを使うのが典型的な方法ですが、始めてプログラムを実行するときには、プログラムファイル、つまりこの場合はウインドウ左側のリストにある「JavaBasic.java」という項目を右ボタンでクリックして、「実行」から「Javaアプリケーション」を選択してください。これにより、このプログラムが実行対象として記憶されますが、最初の1回の実行だけは、このように右クリックしてメニュー選択をするのが手軽でしょう。
なお、一度、このように右クリックからの実行をやっておけば、ツールバーの「実行」ボタンで、プログラムを実行できます。このボタンの単なるクリックは「直前に実行したのと同じプログラムを実行する」ということです。過去に実行したことがあるプログラムは▼部分をクリックして選択する事ができます。なので、以後は、クリックだけ、あるいあドロップダウンしたリストの中から選択して実行する事でかまいません。
実行結果は「コンソール」という部分に表示されます。100や120といった数字が見えていますが、これらの数字は、前に示した手順で打ち込んでもらったプログラムによって出力した数字が見えているのです。プログラムに、System.out.printlnというキーワードがあったことを確認してください。この記述によって、標準出力というところに文字列を書き出します。プログラムでの処理結果を表示するもっとも手軽で、多くの場面で使える手法が標準出力なのです。ただし、標準出力の形態は実行時の環境によってことなります。JBuilderで標準出力への書き出しを実行した場合には、JBuilderのウインドウの下側に出る部分(「コンソール」と呼ばれる)に出力されるというわけです。
プログラムが実行され、そのプログラムはこの場合は終了してしまっています。ワープロなどのようなユーザインタフェースが存在しないプログラムは通常はこのように実行して自動的に終了します。
ここまでに示したプログラムは短いものですが、いくつか重要なポイントが含まれています。まずJavaでは、数値や文字列などのさまざまなデータを扱うことができます。ただし、文字列でも数値でもなんでも自由に扱えるというわけにはいきません。一定範囲の数値、あるいは文字が扱えるようになっています。
こうした制約は、「型」として規定されています。たとえば、整数型というデータの型があるとすると、その型にあてはまる20や500という数値は扱えますが、小数点を含む1.4142の数値は扱えないというわけです。型によって、扱えるデータの種類が決まると言えばよいでしょうか。その型のうち、「基本型」と呼ばれるJava言語に規定されている型を表にまとめておきました。
型名 | サイズ(ビット) | 取り扱えるデータ |
---|---|---|
boolean | 1 | true ないしは false |
char | 16 | UNICODEの一文字 |
byte | 8 | 符号付き整数、-128〜+127 |
short | 16 | 符号付き整数、-32768〜+32767 |
int | 32 | 符号付き整数、-2147483648〜+2147483647 |
long | 64 | 符号付き整数、-2^63〜+(2^63-1) |
float | 32 | 浮動小数点数、仮数部約8桁、指数部は-45〜+38 |
double | 64 | 浮動小数点数、仮数部約17桁、指数部は-327〜+308 |
数値や文字列をプログラム内に書くことができるのは、すでに見ていただいた通りです。数値は、普通に記述します。半角文字で連続して数値を書きますが、小数点はピリオドを使います。この場合、120という数値は実はint型になります。120.1という数値はdouble型になります。単に定数を記述しても、それには型があることは意識しておく必要があります。
プログラムに定数しか書けないとすると、汎用的な処理を組み立てるのはまずできないでしょう。しかしながら、プログラム中に場合によって変化する値というものを記録管理する機能を利用することができます。それが「変数」と呼ばれるものです。変数には、名前をつけて区別をします。この名前はアルファベットと数字とアンダースコア(_)からなるもので、他の文字を使うことは基本的にはいけません。アルファベットの大文字と小文字は区別します。つまり、スペースが入ってはいけないので「My Name」という変数はありません。この場合「myName」とか「my_Name」のように変数を命名します(変数の最初は小文字にするのが一般的です)。
さて、ここで、プログラム中に「int a;」のような記述があります。プログラムの行末にはセミコロンが出てきますが、セミコロンはプログラムの1つ1つのステップを区切る重要な記号です。そして、「型名 変数名;」のように記述することで変数という値の記憶領域が作られて、以後のプログラムで変数が利用できるようになります。
変数に値を代入するには、「変数=値;」と記述します。プログラムにあるように、値は定数でもよいのですが、計算式でもかまいません。「値を代入」という言い方は、数学でおなじみの言い方なので、なんとなくすっと入ってくるかと思います。
一方、値としては、計算式も利用できます。計算式も、やっぱり普通に書けばよいのです。「10+20」のように、演算子をはさんで両側に数値などを書きます。そのとき、定数だけでなく、変数も記述することができます「a+b」というのは、変数aとbがint型であるなら、変数aの値と変数bの値を加えるということです。文字列の「ab」という意味ではありません。たとえば、aが100、bが120であるなら、「a+b」は「220」という値になるわけです。このように、変数の値を読み出して計算に利用することができるわけですが、変数の値を読み出すことを「値を参照する」という言い方をします。
このように、式「a+b」は220などの値を持つわけですが、場合によっては「a+bは220を返す」とかあるいは「戻す」というような言い方をします。計算結果は返ってきたり、戻ってきたりするわけです。その返された値を、「=」の左側の変数に代入するというわけです。このあたり、言い回しがちょっと独特になってきますが、慣れておけば、他の人とプログラミングの話をするときに通りがよくなるでしょう。
さてこのように、変数には値を自由に入れて、自由にその値を取り出すことができるわけです。その意味で、常に一定の値ではないということで「変数」なのです。プログラムを汎用的に作るためには必要な機能ですし、また、いくつものステップを経て目的の処理を行うような場合だと、処理途中を逐一変数に保存しておいて、次あるいはもっとあとのステップで活用するということも行われます。変数を自由に使いこなすというのが、プログラミングの第一歩だと言えるでしょう。
数値の計算に使える演算子は、次の表にまとめておきました。加減乗除はよいとしても、値を1つ増やすなど独特なものがありますが、これについては、今週の日曜日に実例が出てきます。あと、整数型の場合には、割算と言っても、商と余りの形式で求められます。余りを求めるという処理も比較的よく利用するのですが、その演算子が便利なことに用意されています。
優先度 | 演算子 | 処理内容 | 例 | 例の意味 |
---|---|---|---|---|
1 | ++ | 値を増やす | a++ | aの値が1だけ増える |
-- | 値を減らす | a-- | aの値が1だけ減る | |
- | 負の数にする | -a | aの値の正負を逆にした値 | |
2 | * | 乗算をする | a*b | a×bの計算結果 |
/ | 除算をする | a/b | a÷bの計算結果、10/3は3になる | |
% | 剰余を求める | a%b | a÷bの余り、10%3は1になる | |
3 | + | 加算する | a+b | a+bの計算結果 |
- | 減算をする | a-c | a-bの計算結果 | |
13 | *= | 左辺と右辺の乗算結果を左辺に代入 | a*=b | a=a*bと同じ |
/= | 左辺と右辺の除算結果を左辺に代入 | a/=b | a=a/bと同じ | |
%= | 左辺と右辺から求めた剰余を左辺に代入 | a%=b | a=a%bと同じ | |
+= | 左辺と右辺の加算結果を左辺に代入 | a+=b | a=a+bと同じ | |
-= | 左辺と右辺の原産結果を左辺に代入 | a-=b | a=a-bと同じ |
優先度という項目が表にあります。この順位が低いものほど、先に評価されます。これは一般的な計算処理と基本的には同様です。たとえば、a+b*cとある場合、bとcをかけた結果にaを加えるという順序でなされるということを意味します。また()を使えば、そのカッコが優先的に処理されます。つまり(a+b)*cは、aとbを加えた結果にcをかけるという処理を行います。
このようにカッコが使えるのも、普通の数学での表記と同じです。
前に示したプログラムでは、変数cは、( a + b )* b * 100000000という計算式ですから、値は2640000000000となり、int型の上限値を超えてしまいます。Javaコンソールの出力結果を見ると、正しいと思われる値ではなく、負の数になってしまいます。コンピュータの内部では、決まった桁数で値を保持します。それが「Javaの基本型」という表で示したビット数で、intなら32ビット(2進数で32桁ということ。正確には符号に1桁取るので、数値は31桁)という一定の桁数で管理します。変数cへ代入する値は、仮に正しく計算されたとしても、32ビットに収まりきれないくらい大きな数値ですので、収まりきれないデータは破棄されてしまい、結果的に正しくない値が変数cに代入されているのです。
コンピュータで数値計算をするときには、必ず、このような利用可能な数値の範囲に気をつける必要があります。範囲を超えるとここで見たように、大幅に狂うことも忘れてはいけません。限られた桁数をうまく使って、間違った計算をしないように、変数を定義し、計算式を組み立てるというのが基本になります。
変数に代入した結果や、あるいは計算結果は、プログラムの内部的には記録されています。とはいえ、やはりそれを目の当たりにしないと、本当に記録されているのかどうかすぐには信じられないかもしれません。それに、簡単な処理ならともかく、複雑な処理をするとなると、ポイントごとに変数がどうなっているのかということをしっかり目で見て確認したくもなります。そこで、値を簡単に表示するために使える方法として「標準出力」があります。JBuilderの環境下では、JBuilderのウインドウのメッセージペインに出力されます。文字が単に出てくるだけですが、変数の値を確認するなど十分に役に立ちます。変数の値だけではなく、メッセージなどを出力するのにも使ったりしますが、どちらかと言えばプログラムをしたり、それをチェックしたりする人向けのメッセージを表示するために利用されます。完成したアプリケーションでの重要なメッセージをJavaコンソールで表示することは基本的にはありませんし、プログラマ以外の目に触れないようにするのが基本だと言えるでしょう。
標準出力に出力するには、「System.out.println(値);」と記述します。ここでは、Systemとかoutとか、printlnがなにかということは説明しません。こういう“コマンド"があると理解していただければけっこうです。
printlnのlnは、ラインを意味します。つまり、1行分出力するシステム機能…のように理解していただければけっこうです。()に指定した値を、標準出力の1行に出力します。その結果がJBuilderのメッセージペインに出力されているのが見えているわけです。プログラムと、Javaコンソールの出力結果をよく見比べてみてください。
さて、続いて、変数関連のさまざまな機能を実際にプログラムで試してみることにしましょう。作成した、JavaBasic.javaに以下のようにプログラムを追加してください。public static void main(){ 〜 }の、{ }内に追加すると言えばよいでしょうか。
今週はこのように、プログラムを少し追加しては結果を見ると言う手順ですすめます。追加するのは初めてですので、追加した結果をここでお見せしますが、以後、同様な方法で追加していってください。
なお、新たにプログラムを追加するときは、前に追加したプログラムとの間に適当に改行記号を入れてかまいません。こうすることで、プログラムのかたまりが見やすくなるでしょう。
public static void main(String[] args) {
//ここから追加
int a;
int b,c;
a = 100;
b = 120;
c = ( a + b ) * b * 100000000;
System.out.println(a);
System.out.println(b);
System.out.println(c);
//ここまでを追加 ←前の手順でここまでを入力した
//さらに追加
short d = 500; ←ここから追加
c = a + d;
System.out.println(c);
d = a + d;
System.out.println(d); ←ここまでを追加
}
プログラムはまたまた簡単な計算ですので、それほど悩まないとは思います。しかしながら、プログラムのウインドウの左端では×マークが赤いボックスで出ているなど、。「エラー」とあるので、何かの間違いであることがわかりますが、式としては間違っていないように思うところです。
プログラムが見えているペインの左側や右側の赤い部分をクリックすると、理由などが分かるようになっています。いずれも「型の不一致:intからshotには変換できません。」という記述が見えます。特に、行の左側のクリックするとさらにポップアップメニューで対処のリストが出ます。ここでは「キャストを 'short' に追加します。」という方を選択すれば、想定した結果になりますが、左側のボックスでは右側で選択した処理によってプログラムがどのように変更されるかも示されています。
いずれにしても「 d = a + d;」とあるところを、「 d = (short)( a + d );」と修正してください。そうすれば、エラーが出なくなります。なぜこのような記述が必要なのかは、結果を見てから説明をしましょう。
プログラムを追加し終わったら、ツールバーにある「実行」ボタンをクリックして、プログラムを実行してみます。コンソールに新たに追加した部分による出力結果(2つある「600」の数値)が見えています。
それでは追加したプログラムを見てください。ここでは「short d = 500;」という記述があります。まず、short型の変数dを定義しているのですが、続いて右辺で代入の記述を行うことで、変数を定義して値を与えるということが一度にできてしまいます。こうすれば記述がコンパクトにまとまって、見やすくなります。
もう1つ重要なこととして、変数の定義は、プログラム中のどこに出てきてもかまわないということがあります。プログラムの途中で定義をして、以後の部分で変数を使うということもできるわけです。なおここでは、public void init()の後に、{ }でくくられた大きなまとまりがあります。もう少し規模が大きくなると、このまとまりの中にさらに含まれるまとまりを作ったりもしますが、場合によっては内側のまとまりの中だけで有効な変数ということもあります。いずれにしても、処理途中に変数の定義があってもかまわないということです。
追加したプログラムに「d =(short)(a + d);」という部分があります。いきなり型名がカッコで囲まれているだけの記述があります。単に変数aと変数bを加えて変数dに入力するなら、ここを「d = a + d;」とすればいいはずです。すでにみてみたように、赤字で精度が落ちている可能性があるという旨のメッセージが出てきます。これはエラーメッセージとも呼ばれていますが、この赤字のメッセージが出てくると、文法上の誤りがあるためにプログラムの生成と実行ができないことを意味しています。
aもbもintだとすれば、a+bもint型の値になります。そのint型をshortに代入しようとすると、コンパイル時にその不整合を見つけてエラーとしてレポートします。shortはintにくらべて扱える値の範囲が狭くなってしまいます。shortの上限は32767です。たとえば、aもbも20000だったとしたら、a+bは40000になります。しかしながら、この値はshortでは扱えない範囲の数です。このままだと、shortで扱えない値を代入しかねないということを、最初からチェックしてくれているのです。なお、int型のaとshort型のdを加える場合など、異なる型の計算結果は、より広い範囲の値を扱える型として得られます。そのため、int+shortの結果はintになります。
ただ、処理の上ではそれでもOKということもあります。そこで、int型の値をshort型に変換するという手段が与えられています。それが「キャスト」です。キャストは「(型名)値」と記述することで、値を、指定した型で解釈するということです。したがって「a+b」はint型ですが、「(short)(a+b)」はaとbを加えた結果の値をshort型に変換した結果となります。キャストは演算子よりも早く適用されるので、(short)a+bとしたら、変数aにだけキャストが適用されるので、a+bをカッコで囲っているわけです。
もちろん、a+bの結果が、short型で扱える範囲を超えていれば、キャストした結果、誤差は生じます。そのため、キャストは慎重に使わないといけないのですが、どうしても使わざるを得ない場面が出てくるこもあるので、知っておいて損はないでしょう。
本文中でも説明しましたが、数値型などの変数は、実際にはビット、つまり2進数の1桁が何桁か集まって利用できるようになっています。内部的には2進数で記録されているのですが、プログラム上では普通に10進数で記述でき、コンソールの出力も同様です。これは、JavaのコンパイラやVMに、内部の2進数を人間が見て理解しやすい10進数として扱えるような機能が組み込まれているからです。
本書のプログラムでは使っていませんが、こうした変数に収める値を10進数ではなく、2進数として利用したいことがあります。各ビットに異なる意味を持たせて状態を記録したりするような場合に使われます。そのようなデータの記録を行ったときのために、ビット単位での演算を行うような演算子が次の表のように定義されています。詳しい説明は本書では行いませんが、時としてこういう演算が必要になることもあります。
優先度 | 演算子 | 処理内容 |
---|---|---|
1 | ~ | ビットごとのNOT(補数、すなわち1と0を入れ替えたもの) |
4 | << | 左辺を右辺で指定した回数だけ左シフト(1回の左シフトは2倍と同じ) |
>> | 左辺を右辺で指定した回数だけ右シフト。最上位ビットはそのまま(1回の左シフトは2で割るのと同じ。符号は保持) | |
>>> | 左辺を右辺で指定した回数だけ右シフト。最上位ビットは0(1回の左シフトは2で割るのと同じ。符号は変更の可能性あり) | |
7 | & | ビットごとのAND(論理積) |
8 | ^ | ビットごとのXOR(排他的論理和) |
9 | | | ビットごとのOR(論理和) |
13 | <<= | 左辺と右辺を該当する演算子で計算し、その結果を左辺の変数に代入する |
>>= | ||
>>>= | ||
&= | ||
^= | ||
|= |
今週のこれまでのところで、Javaで使える演算子について表で示してきましたが、表に示していなかったものや、紹介をしていないものもありますので、優先順位を含めて次の表に示しておきました。
優先度 | 演算子 | 処理内容 | 例 | 例の意味 |
---|---|---|---|---|
1 | (型名) | キャスト(本文を参照) | (int)a | aをint型に変換する |
3 | + | 文字列の結合 | "abc"+"def" | "abcdef"という文字列 |
5 | instance of | 左辺のオブジェクトが右辺の型かあるいは右辺の型を実装したものかどうかを調べる | a instance of Button | aがButtonオブジェクトならtrue |
12 | ?: | 3つの項を持ち条件によって値が変わる(例を参照) | a?5:100 | aがtrueなら5、aがfalseなら100 |
13 | = | 右辺の値を左辺に代入する | a=10+20 | 変数aには整数の30が代入される |
4-1:新たに演習課題用のプロジェクトを作成すること
4-2:次のような手順のプログラムを作成すること
いちばん最後の小数以下を含めた割り算の結果はちょっと難しいので、さっぱりわからない場合にはとりあえずパスしていいでしょう(教科書にもヒントらしきものは何も書かれていません)
4-3: 4-2のプログラムで、自分で追加した部分を、紙に書き出して次のような表を作成しなさい。もちろん、ワープロなどを使って印刷してもいいが、手で全部作成してもたいした手間ではないはず。「<プログラムの1行目>」とあるのは、4-2で作成したプログラムの1行1行に置き換えること。
プログラム | 変数num | 変数digit | 変数d | 変数e |
<プログラムの1行目> | ||||
<プログラムの2行目> | ||||
<プログラムの3行目> | ||||
: |
||||
<プログラムの最後の行> |
表の枠内には次のように記号を書き込むこと。つまり、変数の状態を書き込むのであるが、この表では、左側のプログラムの1行が実行し終わったときの、各変数の値を、表に書き込むものとする。
Javaに限らず、本格的なプログラム言語では、変数をはじめ、「データの型」ということを強く意識しないといけません。たとえば、「3÷2」は、当然1.5ですが、たとえば、
System.out.println(3/2);
とすると、1になります。こうした実世界との違いを必ず意識しないといけません。(ただし、Visual Basicのように、むしろ一般的な結果になるような動作をするプログラミング環境もあり、言語ごとに動作が違う意識が必要になります。)
まず、なんで整数なんてあるのか、しかも、整数で4種類もあるのか(byte, short, int, long)を説明しましょう。1つは、プログラムを作る上で、整数で十分なことが多くあります。たとえば、数えるとか、回数にかかわることは整数で十分です。それに加えて、なるべくコンピュータ上での実行にかかる時間を短くしようという意図もあります。小数を含む計算より、整数の計算の方が早く済みます。また、同じ整数でも、一般にはバイト数が少ない型の方が速くなります。こうした効率を最大限に発揮させるためにも、整数型の利用は欠かせないのです。
ただ、そうした型がたくさんある場合、計算の上で、普通とは違う規則が適用されてしまいます。変数は型を宣言して定義するということと、キャストにより型を自由に変えることができるというのが基本ですが、それら以外の規則をまとめておきましょう。
Javaの言語規則として決まっていることですが、整数を書くとint、小数点を含む数を記述するとdoubleになります。つまり、12というのはint型の数値で、12.2はdouble型です。また、12.0はdouble型になります。
数字を書いてそれを、shortやfloatなどにする方法もあります。たとえば、5.0fは、float型になりますが、数値のあとにある「f」が一種のキャストのようになります。ただ、キャストを使うほうが、より明示的であるので、そちらがお勧めです。
同じ型同士の計算は、その型になるというのが基本です。intとintの計算結果はintになります。したがって、3/2の結果はintになるのですが、小数部分は切り捨てられて1になるということです。なお、この場合は切捨てであって四捨五入ではありません。 5/3の結果はしたがって1になります。
一方、異なる型同士の計算は、より精度が高い(言い換えれば値として記録可能な範囲が広い)ものに結果はなります。言い換えれば、精度が低い方が高いほうの型に変換されて、計算が行われるということです。floatとintの計算結果は、floatになります。また、doubleとintの計算結果は、doubleになります。したがって、5/3は1だけど、5.0/3は1.6666666666666667となります。
キャストは、数値の前につけるマイナス記号のように、とにかく先に解釈されると思っておいて間違いはないでしょう。したがって、(float)5/3と、(float)(5/3)は違います。前者はintである5をfloatにするのでfloatとintの割り算となり3もfloatにしてしまって結果はfloatの1.666666となります。一方後者は、5÷3=1の結果をfloatに変換するので1.0になります。ただ、前者は、(float)5/(float)3のほうがある意味では明示的ではありますが、こちらの記述はややかったるいという気もするかもしれません。どちらがいいのかということは一概には言えませんが、いずれにしても意味はきちんと理解してください。
テキストに説明してあるとおりです。(4-2のコラム「変数cの出力結果に注目」)
ところが、次のようなプログラムはきちんと、80+120-120の結果である80を表示します。
byte a=80, b=120;
System.out.println((a+b)-b);
これは、実は、(a+b)がint型になるという整数型特有のルールがあるのです。ほんとうなら、a+bの結果は200となりbyte型の範囲を超えるのですが、そこではいきなりintになるので、問題なく数値は扱えます。こうした例外的なものは随所にあったりするわけでかえってややこしいと思ってしまうところですが、例外はつきものです。原則とローカルルールをうまく理解すれば問題はありません。