|
|
変数とデータ型 |
H.Kamifuji . |
プログラムの中で値を記憶しておく場合に使われる変数の使い方を確認します。またJavaで使用される基本データ型に関しても確認します。 なおここでは基本データ型を使った変数だけを解説しますのでクラス型の変数は別のページを参照して下さい。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 現在(2021/08)では、JDK-16.0.2 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2021/11)では、JDK-17.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2023/04)では、JDK-20.0.1 にアップされています。一部、上位互換について、見直しを行っていきます。 現在(2024/10)では、JDK-23 にアップされています。一部、上位互換について、見直しを行っていきます。 |
|
まずは変数とは何かについて簡単に確認してみます。 変数は値を保存しておくための箱のようによく言われます。この箱には数値や文字列などの値を保存することができ、そしていつでも取り出したり改めて違う値を保存することができます。 では順に2倍していき順に結果を表示するようなプログラムの場合を考えてみます。変数を使用しない場合は毎回毎回最初から2倍をしていかなければなりません。 System.out.println(1 * 2); System.out.println(1 * 2 * 2); System.out.println(1 * 2 * 2 * 2); System.out.println(1 * 2 * 2 * 2 * 2);少ない回数ならこれでもいいですけどこの計算を100回も繰り返すことを考えたら毎回毎回計算していくのは非効率です。 そこで変数を使います。計算を行ったら変数に一度保存しておきます。そして変数に保存された値を取り出して2倍していくことを繰り返します。(具体的な記述方法などは次項のページ以降で解説します)。 int num = 1; num = num * 2; System.out.println(num); num = num * 2; System.out.println(num); num = num * 2; System.out.println(num); num = num * 2; System.out.println(num);プログラムの行数が増えてしまっていますが、無駄な計算は行われず前回の計算結果を利用して効率良く計算が行われています。 今回は計算結果を一時的に保存するために変数を利用しましたが、変数に数値が格納されている場合には変数に対して直接演算を行ったり、ユーザーが入力した値を変数に保存しておきプログラムの中で何度でも利用するといったことも可能です。変数を使わなければ実現できないことや、変数をうまく使用することで効率的にプログラムを記述することができるようになります。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample1_1 { public static void main( String[] args ) { int num = 1 ; num = num * 2 ; System.out.println( num ); num = num * 2 ; System.out.println( num ); num = num * 2 ; System.out.println( num ); num = num * 2 ; System.out.println( num ); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample1_1 2 4 8 16 [xxxxxxxx@dddddddddd Var]$ |
変数は値を保管しておく場所の箱のようなものであることは前のページでご説明しました。では実際に変数をプログラムの中で使用するにはどのようにすればいいのかを確認します。 変数を使用するには、まず最初に使用する変数を宣言しなくてはいけません。宣言は次のように行います。 型名 変数名;変数の宣言では、変数に格納される値のデータ型と変数を区別するための変数名を指定します。例えば次のようになります。 int count; double data;1行目は「int」型の値を格納する変数名「count」という変数。2行目は「double」型の値を格納する変数名「data」という変数を宣言しています。 Javaではこのようにプログラムの中で使用する変数は予め宣言しておくことが必要です。また変数は宣言する時にどんな値を格納するのかを決めておかなければなりません。なおデータ型と変数名の規則については次のページで解説します。 同じデータ型を扱う複数の変数を宣言する方法変数は同じプログラムの中で何個でも宣言することができますが同じデータ型の変数を宣言する場合は次のような記述も可能です。型名 変数名1, 変数名2, 変数名3, ...;今まで変数名を記述していた箇所に、カンマで区切って変数を続けて記述していきます。 例えば次のように記述していた場合で考えてみます。 int a; int b; int c;このように同じデータ型の変数を宣言する場合は次のように記述することもできます。 int a, b, c;記述方法が異なるだけでどちらで行っても構いません。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample2_1 { public static void main ( String[] args ) { int num ; double data ; int x ,y ,z ; } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample2_1 [xxxxxxxx@dddddddddd Var]$今回は変数を宣言しただけで他には何もしていません。 ではもう一つサンプルを試してみます。今度は変数宣言を行っていない変数を使用した場合です。 サンプルプログラム下記のサンプルを実行してみよう。class JSample2_2 { public static void main ( String[] args ) { num = 10 ; } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ javac JSample2_2.java JSample2_2.java:3: エラー: シンボルを見つけられません num = 10 ; ^ シンボル: 変数 num 場所: クラス JSample2_2 エラー1個 [xxxxxxxx@dddddddddd Var]$宣言されていない変数を使用した場合は上記のようなエラーとなります。 プログラム言語によっては変数の宣言を行わなくても変数を使用できるものもありますが、Javaでは必ず変数の宣言を事前に行う必要があるということを覚えておいて下さい。 |
変数はプログラムの中で複数使用することができますので、一つ一つの変数を区別するために変数には変数名を付けます。変数名を付ける時の規則は次のようになっています。 使用できる文字はAからZ、aからz、0から9、アンダーバー(_)、$ (例) name, old, no32 先頭文字には数字の0から9は使用できない (例) 12pointなどは× 大文字と小文字は区別される (例) old と Oldは別の変数 予約語は使用できない (例) char や classなどの予約語は使用できない 長さの制限は無い例えば「num」や「name」などのアルファベットのみや「year2009」や「frame_name」などのように数字やアンダーバーと組み合わせた名前を変数に付けることができます。なお先頭の文字が数字の「100year」などは使用できません。「if」や「static」などの予約語も使用できません。(予約語については「予約語」を参照して下さい)。 「$」は使用可能ですがプログラムを記述する人が使用するケースはあまり無いのではと思います。また大文字と小文字は区別されるため「name」と「Name」は別の変数名として扱われます。 今回は変数の名前でしたが、他にもクラスなどに名前を付けることができます。変数やクラスに付けることができる名前をJavaでは識別子と読んでいます。 どのような変数名を付けるべきか変数名は規則に従っていれば任意の名前を付けることができますが、単に変数の名前として付ける場合には先頭の文字を小文字で始める場合が多いと思います。またクラスに名前を付ける時は先頭の文字を大文字にし、定数を定義するときは全て大文字にするといったように自分で規則を決めておくといいのではないでしょうか。では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample3_1 { public static void main ( String[] args ) { int sansu ; int rika ; sansu = 80 ; rika = 45 ; System.out.println( "算数の点数は" + sansu ); System.out.println( "理科の点数は" + rika ); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample3_1 算数の点数は80 理科の点数は45 [xxxxxxxx@dddddddddd Var]$今回は2つの変数を宣言し別々の値を格納しています。そしてそれぞれの変数から値を取り出して画面に出力しています。 エラーとなるサンプル次のサンプルでは先頭の文字を数字にした変数を使用してみます。サンプルプログラム下記のサンプルを実行してみよう。class JSample3_2 { public static void main ( String[] args ) { int 8box ; } }コンパイルすると次のようにエラーとなります。 [xxxxxxxx@dddddddddd Var]$ javac JSample3_2.java JSample3_2.java:3: エラー: 文ではありません int 8box ; ^ JSample3_2.java:3: エラー: ';'がありません int 8box ; ^ JSample3_2.java:3: エラー: 文ではありません int 8box ; ^ エラー3個 [xxxxxxxx@dddddddddd Var]$また予約語を変数名に使用した場合も試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample3_3 { public static void main ( String[] args ) { int const ; } }コンパイルすると次のようにエラーとなります。 [xxxxxxxx@dddddddddd Var]$ javac JSample3_3.java JSample3_3.java:3: エラー: 文ではありません int const ; ^ JSample3_3.java:3: エラー: ';'がありません int const ; ^ エラー2個 [xxxxxxxx@dddddddddd Var]$予約語の場合は、使用した予約語によって発生するエラーも異なりますが変数名として使用できないことに違いはありません。 なお予約語であっても大文字と小文字の区別は適用されますので、例えば「const」ではなく「Const」や「cOnst」のようにすれば変数名として使用できます。ただあまりこのように予約語を大文字にして使う方法はケアレスミスの元となりますのでお勧めできません。 |
変数宣言するときには変数名と同時に変数のデータ型を指定する必要があります。 データ型とは値の種類のことで整数や浮動小数点数、そして文字などです。Javaで用意されているデータ型は次の通りです。
例えば整数を保存するための変数でもいくつか用意されています。大きな値を保管できるデータ型を指定しておけば何でも大丈夫なように思えますが、大きな値を保管できるデータ型はコンピュータの資源を多く必要とします。そのため本当に必要なデータ型を使用することが大事です。 それではひとつひとつデータ型を確認していきます。 整数のデータ型整数の値を格納するためのデータ型は格納する数値の大きさに合わせて4種類用意されています。byte -128 〜 127 short -32768 〜 32767 int -2147483648 〜 2147483647 long -9223372036854775808 〜 9223372036854775807※char型も整数のデータ型と考えることもできます。char型については後で解説します。 通常はint型で十分ですが極めて大きい数値を扱う場合にはlong型を使います。 なお数値リテラルの整数の値はint型の値として扱われます。つまり数値をプログラムの中で記述する場合はint型で格納できる範囲である-2147483648から2147483647までの数値しか記述できません。 そこでint型を越えるlong型の範囲の数値をプログラムの中で記述する場合は、数値の最後に「L」または「l」を付けます。 18000305032230531L 39433204432234523l今後long型の変数に値を格納する場合などに、int型の範囲を超える数値を記述する場合には「L」や「l」を付けるのを忘れないように注意して下さい。 byte型やshort型を明示的に表すための文字はありません。その為、byte型やshort型の変数に値を代入する時は単に数値を記述します。 short s; s = 20;20という数値はint型の値ですが自動的に型変換が行われて代入されます。ただしbyte型やshort型の範囲を超えた数値をそのまま代入するとエラーとなります。その場合はキャスト演算子を使って型の変換が必要となります。詳しくは「型変換」を参照して下さい。 浮動小数点数のデータ型浮動小数点数の値を格納するためのデータ型は格納する数値の大きさに合わせて2種類用意されています。float 32ビット単精度浮動小数点数 double 64ビット倍精度浮動小数点数単精度浮動小数点数は負の値は -3.4028235E+38 〜 -1.401298E-45、正の値は 1.401298E-45 〜 3.4028235E+38 の範囲の値をとります。倍精度浮動小数点数はの値は -1.79769313486231570E+308 〜 -4.94065645841246544E-324、正の値は 4.94065645841246544E-324 〜 1.79769313486231570E+308 の範囲の値をとります。いずれの場合も極めて巨大な値から極めて小さい値まで扱うことができます。 なお数値リテラルの浮動小数点数の値はdouble型の値として扱われます。もしdouble型ほどの精度を必要としない場合には「F」または「f」を付けることでfloat型の数値として記述することができます。 1.223F 0.83f何も付けなければデフォルトでdouble型の値となりますがdouble型を表す「D」または「d」を付けることも可能です。ただ通常は省略して何も記述しません。 浮動小数点数の値について詳しく書くのは専門的になるので省略しますが、浮動小数点数は実際には近似値を格納します。その為、誤差が生じる場合がありますので注意して下さい。(イメージとしては10÷3の結果のように割り切れない値を格納した時に、その近似値が格納されるため格納された値を取り出して3倍しても10にならない場合があります)。 文字のデータ型1つの文字を格納するためのデータ型としてchar型が用意されています。char 16ビットUnicode文字 \u0000〜\uFFFFここで1つの文字とは16ビットUnicodeで定義されている文字となりaやBなどの半角アルファベットだけではなく「あ」や「漢」など全角の文字も1つの文字として扱われます。格納する文字については「文字」や「文字コード」を参照して下さい。 なお文字を格納するために使われるchar型ですが実際にも文字コードを格納します。その為、16ビットの符号が無い整数を格納するためのデータ型と考えることができます。 char 0 〜 65635 boolean型boolean型は特別なデータ型で、格納できる値はtrueまたはfalseのいずれかだけです。boolean true or falseこのtrueおよびfalseはJavaであらかじめ定義された定数です。論理演算の結果などがtrueまたはfalseを返しますのでその値を格納するために使用されます。詳しくは論理演算のページを参照して下さい。 なおJavaでは「1」はtrueではなく「0」はfalseではありません。他のプログラミング言語では「0」がfalseで「0以外」はtrueとして扱われるようなものもありますがJavaではそのようには見なされませんので注意して下さい。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample4_1{ public static void main(String args[]){ int n; long l; double d; char c; boolean b; n = 100; l = 45333336854798037L; d = 32.45503; c = '朝'; b = true; System.out.println(n); System.out.println(l); System.out.println(d); System.out.println(c); System.out.println(b); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample4_1 100 45333336854798037 32.45503 朝 true [xxxxxxxx@dddddddddd Var]$ エラーとなるサンプル次のサンプルではint型の変数にfloat型の値を代入しています。サンプルプログラム下記のサンプルを実行してみよう。class JSample4_2{ public static void main(String args[]){ int n; n = 1.43F; } }コンパイルすると次のようにエラーとなります。 [xxxxxxxx@dddddddddd Var]$ javac JSample4_2.java JSample4_2.java:5: エラー: 不適合な型: 精度が失われる可能性があるfloatからintへの変換 n = 1.43F; ^ エラー1個 [xxxxxxxx@dddddddddd Var]$ 次はboolean型の変数にtrueとfalse以外の値を代入した場合です。 サンプルプログラム下記のサンプルを実行してみよう。class JSample4_3{ public static void main(String args[]){ boolean b; b = 0; } }コンパイルすると次のようにエラーとなります。 [xxxxxxxx@dddddddddd Var]$ javac JSample4_3.java JSample4_3.java:5: エラー: 不適合な型: intをbooleanに変換できません: b = 0; ^ エラー1個 [xxxxxxxx@dddddddddd Var]$このようにboolean型の変数にはtrueまたはfalse以外の値は格納できません。 |
変数の役割は値を格納したり取り出したりすることです。ここでは変数宣言した変数に値を格納する方法を確認します。 変数に値を格納することを変数に値を代入するといいます。書式は次の通りです。 変数 = 値;「=」は代入演算子と呼ばれる演算子の一つです。「=」の右側に記述された値を左側に書かれた変数に代入します。 具体的な例で見てみます。 int num; num = 10; char c; c = 'A';この場合は変数「num」に10という整数を代入し、変数「c」に「A」という文字を代入しています。 変数に値を代入すると、変数はあたかも代入された値のように扱うことができます。 int num; num = 10; System.out.println(num);変数「num」を画面に出力しています。変数「num」には10という整数が代入されていますので結果的に数値の10が出力されることになります。 なお変数に代入することができる値は、変数を宣言した時に指定したデータ型の値しかできません。 多重代入複数の変数に同じ値を代入する場合、多重代入という仕組みが用意されています。書式は次の通りです。変数1 = 変数2 = 変数3 = 値;この場合、変数1から変数3には全て同じ値が代入されます。これは次のように記述した場合とまったく同じです。 変数1 = 値; 変数2 = 値; 変数3 = 値;※厳密に言うと、「変数3 = 値;」「変数2 = 変数3;」「変数1 = 変数2;」と言う順序で代入が行われます。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample5_1{ public static void main(String args[]){ int n; char c; n = 100; System.out.println(n); c = 'B'; System.out.println(c); System.out.println(n); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample5_1 100 B 100 [xxxxxxxx@dddddddddd Var]$ |
ここまで解説したとおり、変数はまず宣言を行い、その後に変数に値を代入しています。 型名 変数; 変数 = 値;もし変数を宣言する時点で代入する値が決まっている場合には次の書式を使うことができます。 型名 変数 = 値;このように変数を宣言すると同時に値を代入することを変数の初期化と言います。 具体的な例で見てみます。 int num = 10; System.out.println(num);この場合は変数「num」は宣言と同時に10という整数を代入されていますので、変数「num」を画面に出力すると変数に代入されている10が出力されます。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample6_1{ public static void main(String args[]){ int n = 100; char c = '鼻'; System.out.println(n); System.out.println(c); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample6_1 100 鼻 [xxxxxxxx@dddddddddd Var]$ |
変数は代入された値を保管しておく場合に使用されますが、変数に値を一度代入した後で改めて別の値を代入することも可能です。 特別な書式は無く、新しい値を再度代入するだけとなります。 int num = 10; num = 8;変数「num」は宣言時に初期化されて10が代入されていましたが、その後で改めて8が代入されています。 注意する点としては、1つの変数は一度に一つの値しか保持することはできません。その為、別の値を変数に代入するとそれまで変数が持っていた値は失われてしまいます。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample7_1{ public static void main(String args[]){ int n = 100; System.out.println(n); n = 12; System.out.println(n); n = 356; System.out.println(n); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample6_1 100 12 356 [xxxxxxxx@dddddddddd Var]$変数に値を代入するたびに画面に出力して確認しました。 |
最後に変数に代入された値を取得する方法を確認します。 これまでのサンプルでも使用してきましたが、数値や文字を記述する場所で代わりに変数を記述すると、変数に代入されている値が取り出されて代わりに使われます。次のサンプルを見てください。 System.out.println('A'); char c = 'A'; System.out.println(c);このサンプルでは2回「A」の文字が画面に出力されます。このようにプログラムの中で変数を記述すると、変数に代入されている値が代わりに使われます。では次のサンプルを見て下さい。 int n1, n2; n1 = 10; n2 = n1;このサンプルではまず変数「n1」に数値の10を代入しています。そして次に変数「n2」に変数「n1」を代入しています。この場合も変数「n1」に代入されている値である数値の10が記述されたものとして扱われますので変数「n2」には数値の10が代入されます。 int n1, n2; int result; n1 = 10; n2 = 20; result = n1 * 5 + n2;このサンプルでは変数「n1」の値を5倍し、それに変数「n2」の値を加算したものを変数「result」に代入しています。このように変数に対して加算や乗算といった演算を行うことも可能です(演算については演算子のページで詳しく解説します)。 基本データ型の変数の場合の代入についてまずは次のサンプルを見てください。int n1, n2; n1 = 10; n2 = n1; n1 = 20; System.out.println(n1); System.out.println(n2);このサンプルでは変数「n1」に10を代入し、次に変数「n2」に変数「n1」を代入し、最後に変数「n1」に20を代入しています。この時、変数「n1」には20が代入されていますが変数「n2」には何が代入されているでしょう。答えは10です。 Javaでは基本データ型を使用する変数の場合、変数毎に実際に値を保管する場所を持っています。変数を他の変数に代入すると、元の変数の値を複製して代入する先の変数に保管します。その為、同じ値が別々に保管されることになります。よってその後でどちらかの変数に別の値を代入しても、他の変数が保管している値には何の影響も与えません。 プログラミング言語によっては、変数は保管場所を持たずに別途用意された保管場所を指す目印だけを持つものもあります。変数に他の変数を代入すると、それはどこかにある同じ保管場所を指し示す目印が複製されることになり、どちらの変数も同じ保管場所を共有することになります。よってその後でどちらかの変数に別の値を代入すると、保管場所を共有している全ての変数に影響が出ます。 Javaであっても配列やクラス型の変数の場合には、実際に保管場所を持たず他に用意された保管場所の目印だけを持つようになります。詳しくは配列やクラスのところで解説しますが、変数に他の変数を代入する場合にはそれが何の変数かによって扱いが異なる場合もあるということだけ覚えておいて下さい。 では簡単なサンプルで試してみます。 サンプルプログラム下記のサンプルを実行してみよう。class JSample8_1{ public static void main(String args[]){ int n1, n2; n1 = 100; n2 = n1; System.out.println(n1); System.out.println(n2); System.out.println("----"); n1 = 80; System.out.println(n1); System.out.println(n2); } }上記をコンパイルした後で実行すると次のように表示されます。 [xxxxxxxx@dddddddddd Var]$ java JSample8_1 100 100 ---- 80 100 [xxxxxxxx@dddddddddd Var]$ |
|