[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIB(Javaプログラミング入門)第3回

目次
3.1 操作法のヒント
3.2 プログラムとは
3.2.1 プログラムとソフトウェア
3.2.2 アルゴリズムの例
3.2.3 プログラミング言語とプログラム
3.3 コメントとインデント
3.3.1 コメント
3.3.2 インデント
3.4 式と演算子(1)
3.5 変数と代入文
3.5.1 変数とは
3.5.2 変数の初期化
3.5.3 変数の値の変更
3.5.4 変数の使用例
3.6 演習3
3.7 レポート課題
3.8 参考文献
索引
  アルゴリズム   インデント   演算子   コメント     初期化   初期値   宣言   宣言文   代入   代入文   プログラマ   プログラミング   プログラミング言語   プログラム   変数   変数名  

3.1 操作法のヒント

よく利用するアプリケーションは、Dockに登録しておきますと、次回からはワンクリックで起動できるようになります。 登録したいアプリケーションのアイコンを、Dockの適当な位置(縦線の左側)にドラッグ・アンド・ドロップしてください。 ただし、「ターミナル」を起動する"Shift_JIS.term"アイコンについては、Dockの縦線の右側に登録します。

「ターミナル」でコマンドを入力するとき、途中でtabキーを押しますと、自動的に残りの部分が入力されます。 ただし、残りの部分に複数の候補がある場合は、自動入力されるのはその共通部分のみです。 また、上矢印キーを押しますと、直前に入力したコマンドが現れ、下矢印キーを押しますと、直後に入力したコマンドが現れます。


3.2 プログラムとは

3.2.1 プログラムとソフトウェア

この授業の内容は、Javaのプログラムを作成することです。 そもそも、プログラムとは何でしょうか。

簡単に言えば、プログラムとはソフトウェアの設計図です。 パソコンには、ワープロ・ソフトやメール・ソフトなど、色々なソフトウェアがインストールされています。 誰かが、ワープロ・ソフトのプログラムやメール・ソフトのプログラムを作成したから、パソコンでワープロ・ソフトやメール・ソフトが利用できるのです。

ただし、この他人まかせの考え方では、プログラムを作成できるようにはなりません。

ここでは、次のように用語を定めます。

3.2.2 アルゴリズムの例

アルゴリズムの説明で、問題解決と言われても、ピンと来ないかもしれません。 例として、次の問題を考えます。

与えられた文字列が回文か否かを判定せよ。 ここで回文とは、「たけやぶやけた」のように、左から読んでも右から読んでも同じになる文字列のことである。

この問題は、次のような手順で解決できます。

  1. 与えられた文字列を s1 とする。
  2. s1 の左右を逆転した文字列を生成し、その文字列を s2 とする。
  3. s1s2 を左から一文字ずつ比較する。
  4. もし途中で文字の違いが見つかったら"No"と答える。
  5. 最後まで文字の違いが見つからなかったら"Yes"と答える。

今、「いるかはまるい」という文字列が与えられたとします。 s1 は「いるかはまるい」に、 s2 は「いるまはかるい」になります。 左から一文字ずつ比較しますと、3文字目で違いが見つかりますので、"No"と答えます。 一方、「たけやぶやけた」の場合は、 s1 は「たけやぶやけた」に、 s2 も「たけやぶやけた」になります。 左から一文字ずつ比較しても違いは見つかりませんので、"Yes"と答えるというわけです。

この手順は、回文を判定するという問題を解決するものです。 したがって、回文判定のアルゴリズムなのです。

アルゴリズムは必ずしも一つとは限りません。 以下も回文判定のアルゴリズムです。

  1. 与えられた文字列を s1 とする。
  2. s1 の左から1番目の文字と右から1番目の文字、左から2番目の文字と右から2番目の文字、…と順番に比較する。
  3. もし途中で文字の違いが見つかったら"No"と答える。
  4. 文字列の中央になるまで違いが見つからなかったら"Yes"と答える。

3.2.3 プログラミング言語とプログラム

アルゴリズムが分かっても、そのままではコンピュータは問題解決をしてくれません。 コンピュータが日本語を理解するわけでもありませんし、どうやって「左右を逆転した文字列を生成」するのかも、はっきりしていません。 コンピュータに問題解決をしてもらうためには、コンピュータに処理できるような形で、アルゴリズムを具体的に表現する必要があります。 この表現のための言語がプログラミング言語であり、表現自身がプログラムです。

Javaはプログラミング言語のひとつです。 この授業の目的は、アルゴリズムをJavaのプログラムで表現し、コンピュータに問題解決をさせることであると言えます。 Java言語を覚えることと、アルゴリズムを見つけることは、無関係ではありません。 Javaの知識があればこそ、Javaで表現しやすいアルゴリズムが構成できるからです。 授業では、Java言語、アルゴリズム、およびプログラミングを並行して身につけることにします。

なお、プログラミング言語はJavaの他にもたくさんあります。 現在よく使われいるのは、C, C++, Javaです。 それなりに使われているのは、Fortran, Cobol, Lisp, Basic, Pascal, Prologといったところです。 プログラミング言語が変われば、解決しやすい問題の種類や、プログラムに対する考え方が変わります。 今はJavaで精一杯かもしれませんが、色々なプログラミング言語を経験し、問題や考え方に応じてプログラミング言語を選べるようなるのが理想的です。


3.3 コメントとインデント

3.3.1 コメント

プログラムの一部や全部の説明文がプログラムの中に書けますと、プログラマにとってプログラムが理解しやすくなります。 このような説明文を コメントcomment ) とよびます。 Javaコンパイラ(javac)は、プログラムに記号 // が現れますと、そこから行末までを無視します。 そこにコメントを書けば、プログラムに影響を与えずにプログラムの説明ができます。 次のプログラムはコメントの使用例です。

class GoodAfternoon {
// b08a001 東 京子 2008年4月25日
    public static void main (String[] args) {
        System.out.println("Good afternoon!"); // 挨拶をする。
    }
}

また、記号 /**/ に囲まれた部分も無視されます。 このふたつは同じ行にある必要はありませんので、たくさんの行を一度にコメント指定できます。 ただし、このコメントは入れ子にできません。 例えば、

System.out.println("Good morning!");
/*
    System.out.println("----------");
    System.out.println("----------");
*/
System.out.println("Good afternoon!");

という部分をコメント指定しようとして、

/*
    System.out.println("Good morning!");
    /*
        System.out.println("----------");
        System.out.println("----------");
    */
    System.out.println("Good afternoon!");
*/

と書きましても、最初の */ までがコメントだと見なされてしまいます。

3.3.2 インデント

プログラムの行頭のスペース(字下げ)は インデントindent ) とよばれます。 Javaコンパイラ(javac)は行頭のスペースを無視します。 インデントをうまく使いますと、プログラムの構造を見やすくできます。

上記のプログラムでインデントを用いませんと

class GoodAfternoon {
// b08a001 東 京子 2008年4月25日
public static void main (String[] args) {
System.out.println("Good afternoon!"); // 挨拶をする。
}
}

となります。 最後の2つの閉じブレース( } )がそれぞれどの開きブレース( { )に対応しているかが分かりにくいです。 インデントを用いずに長いプログラムを書きますと、ブレースの対応が分からなくなり、プログラムの構造を見えなくしてしまいます。


3.4 式と演算子(1)

前々回の授業では、Javaアプリケーションの例として、「ターミナル」にGood afternoon!と出力するプログラムを動かしてみました。 また、前回は、アプレットの例として、絵を描くプログラムを作成しました。 今回は、再びアプリケーションに戻りまして、数(特に整数)を取り扱うことにします。

次のプログラムを動かしますと、「ターミナル」で以下のような出力が得られます。

/*  1*/ class ExpressionTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println(100);
/*  4*/         System.out.println(250 + 100);
/*  5*/         System.out.println(250 - 100);
/*  6*/         System.out.println(250 * 100); // 掛け算
/*  7*/         System.out.println(250 / 100); // 割り算
/*  8*/         System.out.println(250 % 100); // 割った余り
/*  9*/         System.out.println(1000 + 250 * 3);
/* 10*/     }
/* 11*/ }
asiaa1:~/comp2b b08a001$ javac ExpressionTest.java
asiaa1:~/comp2b b08a001$ java ExpressionTest
100
350
150
25000
2
50
1750
asiaa1:~/comp2b b08a001$

プログラムの最初の2行はそのまま書くものと考えてください。 ただし、 class の右はファイル名です。

プログラム中の 250 + 100 , 250 - 100 などは expression ) とよばれるものです。 プログラムを動かしますと、式が計算されているのが分かります。 ここで、記号 * が掛け算を表していることに注意してください。 また、記号 / は割り算を表していますが、この場合は2余り50という計算をして、2を計算結果としています。 余りを求めるには、 / の代わりに % を書きます。

+ , - , * , / , % などを 演算子operator ) とよびます。

表 3.1  整数( int 型)の演算子
記号 演算
+ 足し算 19 + 3⇒ 22
- 引き算 19 - 3⇒ 16
* 掛け算 19 * 3⇒ 57
/ 割り算 19 / 3⇒ 6
% 割った余り 19 % 3⇒ 1

上記の最後の出力を見ますと、式 1000 + 250 * 3 の計算は、はじめに掛け算をして、次に足し算をしていることが分かります。 これは、演算子 + より * のほうが優先順位が高いと決められていて、式は優先順位の高い演算子から順に計算されるからです。 もし、足し算を先に計算したければ、括弧を使って (1000 + 250) * 3 と書いてください。 この式の計算結果は3750となります。

演算子の優先順位を簡単に説明します。 まず、括弧の中が最優先で計算されます。 次に演算子 * , / , および % が優先します。 最も優先順位が低いのは演算子 +- です。 ここで注意すべきことは、 +- は同じ優先順位であり、これらが続いているときは左から右に計算されることです。 例えば、式 5 - 3 + 1(5 - 3) + 1 と見なされ、3という計算結果になります。 演算子 * , / , % についても同様です。

注意: 割り算で、0 で割ることはできません。 そのような計算を行いますと、エラーが発生してプログラムは途中で停止します。 javacコマンドが成功しても、プログラムが動くとは限らないのです。

/*  1*/ class DivisionTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println(100 / 2);
/*  4*/         System.out.println(100 / 0); // エラー
/*  5*/         System.out.println(100 / 5);
/*  6*/     }
/*  7*/ }
asiaa1:~/comp2b b08a001$ javac DivisionTest.java
asiaa1:~/comp2b b08a001$ java DivisionTest
50
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at DivisionTest.main(DivisionTest.java:4)
asiaa1:~/comp2b b08a001$

3.5 変数と代入文

3.5.1 変数とは

プログラムでは、 変数variable ) というものが重要な役割を果たします。 変数とは、数などのデータが格納できる「入れ物」であると考えてください。 次の図は変数のイメージです。

変数のイメージ
図 3.1  変数のイメージ

変数には名前がついています。 これを 変数名variable name ) とよびます。 この場合は x です。 また、変数にはデータがひとつ格納できます。 これを変数の value ) とよびます。 この場合、変数 x の値は100です。

変数を使えるようにするには、変数の 宣言declaration )という手続きが必要です。 変数の宣言を行うのが 宣言文declaration statement )です。

変数にデータを格納することを、 代入assignment )と言います。 代入を行うのが 代入文assignment statement )です。

変数に格納されたデータを取り出すには、式の中で数の代わりに変数名を書きます。

以下は変数を使ったプログラムの例です。

/*  1*/ class VariableTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int x; // 宣言文
/*  4*/         x = 100; // 代入文
/*  5*/         System.out.println(x);
/*  6*/     }
/*  7*/ }
asiaa1:~/comp2b b08a001$ javac VariableTest.java
asiaa1:~/comp2b b08a001$ java VariableTest
100
asiaa1:~/comp2b b08a001$

3行目では、変数の宣言を行って、変数を使えるようにしています。 変数名を x とし、ここに格納するデータの種類(型といいます)は整数( int 型)だと言っています。

4行目は代入文です。 変数 x にデータ100を格納します。 代入文は、一般に

variable = expression;

という形をとります。 式 expression の計算結果を変数 variable に格納するということです。 単なる数も式の一種だということに注意してください。

5行目は結果の出力です。 変数 x にはデータ100が格納されていますので、あたかも System.out.println(100); と書いたように振舞います。

なお、変数名はプログラマが決めます。 アルファベットの大文字か小文字で始まり、アルファベットの大文字、小文字、数字、アンダースコア(_)を並べた文字列が使えます。 ただし、次の文字列はJavaで特別な意味を持つキーワードですので、変数名としては使えません。

表 3.2  Javaのキーワード
A abstract,assert.
B boolean,break,byte.
C case,catch,char,class,const,continue.
D default,do,double.
E else,enum,extends.
F final,finally,float,for.
G goto.
I if,implements,import,instanceof,int,interface.
L long.
N native,new.
P package,private,protected,public.
R return.
S short,static,strictfp,super,switch,synchronized.
T this,throw,throws,transient,try.
V void,volatile.
W while

また、 null , true , false も変数名としては使えません。

次のプログラムはいくつかの変数を使う例です。

/*  1*/ class SomeVariables {
/*  2*/     public static void main (String[] args) {
/*  3*/         int temp1, temp2, temp3;
/*  4*/         temp1 = 300;
/*  5*/         temp2 = 200;
/*  6*/         temp3 = 4 * temp1 + 3 * temp2;
/*  7*/         System.out.println(temp3);
/*  8*/         System.out.println(4 * 300 + 3 * 200);
/*  9*/     }
/* 10*/ }
asiaa1:~/comp2b b08a001$ javac SomeVariables.java
asiaa1:~/comp2b b08a001$ java SomeVariables
1800
1800
asiaa1:~/comp2b b08a001$

3行目で、3つの変数 temp1 , temp2 , temp3 を宣言します。 これは、変数の宣言

int temp1;
int temp2;
int temp3;

をまとめたものです。 6行目で、変数 temp3 に式 4× temp1 +3× temp2 の値を代入します。 変数 temp1 の値は300で、 temp2 の値は200ですので、4×300+3×200を計算して、この値1800が変数 temp3 に格納されます。

3.5.2 変数の初期化

前小節では次のようなプログラムを動かしました。

/*  1*/ class VariableTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         int x;
/*  4*/         x = 100;
/*  5*/         System.out.println(x);
/*  6*/     }
/*  7*/ }

変数の宣言とデータの格納は一緒に行うことができます。 この操作を変数の 初期化initialization ) とよび、そのデータをその変数の 初期値initial value ) とよびます。 次のプログラムの3行目で、変数 x を100に初期化しています。

/*  1*/ class VariableTest2 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100; // 初期化
/*  4*/         System.out.println(x);
/*  5*/     }
/*  6*/ }

次のように書きますと、複数の変数が初期化できます。

int x = 100, y = 200;

次のように、変数の初期化と単なる宣言を混ぜることもできます。

int x = 100, y = 200, z;

3.5.3 変数の値の変更

今までの例では、変数に格納されたデータは特に変更されませんでした。 一般的には、変数に格納されたデータは何度も変更されます。

/*  1*/ class VariableTest3 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100;
/*  4*/         x = x + 1; // 1増加
/*  5*/         System.out.println(x);
/*  6*/     }
/*  7*/ }
asiaa1:~/comp2b b08a001$ javac VariableTest3.java
asiaa1:~/comp2b b08a001$ java VariableTest3
101
asiaa1:~/comp2b b08a001$

このプログラムは、いったん変数 x にデータ100を格納した後、それを1増加させるものです。 4行目は、変数 x の値に1をたしたものを変数 x に格納する代入文です。 xx + 1 が等しいと言っているわけではありません。 このイメージは次の図のようになります。

変数の値の変更
図 3.2  変数の値の変更

変数の値を1増加させることは頻繁に行われますので、省略形が用意されています。 x++;x = x + 1; と同じことが行われます。 変数の値を1減少させることについても、 y = y - 1;y--; と省略することができます。

/*  1*/ class VariableTest4 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100, y = 200;
/*  4*/         x++; // 1増加
/*  5*/         y--; // 1減少
/*  6*/         System.out.println(x);
/*  7*/         System.out.println(y);
/*  8*/     }
/*  9*/ }
asiaa1:~/comp2b b08a001$ javac VariableTest4.java
asiaa1:~/comp2b b08a001$ java VariableTest4
101
199
asiaa1:~/comp2b b08a001$

3.5.4 変数の使用例

変数の使用例として、次の問題を考えます。

A子は店に行き、150円のペットボトルを1本と120円の缶ジュースを3本買いました。 A子はいくら支払わなければならないでしょうか。

この問題を解決するには、式 150+3×120 を計算するのが簡単です。 プログラムは次の通りです。

/*  1*/ class SomeDrinks {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println(150 + 3 * 120);
/*  4*/     }
/*  5*/ }
asiaa1:~/comp2b b08a001$ javac SomeDrinks.java
asiaa1:~/comp2b b08a001$ java SomeDrinks
510
asiaa1:~/comp2b b08a001$

変数を使って、合計金額を順番に増加させるというアルゴリズムもあります。 つまり、始めに合計金額を表す変数 total に0を格納し、次に変数 total の値を150増加させ、最後に変数 total の値を 3×120 増加させます。 プログラムは次の通りです。

/*  1*/ class SomeDrinks2 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int total = 0;
/*  4*/         total = total + 150;
/*  5*/         total = total + 3 * 120;
/*  6*/         System.out.println(total);
/*  7*/     }
/*  8*/ }

合計金額だけではなく、ペットボトルと缶ジュースの値段も変数に格納しておくことも考えられます。 変数名は、それぞれ pet , can とします。 プログラムは次の通りです。

/*  1*/ class SomeDrinks3 {
/*  2*/     public static void main (String[] args) {
/*  3*/         int total = 0, pet = 150, can = 120;
/*  4*/         total = total + pet;
/*  5*/         total = total + 3 * can;
/*  6*/         System.out.println(total);
/*  7*/     }
/*  8*/ }

3.6 演習3

次の問題を考えます。

B子はドラッグストアに行き、100円のティッシュを5箱と200円の石けんを2個と300円のタオルを1枚買いました。 B子はいくら支払わなければならないでしょうか。

この問題を解決するアルゴリズムを考え、プログラムを作成してください。 プログラムでは、変数を適切に利用してください。

asiaa1:~/comp2b b08a001$ javac Drugstore.java
asiaa1:~/comp2b b08a001$ java Drugstore
1200
asiaa1:~/comp2b b08a001$

余力のある人は、同じような買い物を自分で考え、支払金額を求めるプログラムを作成してください。 プログラムは、何を買ったかが分かるようにしてください。


3.7 レポート課題

今日の演習3の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(4月25日)を明記してください。


3.8 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2008年4月25日更新
小西 善二郎 <konishi@cis.twcu.ac.jp>
Copyright (C) 2008 Zenjiro Konishi. All rights reserved.