| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|

型の変換

加減乗除を紹介した時のプログラム
public class Calc1 {
    public static void main(String args[]) {
	System.out.print("除算の結果は");
	System.out.print(7/3);
	System.out.println("です.");
	
    }
}
この結果は"除算の結果は2です."と表示され,小数点以下も含めて計算する 方法として以下のプログラムを紹介し"演算の結果は23.5です."という結果を 得た.
 public class Var2 {
   public static void main(String[] args) {
      double x = 15;
      double y = 32;
      System.out.print("演算の結果は");
      System.out.print((x+y)/2);
      System.out.println("です.");
   }
}
ところで,課題中の以下の解答を見ると,
public class Enn {
    public static void main(String args[]) {
        System.out.print("半径が4cmの円の面積は");
        System.out.print(4*4*3.14);
        System.out.println("です.");
    }
}
計算する式は"4*4*3.14"となっているだけで,特に実数を扱うdouble型の宣言 を行っていない.実行結果は
[onisi@m449 ~/Java] java Enn
半径が4cmの円の面積は50.24です.
であり実数として扱われている.最初のプログラムとこのプログラムで 数の扱い("整数"と"実数")に違いが生じたのはどうしてだろうか?

Java言語では,必要な場合型の拡張が(より大きい範囲を扱えるように)自動的 に行われる.この二つの例では以下のように扱われて,結果に違いが生じる. int 型しか現れなかった"7/3" では,型の拡張を行わなくても計算を実行でき るので拡張されない."4*4*3.14" ではもっとも扱う範囲の大きい"double"型 にあわせて計算が行われ,小数点以下も含む結果が得られる.

プログラム7/34*4*3.14
[int]/[int][int]*[int]*[double]
拡張[int]/[int][double]*[double]*[double]
結果[int][double]

"7/3"を実数で扱うように指定するには,"7/3.0"とでもすればよい.

もう一つの課題でも型は違うが同じようなことが行われている.

public class Calc4 {
    public static void main(String args[]) {
        System.out.println("加算の結果は"+3+2+"です.");
    }
}
と言うプログラムの場合,実行結果は"加算の結果は32です." になってしま う.前回加算記号"+"を説明したが実は,String型('"' で囲まれた文字列を表 す型)の"+"演算は二つのStringをつないだString になる(連結される)

プログラム"前の文字列"+"続きの文字列"
結果"前の文字列続きの文字列"

問題のプログラムの場合,

プログラム"加算の結果は" +3+2+"です."
[String] +[int]+[int]+[String]
変換[String] +[String]+[String]+[String]

のように変換されてしまっている.そこで,

public class Calc4 {
    public static void main(String args[]) {
        System.out.println("加算の結果は"+(3+2)+"です.");
    }
}
のように"(",")"を使って int型での演算を優先的に行うように指定すると,

プログラム"加算の結果は" +(3+2)+"です."
[String] +([int]+[int])+[String]
演算結果"加算の結果は" +5+"です."
[String] +[int]+[String]
変換[String] +[String]+[String]
結果[String]
加算の結果は5です.

のようにして演算・型の変換が行われる.

制御構造

条件判断-if-

「もしも....ならば」

いま仮に「朝,天気予報を見て,降水確率が 50% 以上なら傘をもっていく」 としよう.この行動パターンを整理して書くと,
  もしも
        降水確率が 50% 以上である
  ならば,
        傘をもっていく
となる.このうち,「降水確率が 50% 以上である」の部分を条件(部)と言い, 実際に「降水確率が 50% 以上になる」ことを条件を満たすと言う.また, 「傘をもっていく」の部分を実行部と言う.このような条件による実行処理の 分岐を Java 言語で表現するには,if 文を用いて,以下のように記述する (但し,これはプログラムの一部にしか過ぎないので,このままコンパイルす ればエラーになる).
  if (p >= 50) {
     System.out.println("傘をもっていく");
  }  
  
括弧 ( ) の中に条件が書かれており,中括弧 { } の中に実行部(条件が満たされたときの処理)が書かれている(処理を複数書くことも可能).これを一般的に記述すると,
  if ( 条件 ) {
     実行部(条件が満たされたときの処理)
  }  
  
となる.

条件

上記の条件の中の >= という符合は 以上 を表し,上記の条件は「変数 p が 50 以上である」ことを意味する.>= は 2つの数値を比較し,左 辺が右辺以上ならば true(真)を,それ以外なら false(偽)のどちらかの 値をとる.このように式の値が true か false のどちらかをとるものを boolean 型(論理型)と呼ぶ.代表的な boolean 型の演算子を下の表に挙げ る.

演算子 意味
p == 50 p が 50 に等しいなら true,それ以外なら false
p != 50 p が 50 に等しくないなら true,それ以外なら false
p >= 50 p が 50 以上なら true,それ以外なら false
p <= 50 p が 50 以下なら true,それ以外なら false
p > 50 p が 50 よりも大きいなら true,それ以外なら false
p < 50 p が 50 よりも小さいなら true,それ以外なら false

「もしも...ならば...さもなくば」

今度は,
  もしも
        降水確率が 50% 以上である
  ならば,
        傘をもっていく
  さもなくば
        傘をもっていかない
という例を考えてみよう.このような二者択一を Java 言語で表現するには, if … else 文を用いて,以下のように記述する(但し,これはプログラムの 断片にしか過ぎないので,このままコンパイルすればエラーになる).
  if (p >= 50) {
     System.out.println("傘をもっていく");
  }
  else {
     System.out.println("傘をもっていかない");
  }
括弧 ( ) の中に条件が書かれており,最初の中括弧 { } の中に条件が満たされたときの処理が,else のあとの中括弧 { } の中に条件が満たされなかったときの処理が書いてある.これを一般的に記述すると,
  if ( 条件 ) {
     条件が満たされたときの処理A
  }
  else {
     条件が満たされなかったときの処理B
  }
となる.以上をまとめて,キーボードから降水確率を入力すると,親切なアド バイスをしてくれるプログラムが以下のように書ける.
public class Kasa1 {
    public static void main(String[] args) {

	//int型の変数 n に降水確率を尋ねる
	int n = KeyboardInput.askInt("降水確率を入力してください。");
	
	System.out.println("降水確率は" + n + "%です。");
	if (n >= 50) {
	    System.out.println("傘を忘れずにね。");
	} else {
	    System.out.println("傘はいりません。");
	}
	System.out.println("いってらっしゃい。");
    }
}
[降水確率30%で傘を持っていくように勧めるにはどこを修正すればよいか?]

if 文の連鎖

上の"Kasa1"を実行して,わざと意地悪をしてみる.
降水確率を入力してください。200
降水確率は200%です。
傘を忘れずにね。
いってらっしゃい。
と言うことになる.確率の最大値が"100%"であると言うことはお構いなしである. int型で扱える範囲の整数を入力する限りこうなる.これは,プログラム中で"50% より大きいか"という条件しかないのであるからコンピュータにとっては当然で, プログラム中に記述されていることしか判断してくれない.

このようにコンピュータにとっては,ただしいが結果を利用する立場からすると 誤ったプログラムと言うものも存在する.これは,問題の詳細化を誤った(この 場合は省いた)からであり,詳細化の段階から検討し直す必要がある.つまり,

降水確率が100%より大きいならば,
「降水確率は降水確率は 100 %以下ですよ.」
100%以下で50%以上であるならば,
「傘を忘れずにね.」
50%未満ならば,
「傘はいりません.」
と言うことであり,この場合確率は 100%以下であるという条件をプログラム 中に追加してやればよい.条件を追加するためには,一つの if 文の中の else の続きに別の if 文を書くことで,if 文を連鎖的に用いることが可能であ ることを利用する.つまり

public class Kasa2 {
    public static void main(String[] args) {

	//int型の変数 n に降水確率を尋ねる
	int n = KeyboardInput.askInt("降水確率を入力してください。");
	
	if (n > 100) {
	    System.out.println("降水確率は 0 〜 100 の間ですよ。");
	} else if (n >= 50) {
	    System.out.println("傘を忘れずにね。");
	} else {
	    System.out.println("傘はいりません。");
	}
	System.out.println("いってらっしゃい。");
    }
}
と言うことになる.ここで出てきた条件判断を一般化すると,
  if ( 条件1 ) {
     条件1が満たされたときの処理A
  }
  else if ( 条件2 ) {
     条件1は満たされず,
     条件2が満たされたときの処理B
  }
  else {
     条件1は満たされず,
     条件2も満たされないときの処理C

  }
となる.この例の場合は,条件が"条件1""条件2"の二つの場合であるが, 三つ以上の条件が必要な場合も,
  }
  else if ( 条件n ) {
     ここまでの条件は満たされず,
     条件nが満たされたときの処理
  }
  else {
を追加すればよい.

「または」や「かつ」を表現するには

int 型が扱える整数の範囲は,前回の授業でも示したとおり, -2147483648以上から2147483647までである(符号付き32ビット) つまりマイナスの値も降水確率として入力することができる. そこでマイナスの値が入力されても対応できるように,
降水確率が0%より小さいならば,
「降水確率は降水確率は 0 %以上ですよ.」
降水確率が100%より大きいならば,
「降水確率は降水確率は 100 以下ですよ.」
100%以下で50%以上であるならば,
「傘を忘れずにね.」
50%未満ならば,
「傘はいりません.」
のように考えて条件を四つ用意してもよいが,
降水確率が0%より小さいならば,
「降水確率は降水確率は 0 %以上ですよ.」
降水確率が100%より大きいならば,
「降水確率は降水確率は 100 以下ですよ.」
はまとめて,
降水確率が"0%より小さい"または"100%より大きい"ならば,
「降水確率は降水確率は0〜 100%の間ですよ.」
100%以下で50%以上であるならば,
「傘を忘れずにね.」
50%未満ならば,
「傘はいりません.」
とした方がわかりやすい.ここで出てくるようないわゆる論理和の「または」 や論理積の「かつ」を,if 文ないし if … else 文の中の条件で表現する ことも可能である.「または」を表現するには || という演算子を用いて,下 記のように表現する.これは,条件 1 または 条件 2 のどちらかが満たされ れば処理 A を行い,どちらも満たされなければ処理 B を行うことを意味して いる.
  if ( 条件1 || 条件2 ) {
     条件が満たされたときの処理A
  }
  else {
     条件が満たされなかったときの処理B
  }
  
これを利用すると,
public class Kasa3 {
    public static void main(String[] args) {

	//int型の変数 n に降水確率を尋ねる
	int n = KeyboardInput.askInt("降水確率を入力してください。");
	
	if (n < 0 || n > 100) {
	    System.out.println("降水確率は 0 〜 100 の間ですよ。");
	} else if (n >= 50) {
	    System.out.println("傘を忘れずにね。");
	} else {
	    System.out.println("傘はいりません。");
	}
	System.out.println("いってらっしゃい。");
    }
}
となり,確率の前提も満足したプログラムが完成する.上のプログラムの中で 利用した
  if ( 条件1 || 条件2) {
     処理A
  }
  else {
     処理B
  }
と言う処理は,
条件1が成り立つ
→処理A
条件2が成り立つ
→処理A
条件1も条件2も成り立たない
→処理B
と言う意味であるから,当然
  if ( 条件1) {
     処理A
  }
  else if ( 条件2 ) {
     処理A
  }
  else {
     処理B

  }
のようにもかけるが,おなじ"処理A"を二回記述する必要が出てくる.

次に「かつ」を表現するには && という演算子を用いて,下記のように表現す る.これは,条件 1 と 条件 2 の両方が(同時に)満たされれば処理 A を行 い,それ以外には処理 B を行うことを意味している.

  if ( 条件1 && 条件2 ) {
     条件1,2が満たされたときの処理A
  }
  else {
     条件が満たされなかったときの処理B
  }
  
これを&&演算を使わずに書くには,
  if ( 条件1 ) {
      if ( 条件2 ) {
          条件1,2が満たされたときの処理A
      } else {
          条件1,2が満たされなかったときの処理B
      }
  }
  else {
     条件1,2が満たされなかったときの処理B
  }
  
のようにすればよいが,同じ"処理B"を二回記述する必要があるし,読みづらい.

条件繰り返し-while()-

条件が成り立つ場合にある処理を繰り返して行う制御構造に while 文 がある. while 文 の一般的な書式は以下の通りである.
     while (条件) {
        繰り返す処理
     }
  
while 文ではまず,「条件」が評価される.条件は論理式(boolean 型の 式.true か false かどちらかを値としてとる式)で,その条件の値が true になっている限り,「繰り返す処理」が実行される.従って,「繰り返 す処理」を実行する前に必ず「条件」を評価することになる. まずは次のプログラムを眺めてみよう.
public class Count {
   public static void main(String[] args) {
      System.out.println(0);
      System.out.println(1);
      System.out.println(2);
   }
}
上のプログラムは,0,1,2 の 3 個の数字を順次表示するだけのプログラム である.3 個の数字を表示するだけなら何ら問題はないが,100 個だとか 1000 個だとかの数字を表示するプログラムを書くのは抵抗があるだろう.こ のように,繰り返し回数がわかっている場合に,ある処理(計算)を繰り返し 行う場合には,下のプログラムのように, while文を用いてプログラムを書く ことができる.
public class Count4 {
   public static void main(String[] args) {
      int i = 0;
      while (i < 3) {
         System.out.println(i);
         i=i+1;
      }
   }
}
上のプログラムで,0,1,2 の 3 つの数字を順次表示する部分は,
      while (i < 3) {
         System.out.println(i);
         i=i+1;
      }

である. while 文は,中括弧 { } で括られた部分の処理を,「条件を満たす限 り」繰り返し行う.while のすぐあとの括弧 ( ) で括られた部分は,繰り返し を引き続き行うか判断する条件である.

下記に while 文の例をいくつか列挙する.
  int i = 0;
  while (i < 3) {
     System.out.println("Hello Java World!");   //    ←同じ表示を3回繰り返す
     i = i + 1; 
  }
  
  int j =1 ;
  int sum=0 ;
  while (j < n + 1) {
     sum = sum + j;         //  ←1〜nまでの和
     j = j + 1;
  }
  
次のプログラムでは,"?"に続くキーボードからの入力をそのまま画面に出力 する(鸚鵡返し)事が実現できます.
public class Copy1 {
    public static void main(String[] args) {
	System.out.println("なにも入力しなければ終了します.");
	
	String line = KeyboardInput.askString("?");
	while (!line.equals("")) {
	    System.out.println(line);
	    line = KeyboardInput.askString("?");
	}
    }
}
上のプログラムでは,"KeyboardInput.askString"が2回出てきましたが,次 のように書くと一回ですみます.
 public class Copy2 {
    public static void main(String[] args) {
	String line;
	while ( !(line = KeyboardInput.askString("")).equals("")) {
	    System.out.println(line);
	}
    }
}
条件の部分が複雑になっていますが,一番中から解釈します.
KeyboardInput.askStging("")
Stringを入力してもらうメソッドを呼び出す.
この式の値は,入力された文字列1行文である.
line = KeyboardInput.askStging("")
その文字列を変数 line に代入する
この式の値は,代入した文字列と同じ値になる
(line = KeyboardInput.askStging("")).equals("")
その値を ""(空文字) と比較する.
public class CopyLower {
    public static void main(String[] args) {
	String line;
	while ( !(line = KeyboardInput.askString("")).equals("")) {
	    System.out.println(line.toLowerCase());
	}
    }
}
上のプログラムでは,入力した文字中に登場する大文字をすべて小文字に変換 します.
line.toLowerCase()
の部分がポイントです.String型の変数には".toLowerCase()"をつけることに より,「文字列中の大文字をすべて小文字に変換した新しい文字列を 作る」事ができます[String型(Java.lang.Stringクラス)のメソッド].同様に 大文字にするには,".toUpperCase()"をつけます.

ここでは,lineの文字を置き換えた新しいStringが作られ,直接 "System.out.println()"に渡されています.つまりline の中身は (次に入力されるまで)変わりません.

do〜while()

while 文と似た動作をする構文に,do-while 文がある.while 文では繰り返 す処理を始める前に条件を調べるのに対して,do-while 文では繰り返す処 理を1回行ってから条件を調べる.従って,do-while 文では繰り返す処理 を必ず1回は行うことになる.do-while 文の構造は以下の通り.
     do {
        繰り返す処理
     } while (条件);
  
最低一回は,繰り返す処理を行うことから while 文を使って次のようにもかける.
     繰り返す処理
     while (条件) {
        繰り返す処理
     };
  

線の描画

先週は,文字を描画するメソッド"drawString"を説明したが,線を描画するに は"drawLine"メソッドを利用する.その他のメソッドの一部も追々紹介します が,メソッドの一 覧も参考にしてください.
import java.applet.Applet;
import java.awt.Graphics;
/*
<applet code="Lines" width=150 height=150></applet>
*/

public class Lines extends Applet {
	public void paint(Graphics g){
		g.drawLine(10, 20, 90, 20);
		g.drawLine(10, 80, 90, 80);
		g.drawLine(20, 10, 20, 90);
		g.drawLine(80, 10, 80, 90);
	}
}

課題

1-3が必須の課題です,余裕があれば4も挑戦してみてください.
  1. 現在の時刻を入力すると(何時だけでよい)
    午前中[0時から11時]
    おはようございます
    正午[12時]
    お昼です
    午後[13時から18時]
    こんにちは
    夜[19時から23時]
    こんばんは
    それ以外
    時刻の範囲を超えています
    とそれぞれ表示するプログラムを書きなさい.
    [複数のif文と条件範囲の組合せ]

  2. 1から100までの整数のうち3の倍数の和(=1683)を求めるプログラムを書きなさい.
  3. 数列 A1=1,Ak=2*Ak-1+3について
    (while文を用いること)

  4. [応用]アプレットに線を引いてイニシャルを書くプログラムを書きなさい.

| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|