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

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

目次
9.1 データ型
9.1.1 データ型とは
9.1.2 整数と浮動小数点数
9.1.3 真理値とブール式
9.1.4 文字
9.2 メソッドの応用
9.2.1 変数のスコープ
9.2.2 配列の引数
9.3 演習9
9.4 レポート課題
9.5 参考文献
索引
ASCII   Unicode   基本データ型   クラス変数   参照データ型   真理値   スコープ   データ型   バイト   ビット   ブール式   浮動小数点数   文字符号   論理型  

9.1 データ型

9.1.1 データ型とは

データ型data type ) とは、データの種類のことです。 これまでに、整数と配列の2種類のデータを扱ってきました。 Javaには、この他のデータ型も用意されています。

Javaのデータ型は、まず、基本データ型と参照データ型の2つに大きく分類されます。 基本データ型primitive data type ) には、整数型、浮動小数点数型、論理型、および文字型があります。 参照データ型reference data type ) には、クラス型と配列型があります。 (クラス型については次回説明します。)

以下は、基本データ型の詳細です。

表 9.1  Javaの基本データ型
種類 型名 ビット 説明
整数型 byte 8 -27(-128)〜27- 1(127)
整数型 short 16 -215(-32768)〜215- 1(32767)
整数型 int 32 -231〜231- 1(9桁程度)
整数型 long 64 -263〜263- 1(18桁程度)
浮動小数点数型 float 32 指数+38〜-45, 有効桁数7桁程度
浮動小数点数型 double 64 指数+308〜-324, 有効桁数14桁程度
論理型 boolean - trueまたはfalse
文字型 char 16 \u0000(0)〜\uFFFF(65535)

コンピュータのデータの単位は ビットbit ) であることを思い出してください。 ただし、これは理論上の話です。 現実のコンピュータ・システムは、 バイトbyte ) を単位としています。 1バイトは8ビットです。 基本データ型が8ビット単位であるのは、ここに理由があります。

9.1.2 整数と浮動小数点数

整数を扱う場合、普通は int 型を用います。 ただし、 int 型は9桁程度が限界であり、これを超えると意味のない計算をしてしまいます。 int 型の範囲を超えるような大きい数を扱うときに、 long 型を用います。

浮動小数点数floating point number ) とは、小数点をずらすことによって、非常に大きな数や非常に小さな数も表現できるようにした小数のことです。 浮動小数点数を扱う場合、普通は double 型を用います。 限られたビット数で表現する以上、小数点をずらす桁数には限度がありますし、小数の精度にも限界があります。

9.1.3 真理値とブール式

論理型logical type ) とは、真理値を表すデータ型です。 ここで 真理値truth value ) とは、真を表す記号 true と偽を表す記号 false のことだと思ってください。 Javaでは、型名 boolean で論理型を表します。 値が論理型である式を、 ブール式Boolean expression ) とよびます。 これまで「条件が成り立つ」とか「条件が成り立たない」と言ってきたことは、正確には、ブール式の値が true や false になることです。

9.1.4 文字

Javaは、文字( char 型)を1バイトではなく2バイトで表現します。 これは、英数字だけではなく、漢字なども文字として扱おうという設計です。 なお、ちょうど1バイトで表現されるデータ型として、バイト( byte )が用意されています。

文字は、内部では整数として処理されます。 この、文字から整数への対応を 文字符号character code ) とよびます。 Javaの採用している文字符号は、 Unicode とよばれる体系です。 Unicodeは ASCII という体系の拡張になっています。 主な文字のASCII符号は次の通りです。

表 9.2  主な文字のASCII符号
制御文字 水平タブ 改行 復帰 スペース
表示 '\t' '\n' '\r' ' '
符号 9 10 13 32
文字 ! " # $ % & ' ( ) * + , - . /
符号 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
文字 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
符号 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
文字 @ A B C D E F G H I J K L M N O
符号 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
文字 P Q R S T U V W X Y Z [ \ ] ^ _
符号 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
文字 ` a b c d e f g h i j k l m n o
符号 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
文字 p q r s t u v w x y z { | } ~
符号 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

プログラムの中で文字を表す場合、その文字をシングルクオート( ' )で囲みます。 ただし、シングルクオート自身、およびダブルクオート( " )、バックスラッシュ( \ )については、それぞれ '\'' , '\"' , '\\' とします。


9.2 メソッドの応用

9.2.1 変数のスコープ

変数は、宣言すれば使えます。 しかし、どこでも使えるわけではありません。 変数が使えるのは、ある一定の範囲内です。 変数の使える範囲を、変数の スコープscope )とよびます。

前回、メソッド定義の中で変数を宣言しました。 メソッド定義の中で宣言した変数は、そのメソッド定義の中でしか使えません。 呼び出し側は、 main というメソッドの定義と見なせます。 したがって、呼び出し側の中で宣言した変数も、呼び出し側の中でしか使えません。

次の例では、メソッド main で変数 x , メソッド test で変数 y を宣言しています。 メソッド main では、 mainx は使えますが、 testy は使えません。 メソッド test では、 testy は使えますが、 mainx は使えません。

/*  1*/ class VariableScope1 { // 変数のスコープ1
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100; // xを宣言
/*  4*/         test();
/*  5*/         System.out.println("main x = " + x);
/*  6*/         // testのyは使えない
/*  7*/     }
/*  8*/     static void test () {
/*  9*/         int y = 200; // yを宣言
/* 10*/         System.out.println("test y = " + y);
/* 11*/         // mainのxは使えない
/* 12*/     }
/* 13*/ }
asiaa1:~/comp2b b08a001$ java VariableScope1
test y = 200
main x = 100
asiaa1:~/comp2b b08a001$

では、呼び出し側とメソッド定義の間でデータを交換するには、どうしたらよいでしょう。 正解は、引数と返り値を使う、です。 呼び出し側からメソッド定義にデータを伝えるには、引数を使います。 メソッド定義から呼び出し側にデータを伝えるには、返り値を使います。

次の例では、メソッド mainx の値をメソッド test に伝えるために、引数を使って、その値を x2 に格納しています。 また、メソッド testy の値をメソッド main に伝えるために、返り値を使って、その値を y2 に格納しています。

/*  1*/ class VariableScope2 { // 変数のスコープ2
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100, y2;
/*  4*/         y2 = test(x); // testのyをy2に格納
/*  5*/         System.out.println("test y = " + y2);
/*  6*/     }
/*  7*/     static int test (int x2) { // mainのxをx2に格納
/*  8*/         int y = 200;
/*  9*/         System.out.println("main x = " + x2);
/* 10*/         return y;
/* 11*/     }
/* 12*/ }
asiaa1:~/comp2b b08a001$ java VariableScope2
main x = 100
test y = 200
asiaa1:~/comp2b b08a001$

さて、呼び出し側とメソッド定義で同じ名前の変数を宣言しても、それらは別の変数と見なされます。

次の例では、メソッド main とメソッド test の両方で、変数 x を宣言しています。 メソッド mainx に100を格納し、メソッド testx の値を200に変更しているように見えます。 しかし、 mainx の値は100のままです。 メソッド test では、 mainx でなく、 testx に200を格納したのです。

/*  1*/ class VariableScope3 { // 変数のスコープ3
/*  2*/     public static void main (String[] args) {
/*  3*/         int x = 100;
/*  4*/         test(); // xは変わらない
/*  5*/         System.out.println("main x = " + x);
/*  6*/     }
/*  7*/     static void test () {
/*  8*/         int x = 200; // testのxに格納したから
/*  9*/         System.out.println("test x = " + x);
/* 10*/     }
/* 11*/ }
asiaa1:~/comp2b b08a001$ java VariableScope3
test x = 200
main x = 100
asiaa1:~/comp2b b08a001$

どうしても、呼び出し側とメソッド定義で同じ変数を使いたい場合は、 クラス変数class variable )というものを使います。 これは、 class の直下で宣言する変数で、

static int variable;

と書きます。 クラス変数は、呼び出し側でもメソッド定義でも同じ変数と見なされます。

次の例では、クラス変数 x を宣言しています。 メソッド mainx に100を格納し、メソッド testx の値を200に変更します。 今度は、 main でも test でも、 x の値は200になります。

/*  1*/ class VariableScope4 { // 変数のスコープ4
/*  2*/     static int x; // mainでもtestでも使える
/*  3*/     public static void main (String[] args) {
/*  4*/         x = 100;
/*  5*/         test(); // xは変わる
/*  6*/         System.out.println("main x = " + x);
/*  7*/     }
/*  8*/     static void test () {
/*  9*/         x = 200; // クラス変数xに格納したから
/* 10*/         System.out.println("test x = " + x);
/* 11*/     }
/* 12*/ }
asiaa1:~/comp2b b08a001$ java VariableScope4
test x = 200
main x = 200
asiaa1:~/comp2b b08a001$

9.2.2 配列の引数

今まで定義したメソッドは、引数が整数のものばかりでした。 メソッドは整数に限りません。 引数が配列であるメソッドも定義できます。 これによって、配列に関する処理にも名前を付けることができます。

引数が配列であるメソッドを定義するには、整数のときの int の代わりに、 int []と書きます。 値を返さないメソッドならば、

static void methodname (int[] argument, ...) {
    statement; ...
}

と書き、整数( int 型)を返すメソッドならば、

static int methodname (int[] argument, ...) {
    statement; ...
}

と書きます。

メソッドを呼び出すには、引数に配列の変数名のみ書きます。 引数に[]は書きません。 値を返さないメソッドを呼び出すには、文として

methodname(argument, ...);

と書きます。 値を返すメソッドを呼び出すには、式として

methodname(argument, ...)

と書きます。

例として、配列要素を全て出力するプログラム

/*  1*/ class ArrayPrint2 { // 配列の出力2
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] array = {100, 110, 120, 130, 140};
/*  4*/         int i;
/*  5*/         for (i = 0; i < array.length; i++) {
/*  6*/             System.out.print(array[i] + " ");
/*  7*/         }
/*  8*/         System.out.println();
/*  9*/     }
/* 10*/ }
asiaa1:~/comp2b b08a001$ java ArrayPrint2
100 110 120 130 140 
asiaa1:~/comp2b b08a001$

を、メソッドを使って書き直します。

メソッドの名前は printBySpace とします。 このメソッドの引数は、配列 a です。 このメソッドは値を返さないので、 static void と指定します。

/*  1*/ class ArrayPrint3 { // 配列の出力3
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] array = {100, 110, 120, 130, 140};
/*  4*/         printBySpace(array); // 実引数は配列の変数名
/*  5*/         System.out.println();
/*  6*/     }
/*  7*/     static void printBySpace (int[] a) { // 仮引数も配列の変数名
/*  8*/         int i;
/*  9*/         for (i = 0; i < a.length; i++) {
/* 10*/             System.out.print(a[i] + " ");
/* 11*/         }
/* 12*/     }
/* 13*/ }

次の例は、配列要素の合計を計算するプログラム

/*  1*/ class ArraySum2 { // 配列の合計2
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] array = {100, 110, 120, 130, 140};
/*  4*/         int i, sum = 0;
/*  5*/         for (i = 0; i < array.length; i++) {
/*  6*/             sum = sum + array[i];
/*  7*/         }
/*  8*/         System.out.println(sum);
/*  9*/     }
/* 10*/ }
asiaa1:~/comp2b b08a001$ java ArraySum2
600
asiaa1:~/comp2b b08a001$

を、メソッドを使って書き直します。

メソッドの名前は getSum とします。 このメソッドの引数は、配列 a です。 このメソッドは整数( int 型)を返すので、 static int と指定します。

/*  1*/ class ArraySum3 { // 配列の合計3
/*  2*/     public static void main (String[] args)  {
/*  3*/         int[] array = {100, 110, 120, 130, 140};
/*  4*/         System.out.println(getSum(array));
/*  5*/     }
/*  6*/     static int getSum (int[] a) {
/*  7*/         int i, sum = 0;
/*  8*/         for (i = 0; i < a.length; i++) {
/*  9*/             sum = sum + a[i];
/* 10*/         }
/* 11*/         return sum;
/* 12*/     }
/* 13*/ }

メソッドは、似た処理があるときに便利になります。 ここで、次の出力が得られるようなプログラムを考えます。

asiaa1:~/comp2b b08a001$ java ArrayPrintSum
100 110 120 の合計は330
100 110 120 130 の合計は460
100 110 120 130 140 の合計は600
asiaa1:~/comp2b b08a001$

データは次のように配列で与えます。

int[] array1 = {100, 110, 120};
int[] array2 = {100, 110, 120, 130};
int[] array3 = {100, 110, 120, 130, 140};

上記の2つのメソッドを利用すれば、短いプログラムで書けるのです。

/*  1*/ class ArrayPrintSum { // 配列の出力と合計
/*  2*/     public static void main (String[] args) {
/*  3*/         int[] array1 = {100, 110, 120};
/*  4*/         int[] array2 = {100, 110, 120, 130};
/*  5*/         int[] array3 = {100, 110, 120, 130, 140};
/*  6*/         printBySpace(array1);
/*  7*/         System.out.println("の合計は" + getSum(array1));
/*  8*/         printBySpace(array2);
/*  9*/         System.out.println("の合計は" + getSum(array2));
/* 10*/         printBySpace(array3);
/* 11*/         System.out.println("の合計は" + getSum(array3));
/* 12*/     }
/* 13*/     static void printBySpace (int[] a) {
/* 14*/         int i;
/* 15*/         for (i = 0; i < a.length; i++) {
/* 16*/             System.out.print(a[i] + " ");
/* 17*/         }
/* 18*/     }
/* 19*/     static int getSum (int[] a) {
/* 20*/         int i, sum = 0;
/* 21*/         for (i = 0; i < a.length; i++) {
/* 22*/             sum = sum + a[i];
/* 23*/         }
/* 24*/         return sum;
/* 25*/     }
/* 26*/ }

9.3 演習9

次の出力が得られるようなプログラムを考えます。

asiaa1:~/comp2b b08a001$ java ArrayPrintAverage
100,110,120,の平均は110
100,110,120,130,の平均は115
100,110,120,130,140,の平均は120
asiaa1:~/comp2b b08a001$

データは次のように配列で与えます。

int[] array1 = {100, 110, 120};
int[] array2 = {100, 110, 120, 130};
int[] array3 = {100, 110, 120, 130, 140};

配列要素をコンマ区切りですべて出力するメソッド printByComma と、配列要素の平均を計算するメソッド getAverage を自分で定義し、それらのメソッドを呼び出して、上記の出力が得られるプログラムを作成してください。 (平均が計算できるようにするために、配列の要素数は1以上であると仮定してください。)

余力のある人は、メソッド printByComma を改良して、余計なコンマが出力されないようにしてください。

asiaa1:~/comp2b b08a001$ java ArrayPrintAverage2
100,110,120の平均は110
100,110,120,130の平均は115
100,110,120,130,140の平均は120
asiaa1:~/comp2b b08a001$

9.4 レポート課題

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


9.5 参考文献


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

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