Home >> Lecture 3
プログラムにおいて、「変数(Variables)」というのは、高校の数学みたいな難しい方程式を解くためのものではなく、 一時的に数値を保持しておくための箱だと思っておけば良いでしょう。 この箱に名前をつけて、数値を代入したり、参照したりすることができます。 また、逆に234などの数値そのものを記述することもJavaではできますが、これは「定数(Constants)」と呼ばれています。 一定の値を持ち続けることから、定数という名前が来ていますし、持つ値が変わるということが変数という名前の由来に なっています。 まずは、整数を保持することができる変数を作る文法規則を見てみましょう。 これをJavaでは、変数の宣言(Declaration)と呼びます。
int <変数名>;
上記の「int」は、整数(integer)の略です。C/C++言語の流れを汲んでいますので、このような省略形の 言葉になっています。ちなみに、これとは別に「Integer」クラスという整数を扱うクラスもJavaでは用意されて います。それでは、どんな風に記述するのか見てみましょう。
int value;
上記の記述で、「value」と名付けられた変数ができます。この変数には、最初に何も入っていませんので、 このまま使ってしまいますと、コンパイラがコンパイル時に叱ってくれる、あるいは実行時に叱られるなどの ことが起こります。
変数へは、後から値を代入することもできますし、作るときに初期値を代入しておくこともできます。 まず、代入の一般的な書式を見てみましょう。
<変数名> = <式>;
上記の書式に出てくる<式>の内容は次の節で詳細に説明するとして、まずは定数の値を代入しましょう。 ところで注意して欲しいのは、上記の=(イコール)は、等しいことを示すものではないという ことです。Javaでは、=は、必ず左辺から右辺の変数への代入として扱われます。
//整数の変数への代入 int takochan; takochan = 1234;
もう一つ、整数の変数を作るときに初期値を代入しておく記述の仕方の方も見ておきましょう。 これは、最初しか使えません。 変数へ代入することは何回もできますが、初期値代入は作る(変数を宣言する)ときにしかできませんので注意して下さい。
int <変数名> = <式>;
先ほどの「takochan」への代入のプログラムを、この初期値代入を伴って作る形で書き直してみましょう。
//整数の変数への初期値代入を伴う宣言 int takochan = 1234;
それでは、この変数の値を表示してみましょう。次のような文法規則を用います。 printLineは、 タートル・グラフィックスで用意されたメソッドです。コンソール(文字端末:BlueJでは「ターミナルウィンドウ」と 表現していますので、以降はターミナルという言葉を使います)に表示したいものを表示した後に改行してくれます。
printLine( <対象となるもの> );
この<対象となるもの>のは、定数でも変数でも構わなくて、最終的には「式」と呼ばれるものなのですが、それは 後の節でご説明致しましょう。また、ターミナルに表示した後に改行を行なわないprintも用意しました。
print( <対象となるもの> );
ここでは、まずは、takochanをターミナルに表示させた後、改行させてみましょう。 startメソッドの中だけを記述します。
int takochan; takochan = 1234; printLine( takochan ); // ターミナル(文字端末)に表示されます
次にこの変数の値をプロンプトに表示してみましょう。次のような文法規則を用います。 displayDialogは、 タートル・グラフィックスで用意されたメソッドです。タートルのウィンドウとは、別にでます。 なお、このプロンプトでキャンセル(Cancel)ボタンを押すと、プログラムの実行をそこで終了させることができます。
displayDialog( ""+<対象となるもの> );
この<対象となるもの>のは、定数でも変数でも構わなくて、最終的には「式」と呼ばれる、、、ところまでは、 ターミナル(コンソール)画面に表示するのと同じなのですが、ここでは、""+という変な記号がついています。 これも、後の節でご説明致しますが、強制的に文字列型に変換させるものです。 displayDialogは、文字列しか表示できません。整数をそのまま表示することができないので、このような変換を させています。おなじみ、takochanを今度はプロンプトに表示してみましょう。 今度は、初期値代入を使っています。 またもや、startメソッドの中だけを記述します。
int takochan = 1234; displayDialog( ""+takochan ); // プロンプトに表示されます
プロンプトを表示した後に、「OK」ボタンを表示した後は、タートルのウィンドウが出っぱなしになっていますので、 タートルのウィンドウをクリックしてQuitをメニューを選ぶか、⌘+Q(Command+Q)を入力して下さい。
上記のプログラムを、プロジェクトフォルダ「Project2008」の中で、Practice0301というクラス名で作成し、 保存し、コンパイルし、実行してみなさい。コンソールとプロンプトの両方に表示させてみなさい。
変数に直接、値をプログラム上で代入する以外に、タートル・グラフィックスのライブラリでは、 ユーザから値を入力して貰うことが可能になっています。 これを標準のJavaのライブラリを使って書くと結構大変です。 ここら辺も楽になるように、タートル・グラフィックスのライブラリが整備されています。 さて、これをするには、 displayInputIntegerDialogという長い名前のメソッドを利用します。 名前が長くて申し訳ありませんが、名前が何をするのか表しています。 このメソッドを呼び出して使うには、2つのパラメータと入力された値を受け取る変数が必要になります。
値を受け取る変数名 = displayInputIntegerDialog( 表示される文字列, 何も入力しないときの値 );
表示される文字列は、"(ダブルクォーテーション)で囲みます。これで、何を入力するのか表示して下さい。 ユーザが何も入力欄に入力しなくて「OK」ボタンを押したときに使われるのが2番目のパラメータです。 これは、一般にはデフォルト値(Default Value)と呼ばれています。 たとえば、takochanに整数の値をもらって、takochanの二乗を表示するようなプログラムを作ってみましょう。 Javaでは掛け算は、半角の*(アスタリスク)として記述します。 またもや、startメソッドの中だけを記述します。
// 入力された値の二乗を表示するプログラム int takochan; takochan = displayInputIntegerDialog( "Input integer value", 1 ); // デフォルト値は1としましょう。 displayDialog( "Square is "+takochan*takochan ); // Square is を表示してから二乗を表示しています。
さきほど、""+となっていたところが、"Square is "+になっています。このように、どのような文字列とも足し算すると 計算結果が文字列に変換されます。しかし、この足し算にも後で説明する「落とし穴」が存在します。 それはともかく実行してみましょう。
Practice0302という名前のクラスを新規に作成し、上記のプログラムを入力し、保存し、コンパイルし、実行してみなさい。
ターミナル(文字端末:コンソールとも呼ばれます)の画面が今回初めて出てきました。 ここには、実行時のエラー(赤色表示されます)や printやprintLineメソッドで表示させたいことがでます。また、後で説明するようにここからキーボードからの 入力を受け付けて、プログラムの中にデータを取り込むことができます。 コンソール画面は、プログラム中で必要になったら自動的に現れますが、BlueJの「表示」メニューの 「ターミナルウィンドウの表示」で表示させることができます。 ウィンドウの消去は赤いボタン(Windowsの場合は×ボタン)で行ないます。 ところで、このターミナルウィンドウですが、実は、これにもメニューがあります。 「オプション」というメニューです。このメニューを開いてみたらだいたいのことはわかると思いますが、 次の2つの項目はよく使いますので注意して下さい。これらの項目は、チェックマークを付けたり、外したりする もの(トグルスイッチと呼びます)になっています。
- 「Clear screen at method call」:これにチェックマークが入っていると、実行する度にターミナルをクリア してくれます。もし、入っていないと、前回の実行結果が残ります。
- 「バッファを制限しない」:これにチェックマークが入っていると、表示結果をすべて残してくれます。 もし入っていないと、表示結果の最後の100行ぐらいしか表示が残りません。
これまでは、例えばタートルが回転する角度や進むドット数は、すべて60度とか、50ドット などの定数でした。その部分を変数にしてタートルを動かしてみましょう。 たとえば、以下のプログラムは、大きさを受け取って四角形の一辺を描きます。 またもや、startメソッドの中だけを記述します。
// 四角形の大きさの入力を受け取って四角形を描く // タートルを作る Turtle turtle = new Turtle( this ); //大きさの入力を受け取る int size; size = displayInputIntegerDialog( "Please input the length of the square: ", 50 ); //四角形を描く while ( true ){ turtle.forward( size ); turtle.rotate( 90 ); }
上記のプログラムを利用して、RegularPolygonLocusという名前で新規のクラスを作成しなさい。 このプログラムでは、ユーザから入力を受け取り、その数は正多角形の角数と致します。 たとえば、6角形の場合には、6を入力してもらいます。それで、一辺が50ピクセルぐらいの6角形を描くように しなさい。うまくプログラムを編集し、そのまま保存し、コンパイルし、実行してみなさい。 ヒントは、タートルの曲がる角度は、「360÷角数」であるということです。なお、Javaでは割り算は、 半角の「/」(スラッシュ)で記述します。 実行の終了は、永遠に終わらない繰返しを使っていますので、タートルのウィンドウをクリックしてQuitをメニューを選ぶか、 ⌘+Q(Command+Q)を入力して下さい。
上記(課題3-1ではなく、その上のサンプル)のプログラムを利用して、FiveStarLocus という名前で新規クラスを作成しなさい。そして、☆を描くようなプログラムを作ってみなさい。 ☆は中で線が交差してはいけませんよ。また、傾いていてもいけません。 うまくプログラムを編集し、そのまま保存し、コンパイルし、実行してみなさい。 実行の終了は、永遠に終わらない繰返しを使っていますので、⌘+Q(Command+Q)にて。
変数は使う前に宣言(Declaration)をしなければなりません。次のような書式で行ないます。
▼宣言文:
<型名またはクラス名> <変数名> ;
書式で使われている型名とは、変数が覚えるデータの型を示しています。次の幾つかの型があります。
boolean 論理型 論理値を保持する変数を宣言するとき int 整数型 整数値を保持する変数を宣言するとき long 長桁整数型 21億を超える整数値を保持する変数を宣言するとき char 文字型 文字を保持する変数を宣言するとき double 実数型 実数値を保持する変数を宣言するとき String 文字列のクラス 文字列を保持する変数を宣言するとき
変数の名前は任意の名前をつけてよいのですが、英文字で始まる必要があります。 コンパイラは、32文字ぐらいだったら、変数の名前をちゃんと識別することができます。 なお文字列だけはクラスになっています。 変数の宣言は、例えば、つぎのように行ないます。
int x ; // xという名前の変数を宣言する
こういった宣言は、コンパイラに怒られますので、変数が使われる前に行なっておかなければなりません。 上の例では、変数xが最初に現れるのは、かならず変数宣言の中です。 宣言も1つの文であり、宣言文と呼ばれています。 同じ型の変数を宣言するときは、カンマで区切って複数の変数を宣言することができます。 例えば、次のように、同じ型の2つの変数が宣言されているとしましょう。
int x; // xという名前の変数を宣言したが、 int y; // yという名前の変数も欲しくなってしまった
同じ型やクラスの変数は、以下のように、一回の宣言文で宣言することができます。
int x, y; // 面倒なので一緒に宣言してしまう
長桁整数型や文字列クラスの変数も同じように宣言できます。
long value; // 長桁整数型の変数value String s; // 文字列クラスの変数s
宣言された変数は、宣言後から使用できるようになりますが、そのブロック内だけしか有効ではありません。
{ int x; // ここからはxは有効 { int y; // ここからはxもyも有効 } // ここではxだけが有効 } // xもyも使えない
同じブロック内で、同じ名前の変数を何回も宣言するとコンパイラ・エラーになります。
{ int x; // 整数型の変数xを宣言した int x; // もう一度やってみた→コンパイル・エラー long x; // 同じ名前の変数を別の型で宣言した→コンパイラ・エラー }
変数への代入は以下のような代入演算子=を使って行ないます。
▼代入文:
<変数名> = <式> ;
変数名が必ず左辺に来ていることに注意して下さい。C/C++/Javaでの=は、等号を示す演算子ではなくて、 必ず右辺から左辺への代入が起こる演算子です。逆に書くとコンパイラにエラーにされてしまいます。
int x; x = 45;
変数を宣言する際には、同時に初期値を代入することができます。 これによって、宣言と最初の代入を1つにすることができます。次のような書式で記述します。
初期値代入:
<型名またはクラス名> <変数名> = <式> ;
例えば数値型の変数の場合は、次のように使います。
int z = 1056; // 整数型の変数zを宣言し、その値を1056にする long y = z * 67000000; // 長桁整数型の変数yを宣言し、その値をz * 67000000にする
上記の2番目の例 のように既に存在する変数を使っての初期化することも可能です。 しかし、右辺の式中に出現する変数は、それまでに値が代入されていなければいけません。
同じ型の初期値代入を伴う変数の宣言は、カンマ(,)で区切っていくつも書いても構いません。
int x = 20, y = 30; // 整数型の変数xとyを宣言し、その値を設定する int w = x * 20, u = y / 20; // 同様、途中の区切りはカンマを使う
なお、次のように記述した場合は、変数yは初期化されますが、変数xは初期化されないので注意してください。
int x, y = 30; // 整数型の変数xとyを宣言し、yの値だけ30に設定する // 正解は、int x=30, y=30; と記述する
変数には、一度宣言してしまったら、それ以降の代入には、宣言のための型名を書く必要はありません。 よくある間違いは以下のようなものです。
int w = 20; // 整数型の変数wを宣言し、その値を設定する int w = 40; // 既に変数wは宣言されているのでコンパイラエラーになる。
ショートカットキーはやはり覚えておきたいものです。いくつかの編集で使うショートカットキーを表にして おきます。Windowsの場合は、⌘(Command)キーは、Controlキーになっていることが多いでしょう。 ここに書かれているショートカットキーは、Macintoshのほとんどのエディタやワープロで使えるものです。
⌘+Q 終了 ⌘+.(ピリオド) 中止 ⌘+,(カンマ) 環境設定を行なう ⌘+S 上書き保存 ⌘+Z 元に戻す ⌘+Y やり直し ⌘+A すべて選択 ⌘+C コピー ⌘+X カット ⌘+V ペースト ⌘+F 検索 ⌘+G 次を検索 ⌘+K コンパイル ⌘+H そのアプリケーションを隠す ⌘+W 閉じる(エディタで) ⌘+P 印刷する
それからエディタでマウスクリック操作も注意しておきましょう。これも、お馴染みですが、 案外知らない人が多かったりします。また、Wordやテキストエディタでは、4回クリックも可能で、 その場合は、1つのパラグラフが選択されます。
- ダブルクリック:該当するワードを選択します
- トリプルクリック:該当する行を選択します
キャレット(テキストの挿入位置を示すカーソルのことです)を一定の位置に置いておき、別の場所を Shiftキーを押しながら、マウスクリックすると、キャレットから、そのクリックの手前までのテキストが 選択されるというのは、基本的な操作方法の一つですが、もしかしたら知らない人は、この期に覚えて おいて下さい。他のワープロ、エディタ関係のソフトウェアでも共通になっています。
Javaの1つの命令で終わる単純な文は、セミコロン(Semicolon)「;」で終わります。
▼単純な文:
<式> ;
文には以上のような単純な文以外にも、後で主要構文の節で紹介する制御文があります。
Javaのブロックは半角の波括弧(Braces)「{」と「}」で括ります。 以下の書式で…は、0個以上の繰返しを表しています。
▼ブロック:
{ <文>… }
名前や連続した記号を1つの言葉として区別するために、改行や半角の空白(Spaceキー)、あるいはTabコードを 入力することができます。 これらのコードは区切り子(Delimiter)と呼ばれています。全角の空白は、使えないので注意して下さい。 また、開発環境によってはTabを左側で入力することによって、適切な位置にインデントをしてくれるエディタが あります。加えて、エディタによっては一度入力したTabがいくつかの空白に置き換えられているもののあります。
コメントの書き方は、Javaでは2つあります(AppleScriptでも2つありました)。1行の中で、それ以降をコメントして 認識させるものと、複数の行に跨がってコメントにできるものがあります。//ではじまるこのコメントは、C++と同一です。
// 一行の中では、改行までがコメントとして認識される
複数の行に跨がるコメントは「/*」から「*/」で括ります。これは、C/C++と同一です。
/*
複数の行がコメントとして認識される
*/
上記の複数の行がコメントとして認識されるものは、ネストさせることも可能です。プログラムの実行検証途中で 省略したい処理を飛ばさせるのに用います。これは、コメントアウト(Comment out)と呼ばれています。
import文は、これからプログラムで導入したいクラス・ライブラリ(Java言語の中ではパッケージ:packageと 呼ばれています)や、その中に含まれるクラスを指定することができます。これは、プログラムの先頭(クラス定義の前) に単独で書かれる唯一の文です。
import <パッケージあるいはパッケージのクラス名> ;
特にパッケージ名だけを指定した場合は、「*」がクラス名として使えます。 これは、「すべてのクラス」ということを示しています。なお、残念ながらタートル・グラフィックスでは、「*」 を使うことができません。
import java.awt.Color; // java.awtパッケージのColorクラスを用いる import java.util.Calendar; // java.utilパッケージのCalendarクラスを用いる import java.awt.*; // java.awtパッケージのすべてのクラスを用いる import sfc.turtle.Turtle; // sfc.turtleパッケージのTurtleクラスを用いる
たとえば、import java.awt.*;がプログラムの先頭部分で定義されていれば、プログラムの中でいちいち java.awt.Colorと記述する必要はなく、Colorと記述すれば良いことになります。
import java.awt.*; // この後は、java.awt.Colorと記述する必要はなく、Colorで利用できます。
Javaのパッケージ名は、分類によってドット「.」で区切られます。これは、日本語の「の」と同じ意味です。 パッケージ名は、会社名から始まるものなど様々です。
com.apple.eawt // Apple社が拡張したAquaインタフェースに合わせるためのパッケージ com.sun.java // Sun社がJava用に拡張したパッケージ org.xlith // 特定の団体(Organization)が作成したパッケージ javax.swing // Javaで後から追加拡張されたクラス・ライブラリはjavaxから始まる java.lang // Javaの標準クラス・ライブラリは、javaから始まることが多い
クラスの正式名は、以下のように「パッケージ名.クラス名」となります。import文で導入してあれば、 「パッケージ名.」の部分を省略することができます。なお、我々が通常プログラムするクラスが属するパッケージは、 「無名パッケージ」と呼ばれています。取り敢えずの対象となるパッケージです。
▼クラス名:
<パッケージ名>.<クラス名>
また、「java.lang」パッケージに含まれているすべてのクラスは、import文で導入しなくても、パッケージ名を 指定せずに使えます。逆に、import文で導入したパッケージに含まれているクラスと同じ名前のクラス名があった場合、 次のようにパッケージ名から指定すると別のクラスとして利用することができます。
// 自分のプログラムでColorクラスを定義してしまった場合 java.awt.Color color ; // java.awtパッケージに含まれる方のColorクラスの変数を宣言した
あるパッケージにどのようなクラスやメソッドが含まれるのかについては、Mac OS Xでは、 Developer >> Applications >> Java Tools のフォルダにあるJavaBrowserで確認することが できます。あるいは、以下のページから確認して下さい。
Java 5に標準で含まれるすべてのパッケージやクラスの説明
Javaでは、論理型、整数型、実数型、文字型の型があります。また、文字列はクラスで表現されています。 型とクラスは異なるものなのですが、ここでは、同一のものとして説明します。以下に整数と文字および文字列の記述の 仕方を説明します。
数えることのできる数値を表現するのに用いるための定数です。 数学的には、整数は、離散数(Discrete Number)とも呼ばれています。 整数型は、一般にはIntegerの名前から、intという型が用意されているのですが、 内部的に表現するためのビットサイズに応じて、その他の型も用意されています。 各型に対して、表せる範囲が限られているので注意してください。
int -2147483648〜2147483647 // 32ビット long -9223372036854775808L〜9223372036854775807L // 64ビット
定数の例:330 -522167 +20394
定数そのものを記述した場合は、int型の定数とみなされます。 また、足し算や引き算などを行なったときに、内部の計算では、byte型、short型もint型に変換されて計算されます。 強制的に64ビット長の、long型の整数にしたい場合には、最後にLかl(小文字のエル)を付けます。
long型の整数の例:456L 80l
通常は、数は10進数で表しますが、Java言語では特殊な用途のために、16進数も表現することができます。 これは、元々コンピュータが2進数を使ってすべての情報が表現されていることに起因しています。 2進数は、1と0だけを用いて情報を表しますが、これだと人間には非常に読みづらいので、 2進数を4桁ごとに区切った16進数がよく用いられます。
16進数の場合は、最初に0xを付けます。数字の0〜9以外に、文字のa〜fまでも用いることができます。 A〜Fは大文字でも小文字でも構いません。文字のa〜fは、10進数に換算すると、10〜15までの数を表しています。
16進数の例:0xafdd 0x568e
ちなみに、0から始まる数はJavaでは8進数として解釈されます。「023」は、10進数で2×8+3→「19」という 値を持ちます。
数や文字列を表示するのに、タートルグラフィックスでは、 printや printLineメソッド (あるいはJavaの標準ではSystem.out.printやSystem.out.printlnメソッド)を 用いることができます。printLineメソッドの方は、表示した後に改行をしてくれます。 以下のプログラムの断片は、startメソッドの中だけを記述しています。
printLine( 45 ); // 45と表示されます printLine( -78L ); // -78と表示されます(すいませんlong型ありません、printLine( -78L );を使ってください) printLine( 0x44 ); // 16進数が変換され、10進数で68と表示されます
なお、整数を符号なし16進数で表示したくなった場合に、Java標準のIntegerクラスに次のようなメソッドが用意されています。
Integer.toHexString( <整数式> )
printLine( Integer.toHexString( 34 ) );
同じように、整数を符号なし2進数で表示したくなった場合に、次のようなメソッドが用意されています。
Integer.toBinaryString( <整数式> )
printLine( Integer.toBinaryString( 34 ) );
ダイアログで入力された10進数の整数値を16進数で、やはりダイアログに表示するプログラムを作りなさい。 クラス名は、DisplayHexagonとします。
1文字でで表せる英数字、ひらがな、漢字等を表現するのに用います。文字定数はシングルクォーテション(')で囲みます。
'A' 'a' 'あ' 'ア' '亜' 'À' 'Ǎ' 'ẵ' 'ℵ' '༁' 'ٱ'
次のような特殊文字が用意されています。バックスラッシュ\は、円マーク(¥)で表されるフォントもあります。 BlueJでもそうですし、Windowsでは、標準的にそうなっています。
\' シングルクォーテーション \" ダブルクォーテーション \\ バックスラッシュ
文字の定数は、内部的には国際規格のUnicodeと呼ばれる2バイトの文字コード表現の規格に基づいて表現されてます。 この規格は、日本語以外に、英語、ロシア語、中国の漢字など、多くの国で使われている文字を表すことができる規格です。 直接Unicodeの文字コードを使って、文字を表現したいときは\uという接頭語をつけて、 4桁の16進数で文字を表現することもできます。
例: \u6f22 // 実は、漢字の「漢」を示しています
端末画面が日本語表示可能な実行環境であれば、printやprintLineメソッドは、Unicodeの文字も表示してくれるでしょう。 ただし、文字型を表示するメソッドが用意されていないので、文字列として表示させます。 また、プログラムのソーステキストの漢字などを一旦Unicodeに変換するためのコンパイラのオプション設定が必要になります。 この設定については、開発環境に依存します。
print( "丸" ); // 日本語が表示可能であれば、丸と表示されます printLine( "\u6f22" ); // 日本語が表示可能であれば、漢と表示されます
文字列は、型ではなく、クラスとして定義されています。複数の文字の連なりを表現するために用います。 複数の文字を扱うのでオブジェクトとしてみなした方が整合性が良いからでしょう。 文字列は、最初から出てきましたので、もうおなじみでしょう。 文字列定数は、ダブルクォーテーションで囲みます。日本語や上で示したような特殊文字も使えます。 なお、下の例のように、ダブルクォーテーションマークそのものを文字列中で表現したいときは、 \"という書き方を使います。
"This is an apple." "This is a sample message, \"WOW\" 春に花が咲きます"
printメソッドでの表示は、文字のときと同じように日本語で表示したいときは、 端末を示すウィンドウのフォントなどを調整したり、コンパイラでのオプション設定が必要となります。 Xcodeでは、日本語を実行ログでうまく表示するにはかなりの設定が必要になります。
print( "雨にも負ケズ、風にも負ケズ" ); //BlueJだと一発で表示されます。
なお改行コードはオペレーティング・システムで変わります。UNIXはLF、MacintoshはCR、そしてWindowsはCR+LFです。 このような改行コードの違いを吸収するために、タートル・グラフィックスでは getLineFeed( )メソッドを用意してあります。 これは、System.getProperty( "line.separator" )と同じ働きをします。以下のプログラムは、startメソッドの中だけを記述しています。
String linefeed = getLineFeed( ); print( "途中で改行される" + linefeed + "テキスト" );
論理値、整数、長桁整数、16進数で表された文字を含む文字列を、ターミナルウィンドウに出力するプログラムを作成しなさい。 クラス名はPractice0303とします。
BlueJが何かうまく動いてくれないことがあります。そのときは、次のようなことを試して下さい。
- 「アプリケーションが実行中でコンパイルができません」と表示されるとき→該当するアプリケーションが まだ実行されています。タートル・グラフィックスのときには多く発生します。該当するJavaのアプリケーション をまず終了させるようにしてください。
- 全般的に何故か動きが悪いとき→一度、BlueJを終了させましょう。再起動したら元気になることが多いようです。
- 「BlueJのVMがネットワーク関係で動かない」と英語で表示されるとき→アプリケーションのフォルダの中にある CNSToolsの「CNSiMacを初期化する」のスクリプトを動かしてみて下さい。それで直ります。 ただし、タートル・グラフィックスのライブラリは再インストールしてください。
- メールも読めないし、ダウンロードもうまくいかないとき→Quota(個人に割り当てられているディスク領域の制限) を超えていることがほとんどです。不要な映像ファイルなどを削除して下さい。
おまたせしました、先ほどからでている<式>(Expresssion)の正体なのですが、 これは普通の計算式だと思ってくださると助かります。まず、<式>の書式なのですが、下の表のような文法規則に なっています。 数を宣言した後は、宣言された変数や定数、そして演算子を使って式を記述することができます。 式は、いろいろな計算をさせるための記述で、基本的には算数や数学で習ったものと同じと考えてください。 式には、次のようなものがあります。他にもいろいろあるのですが、ここでは一番簡単なものだけを挙げておきます。
▼式:
<定数>
<変数>
+ <式>
- <式>
<式> + <式>
<式> - <式>
<式> * <式>
<式> / <式>
<式> % <式>
(<式>)
これだけだとなんだかよくわかりませんが、加減乗除はできるのがわかります。 「演算子」(Operator:「+」や「-」などの記号のこと)は、すべて半角で記述してください。 全角で記述するとコンパイラに「わかりません」と叱られます。 掛け算や割り算の記号が、通常のものとは少し異なることに注意しておいて下さい。全部半角の記号です。 乗算の場合は、×ではなくて、半角のアスタリスク「* 」で記述します。 また、除算の場合は÷ではなくて、半角のスラッシュ「/」で記述します。 %は、あとで説明する剰余算です。余りが求められます。これも半角の%を用いてください。 丸括弧は、式を計算する優先順位を変える為のものです。 上記の文法規則に従って、具体的な式の記述を見てみましょう。わかりやすくするために、式はすべて 丸括弧で囲ってあります。優先順位をあげる必要性のないときは、囲む必要はありません。
takochan = ( 45 * 33 ) /2; //代入文の例です。この場合括弧はつけなくても構いません。 ( takochan + 3 ) * 2 //式の例、足し算を優先させるために括弧をつけています。 3 - 453 / 33 //式の例、右側の割り算の方が優先されます。 4758 + 344 + //これは式として認識されず、文法エラーになります。 576 % 3 //剰余算の例、後で解説します。 ( ( takochan * 3 ) + 2 ) / takochan //式の例、括弧はネストしても大丈夫です。
優先順位は、上記の例を見てもわかるように、掛け算、割り算、剰余算の方が優先されます。 足し算や引き算を優先させたいときは、丸括弧で囲むようにしましょう。 同じ優先順位の場合は、左から右へと計算が行なわれていきます。
例えば、この式の書式に基づいて、次のように記述できます(ここで、xやyは変数の名前)。
589 + y * ( x - 28 )
式は必ず計算されて、計算結果が単一の値(定数)になります。この計算のことを式の評価(Evaluation)と呼んでいます。 上の例であれば、変数xに13という値が、変数yに56という値が入っていれば、計算結果は、-251という値に落ち着きます。
式を考える上で、2つの側面を見なければなりません。まずは、記述されたものが式の書き方の規則に 則っているかどうかです。上の例について考えてみましょう。
589 「定数そのもの」だから式 y 「変数そのもの」だから式 x 「変数そのもの」だから式 28 「定数そのもの」だから式 x - 28 「式 − 式」に合っているので式 ( x - 28 ) 「( 式 )」に合っているので式 y * ( x - 28 ) 「式 * 式」に合っているので式 589 + y * ( x - 28 ) 「式 + 式」に合っているので式
このように、よく見てみると上の規則に則っているので式であるとコンパイラに認識されています。 このような書式上の規則のことは、自然言語に倣って文法(Syntax)」と呼ばれています。 文法にあっていないものは、式として認識されません。例えば、以下の記述は、Javaの式の文法としては間違いです。
3 x + 5 y
式の文法規則に見合った式が記述された場合、コンパイラは文句を言ってきません。 そして、プログラム実行時に、優先順位の高い演算から計算が、行なわれ、一つの定数に落ち着くまで 式が計算されます。この計算のことを「式の評価(Evaluation of Expression)」と呼んでいます。 式の評価は、次のような規則で実行されます。
- 変数があれば、それが保持する値に置き換えられる
- 括弧がついていれば、括弧の中の部分式から計算される
- 優先順位の高い演算子があれば、そちらの演算子から計算される
- 同じ優先順位の演算子がある場合は、左から右に計算される(Left Associative)
- 最終的に1つの定数になるまで、計算が行なわれる
たとえば、整数の変数「takochan」に10が代入されているとして、次のような式を計算してみましょう。
(54+takochan) / 8 + 3 * 24 / 6
まず、変数のtakochanがそれが保持する定数10に置き換わります。そして、優先順位を上げるための丸括弧が ついていますので、「54 + 10」という部分式がまず計算され、64になります。 次に「64 / 8」が次に計算され、答えは8になります。 足し算は優先順位が低いので後からになります。 「3 * 24 / 6は」同じ優先順位の演算子が続くので、左から右に計算され、「72 / 6」で12が求まります。 最後に足し算が行なわれ、「8 + 12」 → 20という形で式の評価がなされます。 評価はこのように必ず1つの値(定数)に落ち着くまで計算が実行されます。
Javaの式を考える上で、式が構文規則に則っているかに加えて、 式はどこから計算されるかという点にも気をつけなければなりません。 式は、評価されて、最終的には単一の定数値になります。 この評価の際には、優先順位(priority order)について考える必要があります。 これは、一般の数学(算数)と同じです。まず、括弧のついているものは、先に評価されます。 括弧が多重になっている場合は、一番内側から評価されます。 また、掛け算、わり算、余りについては、足し算や引き算よりも先に評価されます。 では、以下の式が一体どこから評価されるかについて考えてみてください。
2 + (( x - 3 ) * y ) / 4
以下に、より正確に式の評価における優先順位の法則について記述していきます。
▼乗法演算子と加法演算子:
乗法演算子: * / %
加法演算子: + -
Javaでは、掛け算・割り算・剰余算の3つの演算のことを乗法演算と呼び、 足し算・引き算のことを加法演算と呼んでいます。 通常の算数と同様に、乗除剰余算が先に計算されます。 ただし、単項の+や-は乗法演算子よりも優先順位が高くなります。 乗法演算子と、加法演算子の中では、同じ優先順位を持ち、左から評価されます(Left Associative)。
式の評価の例:xが20の値を持っているとします。yに代入される値は、次のように評価されます。
y = ( 10 + x ) * 5 - 15; ↓ 10 + 20 ↓ 30 * 5 ↓ 150 - 15 ↓ 135
式は代入文の右辺に書ける以外にも、メソッド呼出しのパラメータ(実引数)の部分にも記述することができます。
printLine( 34 + 5 * 27 + y );
メソッドのパラメータの部分に記述された場合は、次の順番で実行が行なわれます。
1.パラメータ(実引数)の式が評価され、定数になるまで計算される
2.その定数の値をパラメータ(実引数)として、メソッドが呼び出される。
この例の場合には、まず5*27を計算し、次に34+135+yを計算してから、その計算結果の定数が実引数になって、 printLineメソッドが呼び出されることになります。
メソッド呼出しのパラメータとして、式や定数、あるいは変数を記述するときには、型を気にする必要があります。 例えば、displayDialogメソッドは、第1パラメータとして文字列を要求しています。
displayDialog( 45 ); // 整数であり、文字列ではない。 displayDialog( 100, 100 ); // パラメータの数が異なる。
のようなメソッド呼出しは、コンパイラによって間違っているとしてはねられてしまいます。 45という整数の数と、"45"という数字からなる文字列は違う型に分類されます。 文字列に変換して、整数や実数を表示させる方法は、後の節で説明します。
さて、整数型の変数や式というのは、電卓と異なり、ちょっと違った特性を持っています。その1つが整数除算です。 割り算の結果は、どうなるのかというと整数になります。整数は、小数部分がありませんので、切り捨てになります。 ですから、「10 / 3」の評価結果は、3になります! 評価結果は、プラスもマイナスも原点(0)に近づくように小数部の切捨てが行なわれます。
整数除算の例: 5 / 3 → 1 // 1.66666...の小数部が切り捨てされ、整数になる 1 / 3 → 0 // 0.33333...の小数部が切り捨てされ、整数になる 5 / 2 * 2 → 4 // 5 / 2 = 2.5の小数部が切り捨てされ、整数になる 5 / - 3 → - 1 // 5 / -3 = -1.666666の...の小数部が切り捨てされ、整数になる
しかも同じ優先順位の演算子の評価順序が左から右になりますので(左結合性)、掛け算を先に行なった場合 と割り算を先に行なった場合、評価結果が異なってきます。
5 / 2 * 2 //これは、2 * 2で4に評価されます。 5 * 2 / 2 //これは、10 / 2で5に評価されます。 1 / 3 * 3 //これは、なんと0に評価されます。 -1 / 3 * 3 //もちろん、マイナスでも同じようなことが起こります。0に評価されます。
「Practice0304」という名前で新規クラスを作成し、下記のプログラムをstartメソッドのブロックの中に入力しなさい。 保存(上書き保存:⌘+S)し、コンパイルし、実行してみなさい。文字列やコメントの日本語以外のところは、 すべて半角英語ですから注意して下さい。
// 入力された値を3で割ったり掛けたりして、元の数になるかどうか表示するプログラム int takochan; takochan = displayInputIntegerDialog( "整数を入力して下さい", 10 ); displayDialog( "割り算を先にやりました。" + (takochan / 3 * 3 ) ); displayDialog( "掛け算を先にやりました。" + (takochan * 3 / 3 ) );
整数剰余というのも聞き慣れない言葉ですが、これは小学校のときにやった、「23÷3=7余り2」の、この2の 部分を求めるための演算です。ある正の数mを、別の正の数nで余りを取ったときには次のような評価結果になります。 %が、剰余の演算子となります。<
m % n → 0〜n-1の答えが出てくる
0になる場合は、mがnで割り切れることを示す。あるいは、mがnで割り切れるときは0になる。
整数の剰余算の例: 7 % 3 → 1 // 7 ÷ 3 → 2 余り 1 68 % 12 → 8 // 68 ÷ 12 → 5 余り 8 39 % 13 → 0 // 39 ÷ 13 → 3 余り 0 (39は13で割り切れる)
さて、整数剰余のマイナスの数の場合は複雑です。Javaと同じであれば、整数除算を行なって、割った数とその結果を掛けたものを、 元の割られる数にするために補う数が剰余算の結果になります。以下のサンプルから考えてみて下さい。
マイナスの整数の剰余算の例: 55 % -12 → 7 // 計算理由:55/-12の結果は -4 、-12*-4 →48、48+ 7→55だから。 -9 % 5 → - 4 // 計算理由:-9/ 5の結果は -1 、5 * -1→-5、-5 + - 4 → -9だから。 -26 % -5 → - 1 // 計算理由:-26/-5の結果は 5 、-5 * 5 →-25、-25 + - 1 → - 26だから。 23 % -7 → 2 //計算理由:23/-7の結果は-3、-7 * -3→21、21 + 2→ 23だから。
整数除算や剰余と位取りの数の表記とは密接な関係にあります。 10進数の場合は基数が10ですから、10で整数除算や整数剰余を行なえば、それぞれの桁の数を取り出すことができます。
67 / 10 → 6 // 上位の桁を取り出すことができる 67 % 10 → 7 // 下位の桁を取り出すことができる
4桁の整数をダイアログ(あるいはターミナル)で入力してもらい、上位2桁と下位2桁を別々に ダイアログ(あるいはターミナル)に表示するようなプログラムを作成しなさい。 クラス名は、DecomposeFourDigitsと致します。さらにできる人は、4つの桁それぞれを別々表示するように 変更して見なさい。
ダイアログに秒数を入力してもらうように表示します。 入力を文字列で受け取り、時間数:分数:秒数に分けて表示するプログラムを作成しなさい。 たとえば、94867と入力されたら、「26時間:21分:7秒」と表示するようにします。 クラス名は、DisplayConvertedSecondsとします。コンパイルして実行してみなさい。
ダイアログに4桁の2進数の整数を入力してもらうように表示します。 これを10進数に直して表示するようにしなさい。 1100と入力されたら、「12」と表示するようにします。 クラス名は、ConvertFourBinaryDigitsとします。コンパイルして実行してみなさい。
Javaでは、文字列どうしの足し算を行なうことができます。文字列定数どうしは、引き算や掛け算などはできませんが、 足し算だけは可能です。これは、文字列をそのまま結合(Concatenate)させる演算を行なうものです。
"千里の路も" + "一歩から" → "千里の路も一歩から"
数字から構成される文字列として足し合わせてみると、ちょっと整数の足し算とは違う結果になります。
"2345" + "6789" → "23456789"
Javaでは、文字列どうしだけでなくて、文字列と整数、あるいは文字列と実数なども足し算することができます。 このときに、整数や実数あるいは論理値、すべてのクラスのオブジェクトは、文字列と足し算を行なうと自動的に文字列に 変換されます。一番簡単に整数や実数を文字列に変換するには、中身のない文字列と足し合わせることです。 中身のない文字列(空の文字列)はダブルクォーテーション・マークを2回続けて記述します。 文字列との足し算が計算式に現れたときから、文字列に変換する評価が行なわれます。
123 + "" → "123" 7832974232L + "" → "7832974232" ""+true+false → "truefalse"
加えて、何らか意味を表わす文字列と足すとかなり流暢な形で文字列の形に直すことができます。
333 + "mの高さのタワー" → "333mの高さのタワー" 12 * 5 + "個のみかん" → "60個のみかん"
これを利用して、変数が持つ値を表示させることも可能となります。例えば、変数xに10が入っていたとすると、 次のように変換されます。
" x の値は" + x + "です" → "xの値は10です"
単に、変数を中身のない文字列(空の文字列)と結合すると、変数に代入されている 整数や実数が取り出されて、そのまま文字列に変換することができます。 同じように変数xに10が入っているとしましょう。
"" + x → "10" x * 10 + "" → "100"
ただし、足し算は左結合性持っていますので、左から評価が行なわれていくことに注意してください。 足し算の演算子を持つ計算式を左から評価していったときに、どこかに文字列が出てきた時点で、 そこから「文字列への変換と結合」として解釈されます。 予め整数の足し算を計算しておきたいときは、 次のように括弧を付ける必要があります。なお、掛け算は優先順位が高いので予め整数で計算されます。 先ほどと同じで、変数xに10が入っていたとしましょう。
" 高さ" + x + 4 + "フィート" → "高さ104フィート" " 高さ" + ( x + 4 ) + "フィート" → "高さ14フィート" " 高さ" + x * 4 + "フィート" → "高さ40フィート"
なお、16進数や8進数は、文字列と足し算をすると、10進数の数として扱われ、その10進数としての数字の文字列に変換されます。
"" + 0x1a → "26" // 16進数の1aは、1×16+10→26 "" + 062 → "50" // 8進数の62は、6×8+2→50
これらの文字列の足し算機能を使って、整数や実数、論理値の計算結果や、変数の値を、タートル・グラフィックスでは、 文字列としてdisplayDialogメソッドやprintメソッド、あるいはprintLineメソッドの中で表示することができます。
printLine( "東京にある" + 111 * 3 + "mの高さのタワー" ); print( x + "坪の大きさ" ); displayDialog( "体重" + x * 4 + "kg " ); displayDialog( "value of variable x is :" + x + ". This is " + true + ". " );
整数を入力するダイアログを2回出して、ユーザから分と秒を入力してもらうようにします。 これを秒数に変換して、ダイアログに表示するようにしてみなさい。 クラス名はPractice0305で作成し、コンパイルして実行してみなさい。
<<Previous Lecture | >>Next Lecture |