Upload
maili
View
28
Download
0
Embed Size (px)
DESCRIPTION
アルゴリズムとプログラミング (Algorithms and Programming). 変数 (variable) とは 変数の 型 (type) 変数の 宣言 と初期化 変数への値の 代入 型変換 (cast) Java の 演算子 (operator) ( 補足 ) 文字型の取り扱い. 第 2 回: Java の変数と演算子. 講義資料等:. http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html. Java 開発環境の準備. Java のインストール - PowerPoint PPT Presentation
Citation preview
アルゴリズムとプログラミング
(Algorithms and Programming)第 2 回: Java の変数と演算子
•変数 (variable) とは•変数の型 (type)•変数の宣言と初期化•変数への値の代入•型変換 (cast)•Java の演算子 (operator)•( 補足 ) 文字型の取り扱い
•変数 (variable) とは•変数の型 (type)•変数の宣言と初期化•変数への値の代入•型変換 (cast)•Java の演算子 (operator)•( 補足 ) 文字型の取り扱い
講義資料等: http://www.pe.titech.ac.jp/~watanabe/lecture/ap/index-j.html
Java 開発環境の準備Java のインストールhttp://java.sun.com/javase/downloads/index.jsp• Downloads JDK⇒ の Multi-language 版を選択• 最新版をインストールしてください• Netbeans などの IDE は必須ではない• 環境変数の登録を忘れずに• 手になじんだテキストエディターを準備して.. さあ、はじめよう!!
コンパイルのチェック• テキストエディタで作成: FirstProgram.java
class FirstProgram {
public static void main(String[] args) {
System.out.println(”Hello World!”);
}
}
class FirstProgram {
public static void main(String[] args) {
System.out.println(”Hello World!”);
}
}
• 保存したらコンパイル
• 実行javac FirstProgram.java
java FirstProgram
↲
↲
変数とは変数:データを格納するメモリ領域 ( 読み書き可能 )
変数を定義するには,まずそのビット数を定めなければならない.
( コンパイラは,メモリ領域の先頭番地を,変数aなどの識別子に対応付けている)
a = 3;例) a という識別子に対応付けられたメモリ領域に,値3を代入する
0 0 0 0 0 0 1 1
型 (type) :変数に格納する値の種類が規定される (ビット数とその解釈)
Java で定義されている基本型(type)
型の名称 ビット数
値の範囲 説明
boolean 1 true or false 真偽値
char 16 \u0000 ~ \uFFFF 文字コード (Unicode 規格 ) に対応
byte 8 -27 ~ 27-1 (-128 ~ 127)
符号付整数
short 16 -215 ~ 215-1 (-32768 ~ 32767)
符号付整数
int 32 -231 ~ 231-1(-2147483648 ~ 2147483647)
符号付整数
long 64 -263 ~ 263-1(-9223372036854775808~ 9223372036854775807)
符号付整数
float 32 ±3.40282347E+38 ~±1.40239846E-45
浮動小数点数
double 64 ±1.79769313486231570E+308 ~±4.94065645841246544E-324
浮動小数点数
BB
00050004
34AF
メモリアドレス
00000001
21D10003047F
0002
8bit 分のデータを格納する領域
FFFE 00FFFF
コンパイラが、変数bの値を格納するメモリ領域を確保する( コンパイラの仕事.プログラマは宣言するだけ. )
変数の宣言=メモリ領域の確保例 ) byte 型の変数bを宣言する
byte b;byte b;記法:
表現できる値の個数は?
byte 型 (8bit) の値の範囲
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1
● 10進数で0~255
●byte 型は符号付整数なので, 正負半分ずつにふり分けて -128~127
負数の求め方→2の補数表現最上位ビットが1なら負数
→28 (=256) 個
-1の2進数表現を求める• 1の2の補数をとる
0 0 0 0 0 0 0 11=
1 1 1 1 1 1 1 0
ビット反転
+11 1 1 1 1 1 1 1
ー1の2進数表現コンピュータの内部表現なので,プログラマーは通常意識する必要は無い
-128, -127, -126,..., -1, 0, 1, 2, ...,126, 127128 129 130 255 0 1 2 126 127
byte 型の値の範囲 (-128 ~ 127)
(符号無し整数)
(符号付き整数)
int 型や long 型も同様
この範囲では符号付きと符号無しは一致
2進数の小数表記20212223 2-42-32-22-1
1101 1001
二進数 十進数0.1000 2-1 = 0.50.0100 2-2 = 0.250.0010 2-3 = 0.1250.0001 2-4 = 0.0625
二進数 十進数0.1000 2-1 = 0.50.0100 2-2 = 0.250.0010 2-3 = 0.1250.0001 2-4 = 0.0625
23 + 22 + 20 + 2-1 + 2-4
浮動小数点 (floating point)
表記の例: 3.14
6.02E+23 (→ 6.02×1023 )(仮数部) × 2(指数部) の形に変換し,(仮数)と(指数)をビット列としてメモリに保存
浮動小数点数の宣言と値の代入:double x, y ;float z = 2.05 ;double x, y ;float z = 2.05 ;
float 型のビット構成(IEEE754 規格 32bit 浮動小数点数 )
符号部 S(1bit)指数部 e(8bit) 仮数部 k(23bit)
符号 S 仮数 k
0: +1: -
× 21.指数
20212324
低位桁高位桁263 222
2 進数表記
指数部の 2 進数表現... 1000 0011 +4 乗1000 0010 +3 乗1000 0001 +2 乗1000 0000 +1 乗0111 1111 0 乗0111 1110 -1 乗0111 1101 -2 乗0111 1100 -3 乗...
float 値への変換
ビットレイアウト
127(10)
8bit 指数部の値から127 を引いた値が実際の指数を表す0は、符号部、仮数部、指数部=0で表現
無限大、無限小の表現も定義されている
12723
( 1) (1 ) 22
S ek
class FloatingPoint {public static void main(String[] args) {
// 引数文字列 args[0] を float 型に変換float f = Float.parseFloat(args[0]);// float 型 f のビット表現を文字列 str に変換String str =
Integer.toBinaryString(Float.floatToRawIntBits(f));
System.out.println(args[0] + " = " + str);}
}
class FloatingPoint {public static void main(String[] args) {
// 引数文字列 args[0] を float 型に変換float f = Float.parseFloat(args[0]);// float 型 f のビット表現を文字列 str に変換String str =
Integer.toBinaryString(Float.floatToRawIntBits(f));
System.out.println(args[0] + " = " + str);}
}
FloatingPoint.java
C:\java>javac FloatingPoint.javaC:\java>java FloatingPoint 21.687521.6875 = 1000001101011011000000000000000C:\java>java FloatingPoint -21.6875-21.6875 = 11000001101011011000000000000000
float 値 (32bit) のビットレイアウトを表示するJava プログラム
(注意:上位桁の0は表示されないので、32 bit に足りない分は上位桁に0を補う)
class IntBitsToFloat { // 与えられた int 値を IEEE754 浮動小数点数//(32bit) のビットレイアウトと見なして float 値に変換するプログラム// ラッパークラスにあらかじめ用意されているメソッドを使う public static void main(String[] args) { int i=0xC0E0000 ; // 与えられた int 値 (32bit 以内 )
System.out.println( " 与えられた int 値 (16 進数 )=" + Integer.toHexString(i) ); System.out.println( " 与えられた int 値 (2 進数 )=" + Integer.toBinaryString(i) ); System.out.println( "float 値 =" + Float.intBitsToFloat( i ) ); }}
class IntBitsToFloat { // 与えられた int 値を IEEE754 浮動小数点数//(32bit) のビットレイアウトと見なして float 値に変換するプログラム// ラッパークラスにあらかじめ用意されているメソッドを使う public static void main(String[] args) { int i=0xC0E0000 ; // 与えられた int 値 (32bit 以内 )
System.out.println( " 与えられた int 値 (16 進数 )=" + Integer.toHexString(i) ); System.out.println( " 与えられた int 値 (2 進数 )=" + Integer.toBinaryString(i) ); System.out.println( "float 値 =" + Float.intBitsToFloat( i ) ); }}
IntBitsToFloat.java
32bit のビットレイアウト (int 値 ) を float 値に変換して表示する Java プログラム
ビットレイアウト
double 型のビット構成(IEEE754 規格 64bit 浮動小数点数 )
符号部 S(1bit) 指数部 e(11bit) 仮数部 k(52bit)
20212324
低位桁高位桁263 251
符号 仮数
0: +1: -
× 21.指数
2 進数表記
double 値への変換
102352
( 1) (1 ) 22
S ek
変数の宣言と値の代入
int i ;i = 0 ;int i ;i = 0 ;
宣言 ( 型と変数名を決める )値の代入 ( =は代入演算子 )
int i = 0 ;int i = 0 ; 意味は上と同じ
セミコロンは文の終わりを表す.忘れると文が次の行まで続いていることになってしまうので注意!
0 = i ;0 = i ;
識別子の命名規則• 使える文字は半角文字の英字・数字・アンダースコア
「 _ 」に限定(例外は多いが避けた方が無難)
• 半角英字の大文字・小文字は区別される
• 数字で始まる識別子は認めない
• キーワード (keyword) と呼ばれる Java の予約語と、 true ・ false ・ null の3単語は使用できない。(他の語句と組み合わせれば可)
• 長さに制限はない
変数名,クラス名など
class Sample1401 {
public static void main(String[] args) {
int a;
int b = 10;
a = 200;
b = 100;
System.out.println(” 変数 a”);
System.out.println(a);
System.out.println(” 変数 b”);
System.out.println(b);
}
}
class Sample1401 {
public static void main(String[] args) {
int a;
int b = 10;
a = 200;
b = 100;
System.out.println(” 変数 a”);
System.out.println(a);
System.out.println(” 変数 b”);
System.out.println(b);
}
}
サンプルプログラム ( 宣言と代入 )ファイル名: Sample1401.java
コンパイル: javac Sample1401.java実行: java Sample1401
int 型の変数 a を宣言する
int 型の変数 b を宣言し、値 10 を代入する
この表記法に関しては後の講義で
クイズ: 下記プログラムの実行結果は?
class AP0201 { public static void main(String[] args) { int i = 2147483647 ; i = i + 1 ; System.out.println(i); }}
class AP0201 { public static void main(String[] args) { int i = 2147483647 ; i = i + 1 ; System.out.println(i); }}
ファイル: AP0201.java
-2147483648-2147483648実行結果:
int の最大値
教訓:最大値に留意して変数の型を選択せよ!
数値リテラル ( 定数 ) の表記法整数リテラルlong i = 200L ; ( 明示的に long 型であることを指定する )int i = 200 ; ( 何も指定しなければ int 型とみなされる )
10 進数リテラル 12348進数リテラル 01234 ( 先頭に 0 を付加する)16 進数リテラル 0x1234 ( 先頭に 0x を付加する)
浮動小数点リテラル
double x = 1.0, y = 6.02e+23, z = 1.23d ;float y = 2.0f ;
何も指定しなければdouble
指数の表記
l( 小文字のエル ) でも可だが L が推奨
式の構成• 演算は式によって記述される• 式はオペランドと演算子で構成される 1+3 や i + 10 など• 式には型があり、(演算の結果)値を持つ
i = i + 3 ;i = a - b ;i = i + 3 ;i = a - b ;
その結果を代入文や比較文で利用
• 代入文は値を持つ(値は代入された値)
x = y = z = 3 ;x = y = z = 3 ; → 多重代入式
式の値と型すべての式は、型と値を持つ
int a=1, b;b = 24 * a;← この行全体は変数 b への代入式だが、右辺だ
けでも“式”であり、型と値を持っている。1)まずオペランドの型を全て調べ、式の型を決める。この場合は int 型と判断される。2)次に、それぞれのオペランドの値を確定 ( 評価 ) する。定数はそのままの値だが、強制的に式の型にはめられることに注意せよ。変数の場合は、その時点で格納されている値を採用する。3)それらの値を用いて演算を実行し、その結果を右辺の式の値とする。4)その値が b に代入される。
こんな単純な式でも、 Java VM がやっていることは意外と手が込んでいる!!
long i = 24 * 60 * 60 * 1000 * 1000 ; ( マイクロ秒単位の 1 日の長さ )
代入したい数値は 86400000000 である。 int 値の範囲からは逸脱しているが long 値の範囲内には入っている。一見正しそうだが。
右辺の型が int と判断されるので、演算は int 型で実施される。86400000000 はオーバーフローし、予期しない値が long に拡張型変換されて 変数 i に代入される。
注意! 下記プログラムは意図した動作をしない!
演算子と優先順位演算子 説明
++ インクリメント ( + 1 )
- - ディクリメント ( - 1 )* 乗算/ 除算
% 剰余+ 加算- 減算
+= 加算代入 -= 減算代入*= 乗算代入/= 除算代入
%= 剰余代入
優先順位高い
低い(同一グループ内の優先順位は同じ)
多重代入式の動作
a += b = c ;a += b = c ;
記述 解釈
b = c ;
a = a + b ;
b = c ;
a = a + b ;
a = b += c ;a = b += c ; b = b + c ;
a = b ;
b = b + c ;
a = b ;
a += b -= c ;a += b -= c ; b = b - c ;
a = a + b ;
b = b - c ;
a = a + b ;
(右から左へ )
インクリメント演算子
a++a++
++a++a
(1) (a++) の値として a の値を採用する(2)変数 a の値に1を加算する
(1)変数 a の値に1を加算する(2)加算した結果を (++a) の値として採用する
値の評価と加算の順序が異なる!!
数値型変数のみに使える
(a++) を a の中身の値で置き換える
後置
前置
評価
加算
加算
評価
インクリメント演算子と代入文
b = a++ ;b = a++ ;
b = ++a ;b = ++a ;
(1) (a++) の値として a の値を採用する(2)変数 a の値に1を加算する(3)(1)で採用した (a++) の値を b に代入する
(1)変数 a の値に1を加算する(2)加算した結果を (++a) の値とする(3)(2)で確定した値を b に代入する
実行後の a の値は同じだが、 b の値は異なる!!
a = a+1;b = a ;
int tmp = a ;a = a + 1 ;b = tmp ;
インクリメント演算子の実行
代入演算子の実行
評価
加算
加算
評価
++、ーー演算子を含む式の実行(オペランドの値の決定と演算順序に関する注
意)
a=2; b = --a * a ; // b=1a=2; b = a-- + --a ; // b=2a=2; b = a * --a ; // b=2a=2; b = a + --a * a; // b=3a=2; b = a + a * --a; // b=4a=2; b = --a + a * a ; // b=2
a=2; b = --a * a ; // b=1a=2; b = a-- + --a ; // b=2a=2; b = a * --a ; // b=2a=2; b = a + --a * a; // b=3a=2; b = a + a * --a; // b=4a=2; b = --a + a * a ; // b=2
•演算順序としては ++,- - が一番早いが、オペランドの値の評価は式の左から行われる•式のオペランドは、左から順に値を決めていく。値が決まったら演算順序に従って演算を実行する。値を決める際に ++,-- が反映するので ++,-- の演算順序が早いといわれるが、実際にはオペランドの値は式の左から順に決まっていくのである。
a=2;b = a-- + --a ; b の値はいくつ?
a=2;b = a-- + --a ; b の値はいくつ?
1.まず右辺が評価される
(a--) + (--a)
オペランドの値を左から順に確定 (評価 ) していく。まずは a - - から。a の値は 2 なので、 (a--) の値は 2 と評価される
(問題)
a=2;b = a-- + --a ; b の値はいくつ?
a=2;b = a-- + --a ; b の値はいくつ?
1.まず右辺が評価される
( 2 ) + (--a)
オペランドの値を左から順に確定 (評価 ) していく。まずは a - - から。a の値は 2 なので、 (a--) の値は 2 と評価される
その直後、 a の値は1減算され、 a の値は 1 となるデクリメント演算子の動作
次に (--a) の値が評価される。前置演算子なので(--a) の値は 1-1 で 0 と評価される。
(問題)
a=2;b = a-- + --a ; b の値はいくつ?
a=2;b = a-- + --a ; b の値はいくつ?
1.各オペランドの値が確定した!
( 2 ) + ( 0 )
結果として、演算 (2) + (0) が実行され、右辺の式の値は 2 と確定する。
2. 代入演算子により右辺の式の値 2 が左辺の b に代入される。
∴ b = 2 ∴ b = 2
= 2
(問題)
(答え)
その他の代入演算子
i += 3 ;i += 3 ; i = i + 3 ;i = i + 3 ;
a *= 0.5 ;a *= 0.5 ; a = a * 0.5 ;a = a * 0.5 ;
a *= b + 1 ;a *= b + 1 ; a = a * ( b + 1 ) ;a = a * ( b + 1 ) ;
演算子演算子 説明
+ 加算- 減算 (あるいは正負の符号反転 )* 乗算/ 除算
% 剰余++ インクリメント ( + 1 )- - ディクリメント ( - 1 )+= 加算代入 -= 減算代入*= 乗算代入/= 除算代入
%= 剰余代入
型が異なる変数の代入
型の違う変数の代入int a = 0 ;long b = 0;
b = a ;a = b ;
int a = 0 ;long b = 0;
b = a ;a = b ; エラー!!
OK
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
桁あふれ(byte)
(short)
代入
値を比較しているのではなく、型の大きさだけで判断
型変換double d = 0.1;int i = 1 ;long ii = 3;
ii = i ;d = (double) i ;ii = d;
double d = 0.1;int i = 1 ;long ii = 3;
ii = i ;d = (double) i ;ii = d;
強制的に指定の ( 型 ) へ変換して代入≡型変換
サイズ小→サイズ大への代入は暗黙に行われる
long と double はビット数は等しいが表現する値の範囲が double の方が広いため、コンパイルエラー
( )→ キャスト演算子
型変換の注意int i = 1;long ii = 3;
i = (int)ii ;
int i = 1;long ii = 3;
i = (int)ii ; 強制的に型変換するとサイズ大→サイズ小の代入ができてしまうが情報が失われる可能性に注意せよ!
暗黙の型変換(演算の場合)2つのオペランドの型を比べて,小さい方のオペランドの型を,大きい方のオペランドの型に変換してから演算する. ( 同じ型なら変換せずに演算 )
double d ;int i = 1;
d = 1 / 2 ;d = 0.5 * i ;d = i – d ;
d = 0d = 0.5*(double)1=0.5d = (double)1 – 0.5 = 0.5
文字型 (char 型 )char 型は 16bit の整数値を持ち, Unicode との
対応表により1文字を表現するのに使われる
char c1, c2;
c1 = ‘1’ ;
c2 = ‘a’ ;
c1 = ‘ ‘ ;
char c1, c2;
c1 = ‘1’ ;
c2 = ‘a’ ;
c1 = ‘ ‘ ;
• ‘ ‘は,文字定数 ( リテラル ) を意味する.
• 文字’ 1’ に対応する 16bit 値 (Unicode) がc1 に格納される
• 空白 ( スペース ) も立派な1文字である 半角スペースと全角スペースは異なる Unicode
複数の文字の並び(=文字列)は,1つのchar 型値では表現できない!char c1=‘ab’;char c1=‘ab’;
文法エラー
文字列リテラル ( 定数 )class FirstProgram {
public static void main(String[] args) {
System.out.println(”Hello World!”);
}
}
class FirstProgram {
public static void main(String[] args) {
System.out.println(”Hello World!”);
}
}
“Hello World!”ダブルクォーテーションで文字列を囲む
この文字列を格納するのに必要なメモリサイズはchar 型のサイズ (16bit) × 文字数
文字列リテラル
char 型変数を複数用意する必要がある⇒配列, String クラス等,後述
特殊文字 (エスケープシーケンス )
エスケープシーケンス 機能
\b バックスペース
\t タブ文字
\n 改行
\f フォームフィード
\r 復帰
\” ダブルクオーテーション
\’ シングルクオーテーション
\\ 「¥」の文字そのもの
\0 8 進数で表した文字コード( 0 は 0 ~ 7 までの数字 1 文字)
\00 8 進数で表した文字コード( 00 は 0 ~ 7 までの数字 2 文字)
\T00 8 進数で表した文字コード( T は 0 ~ 3 までの数字 1 文字, 00 は 0 ~ 7までの数字 2 文字≡1 byte 分256文字の 8 進数表現)
\uXXXX ユニコード文字( XXXX は4桁の16進数表記)
クイズ:
”\\” は” \” そのものを表す下の四角で囲った文を出力する Java プログラムを書きなさい。
class AP0301 {
public static void main(String[] args) {
System.out.println("\"\\\\\" は \"\\\" そのものを表す " );
}
}
class AP0301 {
public static void main(String[] args) {
System.out.println("\"\\\\\" は \"\\\" そのものを表す " );
}
}
解答例: AP0301.java
(“や \ は半角文字とする)
まとめ
• 変数 (variable)
• 型 (type)
• 変数の宣言と初期化• Java の演算子 (operator)
• 型変換 (cast)