第3回目-2002/10/21

Java文法の基本(変数)

ポイント

変数を理解する

p58〜p66を実際にやってみます。時間を区切って、各自でやってもらいます。

p67〜p71については、講義をしますが、上記の作業が終わったら、じっくり読み込んでおいてください。

理解してほしいこと:

キャストについて

p72〜p75を実際にやってみてます。時間を区切って各自でやってもらいます。

p74の「変数の型を変える」という見出しの部分の最初に記載されていることを、必ず自分でやってください。

理解してほしいこと:


演習課題

3-1:新たに今日の演習課題用のプロジェクトを作成すること

3-2:次のような手順のプログラムを作成すること

いちばん最後の少数以下を含めた割り算の結果はちょっと難しいので、さっぱりわからない場合にはとりあえずパスしていいでしょう(教科書にもヒントらしきものは何も書かれていません)

3-3:3-2のプログラムで、自分で追加した部分を、紙に書き出して次のような表を作成しなさい。もちろん、ワープロなどを使って印刷してもいいが、手で全部作成してもたいした手間ではないはず。

プログラム 変数num 変数digit 変数d 変数e
<プログラムの1行目>        
<プログラムの2行目>        
<プログラムの3行目>        


       
<プログラムの最後の行>        

表の枠内には次のように記号を書き込むこと。つまり、変数の状態を書き込むのであるが、この表では、左側のプログラムの1行が実行し終わったときの、各変数の値を、表に書き込むものとする。


練習問題3-xに対する補足

Javaに限らず、本格的なプログラム言語では、変数をはじめ、「データの型」ということを強く意識しないといけません。たとえば、「3÷2」は、当然1.5ですが、たとえば、

System.out.println(3/2);

とすると、1になります。こうした実世界との違いを必ず意識しないといけません。(ただし、Visual Basicのように、むしろ一般的な結果になるような動作をするプログラミング環境もあり、いずれにしても、それはそれでJavaとかとは違うという意識が必要になります。)

まず、なんで整数なんてあるのか、しかも、整数で4種類もあるのか(byte, short, int, long)ですが、1つには講義で説明があったように、プログラムでは整数で十分なことが多くあります。たとえば、数えるとか、回数にかかわることは整数で十分です。それに加えて、なるべくコンピュータ上での実行にかかる時間を短くしようという意図もあります。少数を含む計算より、整数の計算の方が早く済みます。また、同じ整数でも、一般にはバイト数が少ない型の方が速くなります。こうした効率を最大限に発揮させるためにも、整数型の利用は欠かせないのです。

ただ、そうした型がたくさんある場合、計算の上で、普通とは違う規則が適用されてしまいます。変数は型を宣言して定義するということと、キャストにより型を自由に変えることができるといのが基本ですが、それら以外の規則をまとめておきましょう。

数字を直接書くとどうなる?

これは決まっていることですが、整数を書くと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のほうがある意味では明示的ではありますが、こちらの記述はややかったるいという気もするかもしれません。どちらがいいのかということは一概には言えませんが、いずれにしても意味はきちんと理解してください。

計算の途中経過にも注意を払う

テキストに説明してあるとおりです。(p71のコラム)

ところが、次のようなプログラムはきちんと、80+120-120の結果である80を表示します。

byte a=80, b=120;
System.out.println((a+b)-b);

これは、実は、(a+b)がint型になるという整数型特有のルールがあるのです。ほんとうなら、a+bの結果は200となりbyte型の範囲を超えるのですが、そこではいきなりintになるので、問題なく数値は扱えます。こうした例外的なものは随所にあったりするわけでかえってややこしいと思ってしまうところですが、例外はつきものです。原則とローカルルールをうまく理解すれば問題はありません。


解答

3-1    省略

3-2

プログラムは適当なメソッドの中に書いてください(たとえば、initの末尾など)

int num = 789;
System.out.println(num);
long digit = 3450;
System.out.println(digit);
long d = digit / num;
System.out.println(d);
long e = digit % num;
num = num * 2;
System.out.println(num);
System.out.println(d);
System.out.println((double)3459 / (double)789);

3-3

プログラム 変数num 変数digit 変数d 変数e
<プログラムの1行目> 789      
<プログラムの2行目>        
<プログラムの3行目>   3450    
<プログラムの4行目>        
<プログラムの5行目>     4  
<プログラムの6行目>        
<プログラムの7行目>       294
<プログラムの8行目> 1578      
<プログラムの9行目>        
<プログラムの10行目>        
<プログラムの11行目>