「変数」の考え方は、プログラミングの重要な基礎です。1つのプログラムをいろいろな状況のもとで正しく稼働させるといった汎用性を持たせるとき、変数の機能は欠かせません。また、複雑な処理や大量のデータを扱うということも、その手がかりは変数にあります。しかしながら、変数そのものの考え方は抽象的です。この章では、いくつかのサンプルを用いて、変数がこんな風にも使えるということを説明しましょう。
この章で入力するプログラムとアプリケーションのひな形を作っておきましょう。手順については、これまでの章とまったく同じですので、ここでは手順は示しません。ウィザードの画面のうち、ポイントになる部分だけを示しておきます。クラスの名前を設定する時、パッケージの名前と「public static void main(String[] args)」のチェックを入れておく事を忘れないようにしましょう。
変数は値を覚えておくものというのは本来の機能ですが、その値に意味を持たせることで、ある種の状態を覚えておくことも可能になります。そうすれば、以前に行った判断結果などをプログラムの後の方で使うということもできるようになります。こうした使い方に決まった名前はありませんが、「フラグ」や「ステータス変数」などと言った言い方がなされます。
フラグというのは文字通り旗のことで、旗が立っているか立っていないかという状態から類推するとわかりやすいかもしれません。たとえば、ある条件がYESなら旗が立っている、NOなら旗が立っていないとう状況です。たとえば、部屋の外の気温を測定して、20度以上なら旗が立っている、20度以下なら旗が立っていないとします。部屋の中から旗が立っているかを確認すれば、暖かいのか寒いのかがわかるという具合です。すると、こうした状況を変数で覚えさせて管理する場合、フラグやあるいはフラグ変数などと呼んでいます。
ただ、ここで、フラグ変数用のコマンドとか書き方がJavaにあるというわけではありません。一般にプログラミングの世界では、汎用的な機能が中心にあるため、その言語の状況に合わせてフラグ的な働きをするように、プログラムを組むというのがポイントになります。たとえば、int型だといろいろな数値が記憶できますが、0ならNO、それ以外の数値ならYESなどとあらかじめ決めておいて、それに従ってフラグとして機能するようにプログラムを組むということができます。もちろん、1がNOで2がYESでもかまいません。プログラムが正しく動作すればいい訳です。しかしながら、最初に決めた規則は、しばらくすると「どう決めたっけ?」などと覚えていないものです。メモを書いておくのも手ですが、面倒だとそのままやりすごすと、翌日に自分の作ったプログラムを解析・分析することになりかねません。
YESかNOの2通りの場合しかないのなら、Javaではboolean型を利用できます。boolean型はその意味ではフラグとしての動作をそのまま組み込んだものと思ってもいいでしょう。boolean型は、値として「true」「false」のどちらかしか取りません。また、プログラムの中でも、そのままtrue、falseと書くことができます。数字をそのままプログラムの中の式で書いてもいいのと同じように、true、falseはプログラム中に存在できる特別なキーワードなのです。
それでは、状態を覚えておくという変数の使い方を行うプログラムを入力して実行してみます。VariableExam.javaのプログラムの、public static void mainの最後のところに、以下のようなプログラムを入力します。プログラムを入力する場所は、これまでの章と同じです。
int number = 19;
boolean check = false;
if ( number % 3 == 0 ) {
check = true;
}
if ( number % 5 == 0 ) {
check = true;
}
if ( check ) {
System.out.println(number + "は、3の倍数ないしは5の倍数です。");
} else {
System.out.println(number + "は、3の倍数ではなく、5の倍数でもありません。");
}
ここで、最初の「int number = 19;」の「19」の代わりにいろいろな数字を入れて実行し、コンソールに表示されてる内容をみてください。たとえば、21は3の倍数ですので、次のように表示されます。
たとえば、20は5の倍数ですので、次のように表示されます。
少し面倒ですが、ここで、プログラムの中の定数をいろいろな数値に変えて、その都度実行を行って結果をみてください。いずれにしても、変数numberに記憶させた数値が、「3ないしは5の倍数」なのか「3の倍数でも5の倍数でもない」のどちらかであることを判断しているプログラムであることがわかります。
プログラムでは、倍数かどうかの判断が入っています。そうした機能がJavaにあるのかといえば、実は直接そうした機能を実現するものは何も用意されていません。しかしながら、整数の割り算の余りを求めるという計算処理が可能なので、その結果から「倍数かどうか」の判断をすることができるのです。たとえば、「3の倍数かどうか」は、「3で割った余りが0かどうか」で判断ができます。「3で割った余りが0かどうか」という条件は、Javaで書くことができます。
変数numberを3で割ったあまりは「number % 3」で求めることができます。%が、+や-と同じような演算子なのです。計算で求めた結果が0かどうかということで、「number % 3 == 0」という条件式を作ります。ここで、先に3で割った余りを求めて、その値が0と等しいかどうかを求めています。これが「演算子の優先順位」というもので、Javaでは文法として順位が決められています。この順位についてはすでに紹介しています。もし、numberが18なら、18 % 3の結果は0になります(もちろん、割り算の結果は6です)。よって、「0 == 0」という判断が行われて等しいので結果はboolean型のtrueになります。もし、numberが14なら、14 % 3の結果は2なので、2 == 0という判断はfalseになります。よって、numberが3の倍数のときのみifの条件がtrueとなるため、その次の「check = true;」が実行されるということになります。
変数のcheckはもともとfalseになっていました。もし、numberが3の倍数であれば、ifのあとには変数checkへの代入が行われてcheckの値はtrueになります。numberの値が3の倍数でなければ、変数checkの値はfalseのままになります。
なお、ここで等しいかどうかの判断に==を使っていることに注意をしてください。=は1つではだめです。この場合、等しいかどうかではなく、代入するという演算子として解釈されます。こうしたミスはなかなか見つけられないので、しっかりと理解をしておく必要があります。
変数を利用して、ある条件に合ったものの個数を数えるということができます。もちろん、数え終わったら、そこから後では、条件に合ったものの個数を記憶しておくものとして利用できます。
VariableExam.javaのプログラムの、public static void mainの最後のところに、以下のようなプログラムを入力します。プログラムを入力する場所は、前のプログラムの続きのところにします。
int upperLimit = 100;
int counter = 0;
for ( int i = 1 ; i <= upperLimit ; i++ ){
if( i % 7 == 0 ){
counter++;
}
}
System.out.println(counter + "個あります。");
まず、forで繰り返す部分の内側を見てみます。if文がありますが、すでに前のところで説明したように、変数のiが7の倍数かどうかを判断する条件式であることが分かります。変数iは、その前の、forの引数で定義されているので、forで繰り返す部分で使えます。ここは、つまり「iが7の倍数なら、変数counterの値が1つ増える」と解釈ができます。
次にforによる繰り返し部分をみてみましょう。カウンタ変数としてはiを使っていますが、ここでは、iの値が1からupperLimitの値で指定した値まで1ずつ増加して変化します。前の章での繰り返しでは、0から…というやり方ですが、このように1からスタートしてもかまいません。このとき、繰り返しを抜ける条件が、前の章では<だけだっのが、<=になっていることに気づいてください。
たとえば、upperLimitが3だとしたら、1が7の倍数かどうか、2が7の倍数かどうか、3が7の倍数かどうか、と判断して繰り返しを抜けることになります。つまり、upperLimitで指定した数値までの間に、7の倍数がいくつかあるかを変数counterを使ってカウントすることができるわけです。ただし、そのために、counterの値を最初に0にするというところがあります。これは非常に重要な概念で、「初期化」などとも言われています。文法上、変数を定義した当初は0に設定されるので、0を代入する必要はこのプログラムではないのですが、個数を数えるような変数を使う直前に初期値にするというのは作法としては必須のことです。たとえば、前に使った同じ変数使うような場合、初期値が重要ですし、プログラムにさせたいことによっては初期値は0でないかもしれません。初期化する必要性がポイントになります。
ここまでで、「3ないしは5の倍数」かどうかを判断するプログラムと、条件に合ったものを数えるプログラムを紹介しました。それでは、ここで2つのプログラムをうまく合体させて「3ないしは5の倍数の数を数える」というプログラムを作ってみます。VariableExam.javaのプログラムの、public static void mainの最後のところに、以下のようなプログラムを入力します。プログラムを入力する場所は、前のプログラムの続きのところにします。
counter = 0;
for ( int i = 1 ; i <= upperLimit ; i++ ){
boolean checkNumber = false;
if ( i % 3 == 0 ) {
checkNumber = true;
}
if ( i % 5 == 0 ) {
checkNumber = true;
}
if( checkNumber ){
counter++;
}
}
System.out.println(counter + "個あります。");
少しややこしい感じになってきました。プログラムの動作をよく検討してください。繰り返し部分は、1ならどうなる? 2ならどうなる? …と考えますが、たとえば、50なら? 73なら? などととびとびの値でもかまいません。そのとき、変数がどのように推移するかを考えます。これにより、1からupperLimitで指定した数までの間に、3ないしは5の倍数がいくつあるかをカウントすることができます。
なお、こうしたプログラムはいろいろな書き方ができます。このプログラムは決してベストなものとは言えないでしょう。しかしながら、どのようにプログラムを作っても、意図した通り機能すれば問題ないという考え方もあります。いずれにしても、プログラムの書き方はひととおりではないことを知っておいてください。
繰り返しを行うのはforやwhileなどを使う訳ですが、繰り返しをさらに繰り返すということも可能です。つまり、繰り返す一連のプログラムの中で繰り返しを行うと言った状態になります。このように、内側に繰り返しがあるような状態を「ネストしている」や「入れ子になっている」といった言い方を行います。
たとえば、かけ算の九九の結果を求めるプログラムとしては次のようなものがあります。結果の表示はあまり美しくないのですが、とりあえず、かける数とかけられる数が、それぞれ、1から9まで変化するという場合、入れ子になった繰り返しですべての種類の計算ができます。
for ( int x = 1; x <= 9 ; x++ ) {
for ( int y = 1; y <= 9 ; y++ ) {
int r = x * y;
System.out.println( x + "×" + y + "=" + r );
}
}
実行結果は1つの計算に1行を使っているので、みづらいものになっていますが、System.out.printlnのステートメントが、81回繰り返されていることに注目してください。つまり、9回の繰り返しを9回行うので、9×9=81回です。
変数rの値は、xとyのかけ算の結果です。ここの部分「int r = x * y;」ですが、この部分にはじめて実行処理がやってきたときは、x=1、y=1です。では、2回目はとなるとyが1つ増えてx=1、y=2としてやってきます。その結果は、メッセージペインで確認できるはずです。
7-1: 7-2節では、「3ないしは5の倍数の数を数える」というプログラムを紹介している。ここで、同じ作業を行うものの、フラグという手段を使わない方法で、判断を行い、「3ないしは5の倍数の数を数える」というプログラムを作ること。ヒントは、||といった演算子を使う。「if( 条件式1 || 条件式2 ) …」という書き方で、2つの条件式のいずれかがtrueの場合、if全体の条件式はtrueとみなされる。
7-2: 演習問題の7-1のプログラムをもとに、「3の倍数でかつ5の倍数でもある数を数える」というプログラムを作ること。ヒントは、&&といった演算子を使う。「if( 条件式1 && 条件式2 ) …」という書き方で、2つの条件式の両方がtrueの場合にのみ、if全体の条件式はtrueとみなされる。
7-3: かけ算の九九は81通りの計算があるが、かけ算はかける数とかけられる数が入れ替わっても計算結果は同じである(つまり、a×b=b×a)。したがって、3×4=12を覚えれば、4×3は覚えなくてもいいとも言えるだろう。では、かけ算九九をマスターするために最低限覚えないといけないかけ算のパターンはいくつあるかを求めるプログラムを作ってみよう。
7-4: ある整数を変数numberに入力する。その数が素数かどうかを判断して、判断結果を表示すること。ヒント:素数とは、1とその数以外に割り切れる整数がない数のこと。たとえば、3,5,7,11...。ということは、たとえば、13が素数かどうかを判断するには、2,3,4,5,6....12までの数値で順番に剰余を求めてみて、もし、剰余が0になる数字があれば、その数は素数ではないと言える。ただ、効率の上では、2で割り切れないのに、4で割り切れるはずはない。また、13の場合だと、7以上の数値で割り切れるわけではないので、その意味では、2〜(その数の半分)までをチェックするということでことは足りる。ただ、そこまでの機能を組み込んでもいいし、組み込まなくてもいい。まずは正しい結果が得られるようにがんばってみよう。