データの出力で使う
System.out.println(
data
);
や
System.out.print(
data
);
の
data
の所では、文字列や変数などを演算子
+
で結ぶことができます。
/* 1*/ class IntToString { // 整数を文字列にする /* 2*/ public static void main (String[] args) { /* 3*/ int x = 100; /* 4*/ System.out.println("x"); /* 5*/ System.out.println(x); /* 6*/ System.out.println("x = " + x); // 連結 /* 7*/ } /* 8*/ }
asiaa1:~/comp2b b08a001$ java IntToString x 100 x = 100 asiaa1:~/comp2b b08a001$
実は、この演算子
+
は文字列の連結です。
一方だけが文字列のときは、他方を文字列に変換して連結するという約束になっています。
整数と整数の足し算も
+
なので、混乱しそうなら、括弧を使ってください。
前回の授業では、反復構造について説明しました。
その中で、繰り返しの回数がはっきりしているときには
for
文を使い、そうでないときには
while
文を使うと言いました。
繰り返しの回数がはっきりしていない例として、レジのような計算を考えます。 つまり、整数を次々と入力してもらい、最後にその合計を出力するというプログラムです。 最後の目印として、0が入力されたら合計を出力して終了することにします。
asiaa1:~/comp3b b08a001$ java InputTotal 整数を入力してください: 100 整数を入力してください: 200 整数を入力してください: 300 整数を入力してください: 0 合計は600です。 asiaa1:~/comp3b b08a001$
次のプログラムは、while文を使った場合です。 最初に0が入力される可能性があるので、10行目と14行目の両方で、入力される値を取り出しています。
/* 1*/ import java.io.*; /* 2*/ /* 3*/ class InputTotal1 { // 入力の合計1 /* 4*/ public static void main (String[] args) throws IOException { /* 5*/ InputStreamReader isr = new InputStreamReader(System.in); /* 6*/ BufferedReader br = new BufferedReader(isr); /* 7*/ int x, total = 0; /* 8*/ System.out.print("整数を入力してください: "); /* 9*/ x = Integer.parseInt(br.readLine()); // 入力 /* 10*/ while (x != 0) { // 0が入力されるまで繰り返す /* 11*/ total += x; /* 12*/ System.out.print("整数を入力してください: "); /* 13*/ x = Integer.parseInt(br.readLine()); // 入力 /* 14*/ } /* 15*/ System.out.println("合計は" + total + "です。"); /* 16*/ } /* 17*/ }
while
文と似たものに、
do
-
while
文があります。
これは、条件式を確認してから文の並びを実行するのではなく、文の並びを実行してから条件式を確認するものです。
do
-while
文
の形式は、次の通りです。
do { statement; ... } while (condition);
これは、
statement; ... while (condition) { statement; ... }
と同じ意味です。
while
文がその中身を一度も実行しないかもしれないのに対して、
do
-
while
文はその中身を必ず一度は実行します。
条件式の値に関わらず、1回以上繰り返す場合は、
do
-
while
文を使います。
次のプログラムは、入力の合計の計算で、
do
-
while
文を使った場合です。
while
文の場合と比べて、入力される値を取り出す部分が、1か所になっています。
ただし、0が入力されても12行目が実行されるので、もし0でない数で終了を表すなら間違うことになります。
/* 1*/ import java.io.*; /* 2*/ /* 3*/ class InputTotal2 { // 入力の合計2 /* 4*/ public static void main (String[] args) throws IOException { /* 5*/ InputStreamReader isr = new InputStreamReader(System.in); /* 6*/ BufferedReader br = new BufferedReader(isr); /* 7*/ int x, total = 0; /* 8*/ do { /* 9*/ System.out.print("整数を入力してください: "); /* 10*/ x = Integer.parseInt(br.readLine()); // 入力 /* 11*/ total += x; /* 12*/ } while (x != 0); // 0が入力されるまで繰り返す /* 13*/ System.out.println("合計は" + total + "です。"); /* 14*/ } /* 15*/ }
break
文
は、繰返しを終了する文です。
具体的には、繰返し文
while
,
do
-
while
,
for
の実行中に
break
文があると、繰返しの途中でも実行が終了し、繰返し文の次に制御が移ります。
次のプログラムは、入力の合計の計算で、
break
文を使った場合です。
do
-
while
文の場合と比べて、もし0でない数で終了を表しても大丈夫です。
なお、
while
文の条件が
true
なのに注意してください。
これは、条件が成り立つことを意味し、無限ループを作るときに使います。
無限ループはプログラムとして間違っていますが、
break
文で終了しているので、本当の無限ループではないのです。
/* 1*/ import java.io.*; /* 2*/ /* 3*/ class InputTotal3 { // 入力の合計3 /* 4*/ public static void main (String[] args) throws IOException { /* 5*/ InputStreamReader isr = new InputStreamReader(System.in); /* 6*/ BufferedReader br = new BufferedReader(isr); /* 7*/ int x, total = 0; /* 8*/ while (true) { // 無限ループ /* 9*/ System.out.print("整数を入力してください: "); /* 10*/ x = Integer.parseInt(br.readLine()); /* 11*/ if (x == 0) { /* 12*/ break; // 途中で繰り返しを終了 /* 13*/ } /* 14*/ total += x; /* 15*/ } /* 16*/ System.out.println("合計は" + total + "です。"); /* 17*/ } /* 18*/ }
繰返しの繰返し、すなわち、繰返し文の中にさらに繰返し文を書くこともできます。 このような制御構造を、 2重ループ ( nested loop )と呼ぶことがあります。 3重ループやそれ以上も考えられます。
一般的に、2重ループではループ制御変数を2つ用意します。 変数が i と j ならば、 i を外側のループ制御変数とし、 j を内側のループ制御変数とします。
次のプログラムは、出力を4回繰り返すことを3回繰り返すものです。 変数 i と j がどのように変化するかを見てください。
/* 1*/ class NestedLoop { // 2重ループ /* 2*/ public static void main (String[] args) { /* 3*/ int i, j; /* 4*/ for (i = 0; i < 3; i++) { // 3回繰り返す /* 5*/ for (j = 0; j < 4; j++) { // 4回繰り返す /* 6*/ System.out.println("i = " + i + ", j = " + j + "."); /* 7*/ } /* 8*/ } /* 9*/ } /* 10*/ }
asiaa1:~/comp3b b08a001$ java NestedLoop i = 0, j = 0. i = 0, j = 1. i = 0, j = 2. i = 0, j = 3. i = 1, j = 0. i = 1, j = 1. i = 1, j = 2. i = 1, j = 3. i = 2, j = 0. i = 2, j = 1. i = 2, j = 2. i = 2, j = 3. asiaa1:~/comp3b b08a001$
反復の使用例として、九九の表を作成します。 九九の表は、2重ループを使うと、うまく作れます。 ループ制御変数 i と j を、1から9まで変化させればよいのです。
/* 1*/ class MultiplicationTable { // 九九の表 /* 2*/ public static void main (String[] args) { /* 3*/ int i, j; /* 4*/ for (i = 1; i <= 9; i++) { // 9回繰り返す /* 5*/ for (j = 1; j <= 9; j++) { // 9回繰り返す /* 6*/ System.out.print(" " + i + "*" + j + "=" + i * j); /* 7*/ } /* 8*/ System.out.println(); // 改行 /* 9*/ } /* 10*/ } /* 11*/ }
asiaa1:~/comp3b b08a001$ java MultiplicationTable 1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9 2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18 3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 asiaa1:~/comp3b b08a001$
反復を使ったアプレットの例として、パターンを描きます。 ここでは、市松模様を取り上げます。 幅300ピクセル、高さ200ピクセルのアプレットに、一辺20ピクセルの正方形を敷き詰めます。
一見、繰返しでは描けないように見えますが、以下のパターン要素を縦横に繰り返し描けばできます。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class Checkers1 extends Applet { // 市松模様1 /* 5*/ public void paint (Graphics g) { /* 6*/ g.setColor(Color.white); /* 7*/ g.fillRect(0, 0, 20, 20); /* 8*/ g.fillRect(20, 20, 20, 20); /* 9*/ g.setColor(Color.black); /* 10*/ g.fillRect(20, 0, 20, 20); /* 11*/ g.fillRect(0, 20, 20, 20); /* 12*/ } /* 13*/ }
まず、このパターン要素を横に描きます。 ループ制御変数を j とし、 j を1増加させるごとに横に40ピクセルずらします。 最後が少しはみ出ますが、アプレットではみ出た描画は単に表示されないだけなので問題ありません。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class Checkers2 extends Applet { // 市松模様2 /* 5*/ public void paint (Graphics g) { /* 6*/ int j; /* 7*/ for (j = 0; j < 8; j++) { // 8回繰り返す /* 8*/ g.setColor(Color.white); /* 9*/ g.fillRect(40 * j, 0, 20, 20); /* 10*/ g.fillRect(40 * j + 20, 20, 20, 20); /* 11*/ g.setColor(Color.black); /* 12*/ g.fillRect(40 * j + 20, 0, 20, 20); /* 13*/ g.fillRect(40 * j, 20, 20, 20); /* 14*/ } /* 15*/ } /* 16*/ }
そして、これをさらに縦に繰り返すと出来上がりです。 ループ変数を i とし、 i を1増加させるごとに縦に40ピクセルずらします。
/* 1*/ import java.applet.*; /* 2*/ import java.awt.*; /* 3*/ /* 4*/ public class Checkers3 extends Applet { // 市松模様3 /* 5*/ public void paint (Graphics g) { /* 6*/ int i, j; /* 7*/ for (i = 0; i < 5; i++) { // 5回繰り返す /* 8*/ for (j = 0; j < 8; j++) { // 8回繰り返す /* 9*/ g.setColor(Color.white); /* 10*/ g.fillRect(40 * j, 40 * i, 20, 20); /* 11*/ g.fillRect(40 * j + 20, 40 * i + 20, 20, 20); /* 12*/ g.setColor(Color.black); /* 13*/ g.fillRect(40 * j + 20, 40 * i, 20, 20); /* 14*/ g.fillRect(40 * j, 40 * i + 20, 20, 20); /* 15*/ } /* 16*/ } /* 17*/ } /* 18*/ }
例を参考にして、2重ループを使って、パターンを描画するアプレットを作成してください。 余力のある人は、パターンを複雑にしてください。
今日の演習8の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(6月11日)を明記してください。