Report#4


制御文と配列を用いてオリジナルのJavaアプリケーションによる初級問題(なるべく短い行数で)を作成し、模範解答例を示せ。併せて、同様な動作を行うC言語のソースコードを示せ。

問題1.if文を使ったプログラム
問題2.switch文を使ったプログラム
問題3.配列を使ったプログラム

問題1

Greeting.javaという、現在の時刻(「時」だけでよい)をキーボードから入力すると、午前中なら「おはようございます」、正午なら「お昼です」、午後なら「こんにちは」、夜なら「こんばんは」、それ以外なら「時刻の範囲を越えています」を表示するプログラムをif文を使って完成させてください。

模範解答例


((解答例1))

 1: import java.io.*;
 2:
 3: public class Rep4_1 {
 4:    public static void main(String[] args) {
 5:       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 6:           try {
 7:                System.out.println("現在の時刻を入力してください(「時」のみでけっこうです)。");
 8:                String line = reader.readLine();
 9:                int n = Integer.parseInt(line);
10:                if (0 <= n && n <= 11) {
11:                    System.out.println("おはようございます\n");
12:                } else if (n == 12) {
13:                    System.out.println("お昼です\n");
14:                } else if (13 <= n && n <=18) {
15:                    System.out.println("こんにちは\n");
16:                } else if (19 <= n && n <= 23) {
17:                    System.out.println("こんばんは\n");
18:                } else {
19:                    System.out.println("時刻の範囲を越えています\n");
20:                }
21:           } catch (IOException e) {
22:                    System.out.println(e);
23:           } catch (NumberFormatException e) {
24:                    System.out.println("数字の形式が正しくありません。\n");
25:           }
26:    }
27: }


実行結果

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
9
おはようございます

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
12
お昼です

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
16
こんにちは

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
21
こんばんは

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
29
時刻の範囲を越えています

[nw0451:~/java/Rep4] j04051% java Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
!
数字の形式が正しくありません



((解答例2))

 1: import java.io.*;
 2: 
 3: public class Rep4_1_2 {
 4:    public static void main(String[] args) {
 5:       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 6:       try {
 7:            System.out.println("現在の時刻を入力してください(「時」のみでけっこうです)。");
 8:            String line = reader.readLine();
 9:            int n = Integer.parseInt(line);
10:            if (n < 0) {
11:                System.out.println("時刻の範囲を越えています\n");
12:            } else if (n <12) {
13:                System.out.println("おはようございます\n");
14:            } else if (n == 12) {
15:                System.out.println("お昼です\n");
16:            } else if (n < 19) {
17:                System.out.println("こんにちは\n");
18:            } else if (n < 24) {
19:                System.out.println("こんばんは\n");
20:            } else {
21:                System.out.println("時刻の範囲を越えています\n");
22:            }
23:       } catch (IOException e) {
24:               System.out.println(e);
25:       } catch (NumberFormatException e) {
26:               System.out.println("数字の形式が正しくありません。\n");
27:       }
28:    }
29: }


実行結果

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
-3
時刻の範囲を越えています

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
8
おはようございます

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
12
お昼です

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
15
こんにちは

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
20
こんばんは

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
30
時刻の範囲を越えています

[nw0451:~/java/Rep4] j04051% java Rep4_1_2
現在の時刻を入力してください(「時」のみでけっこうです)。
#
数字の形式が正しくありません。

 考察

・プログラムについて
 1: import java.io.*;
 java.ioは、ファイル入出力関係のパッケージである。BuffereReaderやreadLineのメソッドを使用するためにimportする。
 5:    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 BufferedReaderは参照型の一つでクラスと呼ばれるものであり、データの読み込みを行うためのクラスである。この一文の意味は、「標準入力のSystem.inをもとに、InputStreamReaderオブジェクトを作り、それをもとに、BufferedReaderオブジェクトを作り、変数readerを、そのBufferedReaderオブジェクトで初期化する」ということになる。
 System.outは、画面へデータを出力するためのものだが、System.inは、キーボードからデータを入力するためのものである。
 つまり、データの読み込みを行うための「もの」を新しく作ったことになる。
 6:    try {  

23:    } catch (IOException e) {
24:             System.out.println(e);
25:    } catch (NumberFormatException e) {
26:             System.out.println("数字の形式が正しくありません。\n");
27:    }
 try…catch文は、例外処理と呼ばれるもので、コードの実行中に問題が起こった場合の処理を指定するものである。tryブロックには、例外の発生を監視する必要があるコードを記述し、catchブロックには、発生した問題に関する情報を格納した例外処理を記述する。tryブロック内のコードを実行しているときに問題が発生した場合、実行を停止し、その種類の例外を処理できるcatchブロックを検索する。
 IOExceptionは、コンパイラによってチェックされる例外である。コンパイル中に例外が生じた場合、その例外をそのまま表示する。
 NumberFormatExceptionは、整数の形式が不正の時の例外である。整数の形式が不正だった場合、"数字の形式が正しくありません"と表示する。
 8:    String line = reader.readLine();
 Stringは、「文字列」を表すクラス。readLineは、文字列を1行分取得するメソッドである。
 reader.readLine()で得た1行分の文字列で、変数lineを初期化する。
 9:    int n = Integer.parseInt(line);
 変数lineは文字列を表すString型なので、if文で比較するためには、変数lineに格納されている文字列を整数に変換しなくてはならない。Integerは整数を表すクラスで、parseIntは整数値を得るメソッドである。
 変数lineに格納されている文字列を整数に変換したものを変数nに代入する。
10:    if (0 <= n && n <= 11) {
11:    System.out.println("おはようございます\n");
12:    } else if (n == 12) {
13:    System.out.println("お昼です\n");
14:    } else if (13 <= n && n <=18) {
15:    System.out.println("こんにちは\n");
16:    } else if (19 <= n && n <= 23) {
17:    System.out.println("こんばんは\n");
18:    } else {
19:    System.out.println("時刻の範囲を越えています\n");
20:    }
 このif文で、時間の範囲を判断し、 表示するあいさつを判断する。
・&&は「かつ」の意。2つ条件式をまとめて1つの条件式を作る演算子である。(nが0以上で11以下なら、おはようございますと表示する)
・==は「等しい」の意。2つの値が等しいかどうかを判断する演算子である。(nが12と等しければ、お昼ですと表示する)
以下略
このようなプログラムは、境界線をチェックするのが大切である。

・C言語でのプログラム (Rep4_1.c)


 1: #include
 2:
 3: int greeting(int y);
 4:
 5: main()
 6: {
 7:    int n;
 8: 
 9:    printf("現在の時刻を入力してください(「時」のみでけっこうです)。\n");
10:    scanf("%d",&n);
11:    greeting(n);
12:    printf("\n");
13: }
14:
15: int greeting(int n)
16: {
17:    if ((0 <= n ) && (n <= 11)) {
18:        printf("おはようございます\n");
19:    } else if (n == 12) {
20:        printf("お昼です\n");
21:    } else if ((13 <= n) && (n <= 18)) {
22:        printf("こんにちは\n");
23:    } else if ((19 <= n) && (n <=23)) {
24:        printf("こんばんは\n");
25:    } else {
26:        printf("時刻の範囲を越えています\n");
27:    } 
28: }


実行結果

[nw0451:~/prog2] j04051% ./Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
8
おはようございます

[nw0451:~/prog2] j04051% ./Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
12
お昼です

[nw0451:~/prog2] j04051% ./Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
16
こんにちは

[nw0451:~/prog2] j04051% ./Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
21
こんばんは

[nw0451:~/prog2] j04051% ./Rep4_1
現在の時刻を入力してください(「時」のみでけっこうです)。
25
時刻の範囲を越えています


・C言語でのプログラムの考察

 C言語のソースでもif文を使って同じような動作をするプログラムを作ることができる。しかし、Cの場合は、javaのNumberFormatExceptionように文字列が数字なのか文字なのかを判断する機能がない。ので、数字ではない文字が入力された場合の処理である、「数字の範囲を越えています」と表示するための判断文が書けなかった。まず最初にchar型で変数を宣言し、文字列をint型にキャストして判断することも考えたが、文字列をint型に変換するとASCII文字コード表の数字になってしまうため、うまくいかなかった。


問題2

プログラムを見て、実行結果の   の空白をうめてください。

((プログラム))

 1: public class Rep4_2 {
 2:      public static void main(String[] args) {
 3:            char ch[] = { '+', '-', '*', '/', '%','&','!' };
 4:            int a,x,y,s;
 5:            float f;
 6:            x = 500;
 7:            y = 200;
 8:            System.out.println("x=500,y=200\n");
 9:            for (a=0; a<7; a++) {
10:                  System.out.println("--------ch["+a +"] = " + ch[a]);
11:                  switch (ch[a]) {
12:                  case '+':
13:                         s = x + y;
14:                         System.out.println("x + y = " + s+"\n");
15:                         break;
16:                  case '-':
17:                         s = x - y
18:                         System.out.println("x - y = " + s+"\n");
19:                         break;
20:                  case '*':
21:                         s = x * y;
22:                         System.out.println("x * y = " + s+"\n");
23:                         break;
24:                  case '/':
25:                         f = x / y;
26:                         System.out.println("x / y = " + f+"\n");
27:                         break;
28:                  case '%':
29:                         f = x % y;
30:                         System.out.println("x % y = " + f+"\n");
31:                         break;
32:                  default:
33:                         System.out.println("?\n");
34:                  }
35:            }
36:      }
37: }


実行結果

[nw0451:~/java/Rep4] j04051% java Rep4_2
x=500,y=200

--------ch[0] = +
x + y = a 

--------ch[1] = -
x - y = b 

--------ch[2] = *
x * y = c 

--------ch[3] = /
x / y = d 

--------ch[4] = %
x % y = e 

--------ch[5] = &
 f 

--------ch[6] = !
 f 

模範解答例

 a. 700
 b. 300
 c. 100000
 d. 2.0
 e. 100.0
 f. ?

 考察

・プログラムについて

 3:    char ch[] = { '+', '-', '*', '/', '%','&','!' };
 chの配列を宣言。'+'、'ー'、'*'、'/'、'%'、'&'、'!'が格納されている。
 4:    int a,x,y,s;
 5:    float f;
 int型で、a、x、y、sを宣言。ここでのaは、for文の繰り返す回数を定義するため。xとyは、計算のための数字を代入した。sは、計算した後の答えを代入するため。
 fは、小数がでる計算を代入するため。
 9:    for (a=0; a<7; a++) {
 chの配列に格納されているデータが7つなので、7回繰り返すようにする。
10:    System.out.println("--------ch["+a +"] = " + ch[a]);
 配列の何番目なのか、そこには何が格納されているのかを表示する。
11:    switch (ch[a]) {
 a番目の配列に格納されているものをもとに、多方向分岐の処理をする。
12:    case '+':
13:    s = x + y;
14:    System.out.println("x + y = " + s+"\n");
15:    break;
 ch[]の値が、'+'だった場合の処理。xとyを加算し、表示する。
16:    case '-':
17:    s = x - y
18:    System.out.println("x - y = " + s+"\n");
19:    break;
 ch[]の値が、'ー'だった場合の処理。xからyを減算し、表示する。
20:    case '*':
21:    s = x * y;
22:    System.out.println("x * y = " + s+"\n");
23:    break;
 ch[]の値が、'*'だった場合の処理。xとyを乗算し、表示する。
24:    case '/':
25:    f = x / y;
26:    System.out.println("x / y = " + f+"\n");
27:    break;
 ch[]の値が、'/'だった場合の処理。xをyで除算し、表示する。
28:    case '%':
29:    f = x % y;
30:    System.out.println("x % y = " + f+"\n");
31:    break;
 ch[]の値が、'%'だった場合の処理。xをyで除算し、その余りを表示する。
32:    default:
33:    System.out.println("?\n");
 ch[]の値が、上の条件と合わなかった場合の処理。?を表示する。

・解答例について

 a.700
 x=500、y=200なので、500+200で答えは700になる。
 b.300
 x=500、y=200なので、500-200で答えは300になる。
 c.100000
 x=500、y=200なので、500*200で答えは100000になる。
 d.2.0
 x=500、y=200なので、500/200で答えは2.0になる。
 e.100.0
 x=500、y=200なので、500%200で答えは100.0になる。
 f.?
 &と!は、case文で定義されていないので、?となる。

・C言語でのプログラム (Rep4_2.c)


 1: #include 
 2: 
 3: main()
 4: {
 5:  char ch[] = { '+', '-', '*', '/', '%', '&', '!' };
 6:  int a,x,y,s;
 7:  float f;
 8:  x = 500;
 9:  y = 200;
10:  printf("x=500,y=200\n");
11:  for (a=0;a<7;a++) {
12:   printf("-------------ch[a] = %c\n",ch[a]);
13:   switch (ch[a]) {
14:     case '+' :
15:     s = x + y;
16:     printf("x + y = %d\n",s);
17:     break;
18:     case '-' :
19:     s = x - y;
20:     printf("x - y = %d\n",s);
21:     break;
22:     case '*':
23:     s = x * y;
24:     printf("x * y = %d\n",s);
25:     break;
26:     case '/' :
27:     f = x / y;
28:     printf("x / y = %f\n",f);
29:     break;
30:     case '%' :
31:     f = x % y;
32:     printf("x %% y = %f\n",f);
33:     break;
34:     default:
35:     printf("?\n");
36:   }
37:  }
38: }


実行結果

[nw0451:~/prog2] j04051% ./Rep4_2
x=500,y=200
-------------ch[a] = +
x + y = 700
-------------ch[a] = -
x - y = 300
-------------ch[a] = *
x * y = 100000
-------------ch[a] = /
x / y = 2.0
-------------ch[a] = %
x % y = 100.0
-------------ch[a] = &
?
-------------ch[a] = !
?


・C言語でのプログラムの考察

 C言語のswitch文とjavaのswitch文は、大きな違いはない。表示の部分のソースの形式を変えるぐらいの変更で、簡単に作れた。


問題3

Rep4_3のプログラムは、配列dataの要素を小さい順に並べ替えるものです。   の部分に適切な文字を入れて完成させてください。

((プログラム))

 1: public class Rep4_3 {
 2:     public static void main(String[] args) {
 3:        int data[] = { 31, 41, 59, 26, 53, 64, 97, 93, 23, 84, 19 };
 4:        System.out.println("並べ替える前");
 5:        for (int i = 0; i < data.length; i++) {
 6:              System.out.print(data[i] + " ");
 7:        }
 8:        System.out.println("");
 9:        for (int i = 0; i <  a  ; i++) {
10:              for (int j = i + 1; j <  b  ; j++) {
11:                     if (data[i] > data[j]) {

                            // 交換
12:                          c  =  d ;
13:  e  =  f ;
14:  g  =  h ; 15: } 16: } 17: } 18: System.out.println("並べ替えた後"); 19: for (int i = 0; i < data.length; i++) { 20: System.out.print(data[i] + " "); 21: } 22: System.out.println(""); 23: } 24: }

実行結果

[nw0451:~/java/Rep4] j04051% java Rep4_3
並べ替える前
31 41 59 26 53 64 97 93 23 84 19 

並べ替えた後
19 23 26 31 41 53 59 64 84 93 97 


模範解答例

 a. data.length - 1
 b. data.length
 c. int a
 d. data[i]
 e. data[i]
 f. data[j]
 g. data[j]
 h. a

 考察

・プログラムについて

 3:    int data[] = { 31, 41, 59, 26, 53, 64, 97, 93, 23, 84, 19 };
 int型の配列dataを宣言。配列dataには初期値として、31,41,59,26,53,64,97,93,23,84,19が代入されている。
 5:    for (int i = 0; i < data.length; i++) {
            System.out.print(data[i] + " ");
 int型のiを宣言。iの初期値を0とし、iがdata.lengthより小さい間、処理を続ける。data.lengthとは、配列の長さで、配列の要素の個数のことを指す。この配列dataには、11個の要素があるのでfor(int i = 0; i < 11; i++)という意味になる。
 System.out.print(data[i] + " ")は、配列dataの要素を表示している。ここでは、改行をしなくてもいいのでprintを使い、要素との間にスペースを表示するため+ " "としている。
 8:    System.out.println("");
 配列を表示した際に、printを使ったので改行がされておらず、続けて表示されてしまうため、println("")で改行するようにした。
 9:    for (int i = 0; i <  a  ; i++) {  ( a = data.length - 1 )
 このソートでは、隣同士で大小をくらべるバブルソートを利用している。ので、要素の数から1を引いた回数しらべる。
10:    for (int j = i + 1; j <  b  ; j++) {  ( b = data.length )
 隣同士を比べるので、iに1を足して隣の要素をjとし、比べあう。
11:    if (data[i] > data[j]) {
 配列data[i]と配列data[j]を比べ、data[i]の方が大きければ真、そうでなければ偽となる。
12:     c  =  d ;  ( c = int a , d = data[i] )
 上のif文の結果が真ならば、次の処理をする。int型のaを宣言し、data[i]をaに代入する。ここでは、aを宣言しているが、並べ替えるために一時保管しておくためなので、特に決まりはない。
13:     e  =  f ;  ( e = data[i] , f = data[j] )
 data[j]の値をdata[i]に代入する。
14:     g  =  h ;  ( g = data[j] , h = a )
 data[j]にaを代入する。これで、隣同士の大小が比較され、入れ替えられた。
19:    for (int i = 0; i < data.length; i++) {
            20:    System.out.print(data[i] + " ");
 int型のiを宣言。iの初期値を0とし、iがdata.lengthより小さい間、data[i]を表示する。表示した要素との間にスペースを入れ見やすくする。これで、並べ替えた後の配列の要素を表示する。
22:    System.out.println("");
 最後に改行する。

・C言語でのプログラム (Rep4_3.c)


 1: #include 
 2: void sort(int x[],int n);
 3: void print(int x[],int n);
 4: #define MAX 100
 5: int no[MAX];          /*作業用配列*/
 6: 
 7: main()
 8: {
 9:  int x[MAX] = { 31, 41, 59, 26, 53, 64, 97, 93, 23, 84, 19 };    /*ソートするデータ*/
10:  int n = 11;                                                   /*ソートするデータの数*/
11:  printf("並び替える前\n");
12:  int a;
13:  for (a = 0; a < 11; a++) {                /*ソート前のデータを表示*/
14:   printf("%d ",x[a]);
15:  }
16:  printf("\n\n");
17:  sort(x,n);
18:  printf("並び替えた後\n");
19:  print(x,n);
20:  printf("\n");
21: }
22: 
     /*ソートを行う*/
23: void sort(int x[],int n)
24: {
25:  int i,j;
26:  for (i = 0; i < MAX; i++)
27:     no[i] = 0;                    /*作業用配列の初期化*/
28:  for (i = 0; i < n; i++)
29:     no[x[i]]++;                   /*x[i]の値のno[]の要素の値をインクリメント*/
30:  j=0;                               /*x[]の添字として使用*/
31:  for (i = 0; i < MAX; i++)
32:     if (no[i])                    /*0でなければ書き戻す*/
33:     x[j++] = i;
34: }
35: 
     /*ソート後のデータを表示*/
36: void print(int x[],int n)
37: {
38:  int i;
39:  for (i = 0; i < n; i++)
40:     printf("%d ",x[i]);
41: }


実行結果

[nw0451:~/prog2] j04051% ./Rep4_3
並び替える前
31 41 59 26 53 64 97 93 23 84 19 

並び替えた後
19 23 26 31 41 53 59 64 84 93 97 


・C言語でのプログラムの考察

 C言語でのソートはプログラミングIのレポートでやったことがあるため、比較的簡単だった。javaに比べて、Cで書くとちょっと複雑に感じる。

感想・反省

 今回のレポートは、締め切りに間に合わなかった。それが残念だ。
 しかし、今までのレポートの中では1番がんばったと思う。レポートをhtmlで書くことにも、ちょっとずつだが、慣れてきた。次は、もうちょっと凝ったレポートにしてみようと思う。
 今回のレポートでビックリしたことは、C言語を忘れていたこと!ソースを書くにつれて思い出したが、最初の時は、忘れてしまって教科書を見ながらだった。あんなにがんばったのに…忘れてるなんて…
 今回思ったことは、授業が終わったとしても勉強は続けていないと簡単に忘れてしまうって事。日々勉強しないと。
今回の格言『1日1ソース!』

参考文献

 独習Java 第2版           ジョセフ・オニール 著
 Jave入門               河西朝雄 著
 Java言語プログラミングレッスン上   結城浩 著
 プログラミング言語C         カーニハン・リッチー 著