独学Java Day2~Day5

Day2

9/23

 

ノート

 

・計算の文

四則演算のみならず、変数に値を代入することも計算の一種。

式「b=a+5」を分解するとaやb、値の5、+や̠ーの計算記号に分けることができる。Javaを含む多くのプログラミング言語はa、b、5をオペランド、+やーを演算子と呼ぶ。簡単な式でも複雑な式でも全ての式はこの二つの要素のみで構成されている。

 

オペランド

オペランドの中でも数字5や文字列「hello,world」などソースコードに記述されてる具体的な値をリテラルと呼ぶ。そしてそれぞれのリテラルはデータ型を持っている。’A’と”A”は一見同じに見えるが引用符の違いにより別のデータ型として扱われるので注意(前者がChar型、後者がString型)

整数リテラルの先頭に0xをつけると16進数、0を付けると8進数、0bを付けると二進数として解釈される。例 「int a=0x11; int b=0b0011」であればaには17、bには3が代入される。

 

エスケープシーケンス

String型やChar型にリテラルを記述する際に、ときどき用いられるのがエスケープシーケンスと呼ばれる特殊な文字。これは次のような「¥記号と、それに続く一文字」の合計2文字による記述方法で、その2文字で特殊な一文字を表現する。

¥”  二重引用符記号(”)

¥’  引用符記号(’)

¥¥  円記号(¥)

¥n  改行(制御文字)

Javaは二つの二重引用符に囲まれた部分を文字列リテラルとみなすため「”」を文中に表現しようとしても普通にはできない(例 ”これが二重引用符(")です”)。そこでエスケープシーケンスを用い表現できるようにする(例 "これが二重引用符(¥")です")

(docojavaでこれを試してみたところ¥マークが半角で\になり、このマークで正常にコンパイルされた)

 

・評価の仕組み

Javaが式に従って計算処理することを式の評価という。三つの単純な原則に従いながら、式の一部から少しずつ部分的に処理し、最後に式全体の計算処理が完了する。

1評価結果への置換の原則 …演算子は周囲のオペランドの情報を使って計算を行い、それらオペランドを巻き込んで結果に化ける(置き換わる)

2優先順位の原則 …式に演算子が複数ある場合は、Javaで定められた優先順位の高い演算子から順に評価される。Javaには多く演算子がある中で、それらには15段階の優先順位が定められている。

3結合規則の原則 …式の中に同じ優先順位グループに属する演算子が複数ある場合、演算子ごとに決められた「方向」から順に評価される。+演算子であれば左から右、=演算子は右から左へ評価されるといった具合ですべての演算子は左か右か、どちらかから評価するという「方向」が結合規則として定められている。

 

演算子

・算術演算子

左右の数値オペランドを使って四則計算を行うための演算子は、算術演算子と総称される。

+ 加算 優先順位 中(5) 評価の方向 左→右

- 減算 優先順位 中(5) 評価の方向 左→右

* 乗算 優先順位 高(4) 評価の方向 左→右

/ 除算 優先順位 高(4) 評価の方向 左→右

% 剰余 優先順位 高(4) 評価の方向 左→右

なお除算演算子は整数同士の割り算に用いると「商」を計算する。

・文字列結合演算子

「"こん+にちは"」のように+記号を用いて左右の文字列オペランドを結合して一つの文字列にする演算子

・代入演算子

オペランドの内容を左オペランドの変数に代入する演算子。演算や結合を行いながら代入を行うものもある。

・インクリメント、デクリメント演算子

変数に内容を1だけ増やしたり減らしたりする場合に使用する演算子。++であれば1増え、--であれば1減る。この演算子は左右両方にはオペランドを持たず、一つしかオペランドをもたない演算子を単項演算子と総称される。

なお「++a+50」と「b+++50」では微妙な違いが生じる。変数a、bの初期値は10であるとき、前者は変数aが1増え、それに50を加えたものが表示されるため61と表記されるが、後者は変数bに50を加えたものが画面に表示され、変数bの値が1増えるため60と表示される。インクリメント、デクリメント演算子が前か後ろかで1増えるタイミングが変わるため、他の演算子と併用するとバグの原因になる。ゆえに特別な理由がなければ単独で使用するよう心掛ける。

 

■型の変換

・三種類の型変換

Javaには評価する過程で自動的に型を変換する仕組みが三つ備わっている

1代入時の自動変換2強制的な型変換3演算時の自動型変換

 

・代入時の型変換

ある型で宣言された変数にはその型の値しか代入できない。例としてはInt型にInt型の整数だけ、String型の変数にはString型の文字列だけしか代入できない。

一日目のノートに記述があるように型には消費するメモリの大小がある。Long型の値はInt型変数にはLong型の数字が大きすぎて入らない場合があり代入できないが、その逆、小さな型の値を大きな型の変数に代入する場合に限って、値が自動的に箱の型に変換されて代入される。

大きな型の値を小さな型の変数に代入することは原則としてエラーが出るがByte型やShort型の変数に数値リテラルを代入できないと困るため「Byte b=3;」のように実害がない範囲でInt型リテラルを代入することは認められている。

Char型は算術演算も型変換も行えるが数値として利用することはほとんどない。

 

・強制的な型変換

通常は大きな型に小さな型の変数に代入することはできないがint age=(int)3.2;といった具合にdouble型リテラルの前に(int)をいれることで強制的な型変換をすることができる。これを指示する演算子をキャスト演算子と呼ぶ。しかしキャスト演算子そのものは乱暴な道具であり、利用にはデータの欠損の不具合といった代償を伴うこともあるので、よほどの限りは使うことはない。

 

・演算時の自動変換

Javaは代入にしても演算にしてもきっちりと型をそろえてから処理される。double d=8.5/2;であれば2を2.0とDouble型に変換して処理されるし、long l=5+2L;であれば5を5LとLong型に変換してから処理される。

文字列を含む演算時でも同様であり肩をそろえてから連結が行われる。String msg="私の年齢は"+23;であれば23がInt型ではなくString型に変換されて連結される。

 

■命令実行の文

Javaが準備してくれている様々な命令を呼び出すことのできる文。System.out.println();がよく見る命令実行の文だろう。また改行せずに画面に文字を表示させたいときは末尾をprint();にするとできる。

 

・大きいほうの数値を代入する命令

int m=Math.max(a,b); これは引数として与えたaとbのうち大きいほうがmに代入される。

 

・文字列を数値に変換する

文字列のままの数値では四則演算はできないため、文字列の10を数値としての10に変換したいときに用いる命令がint n=Integer.parseInt(a);である。

 

・乱数を生み出して代入する命令

int r=new java.util.Random().nextInt(a); このaの部分に1以上の整数を指定して命令を呼び出すと、0以上かつaで指定した数未満のランダムな整数がrに代入される。

 

・キーボードから1行の入力を受け取る命令

一行の文字列の入力を受け付ける String s=new java.util.Scanner(System.in).nextLine();

一つの整数の入力を受け付ける int input=new java.util.Scanner(System.in).nextInt();

これらの文を実行すると、プログラムは一時停止状態になり、利用者がキーボードから文字を入力できるようになる。そして利用者が入力の後、エンターキーをおすとその内容が変数inputに代入される。

 

二章、終

 

🔴プログラムの流れ

■代表的な制御構文

文を実行させる順番のことを制御構文(または制御フロー)といい、代表的なものとして順次、分岐、繰り返しの三つがある。構造化定理という順次、分岐、繰り返しの三つの制御構造を組み合わせれば、どんなに複雑なプログラムでも作成可能であることが数学的に証明されている。

 

・分岐

 ・ifという命令を使えば分岐を行うことができる

 ・ifの後ろの()内には分岐条件を書く

 ・変数がtrueかどうかのチェックを行うには「==」とイコール記号を二つ使う

 ・分岐条件が成立していたなら、()の直後にあるブロックの中身だけを実行する。

 ・分岐条件が成立していなければ、elseの後ろにあるブロックの中身だけを実行する。

 

・繰り返し

 ・whileという命令を使えば繰り返し制御を行うことができる。

 ・whileの後ろの()内には繰り返しを続ける条件を書く。

 ・繰り返しを続ける条件が成立している限り、何度でも直後のブロックの中身だけが繰り返される。(やってみたらめちゃくちゃ重くなった)

 

■制御構文の構成要素

if文やwhile文のような制御構造を表す文のことを、制御構文という。制御構文は分岐条件や繰り返しを続ける条件を示した式である「条件式」、分岐や繰り返しで実行する一連の文の集まりである「ブロック」、この二つが構成要素である。

 

・ブロック

複数の文をひとまとまりとして扱うもの。ルールが二つある

ルール1 波カッコの省略 …内容が1文しかなければ、波カッコを省略しても構わないというルールがある。が、実際の開発現場では、プログラミングのミスの防止するため、波カッコの省略は推奨されない。

ルール2 ブロック内で宣言した変数の寿命 …ブロックのなかで新たに変数を宣言することができるが、ブロック内で宣言した変数はそのブロックが終わることで消滅する。

「変数が利用可能な場所の範囲」のことをスコープと呼ぶ。

 

■条件式の書き方

・条件式とは

条件式とはif文やwhile文で利用される式の一種で「処理を分岐する条件」や「繰り返しを続ける条件」を表現するためのもの。条件式の中で用いられる「==」や「>」のことを関係演算子と呼ぶ。

sw !=false 変数swがfalseでなかったら・・・

deg-273.15<0 変数degから273.15を引いたものが0未満なら・・。

initial =='雅' 変数initialに入っている文字が「雅」だったなら・・・

関係演算子を使いこういった条件式を考えることができる。

また関係演算子演算子の仲間であるため「評価されて化ける」特性を持つ。関係演算子の場合、真か偽かのどちらかに化ける。故に

・if文とは「条件式の評価結果がtrueなら第一ブロックを、falseなら第二ブロックを実行する」文

・while文とは「条件式の評価結果がtrueなら、ブロックを繰り返し実行する」文。

と捉えられる。

 

・文字列の比較

Javaでは文字列は「==」で比較できないことになっている。文字列の比較をする場合

if(str.equals("夕日")) {... 文字列型の変数.equals(比較相手の文字列) 

という形になる。

 

・論理演算子を用いた複雑な条件式

二つ以上の条件を組み合わせたい場合に論理演算子を使う

&& 意味 かつ(両方の条件が満たされた場合にtrue)

‖  意味 または(どちらか片方の条件さえ満たされればtrue)

if(age>=18 && month==5){... もしageが18以上でかつmonthが5なら…

if(name.equals("斉藤") ‖ name.equals("斎藤")){... もしnameが斉藤または斎藤なら…

なお、もし~でないならばと否定形の条件式を作りたい場合は条件式の前に否定演算子「!」をつける。

if(!(age==10)){... ageが10に等しくないならtrue

!はそれに続く評価式の結果を反転する役割を持つ。(trueの評価が出たときに!があった場合それはfalseになる)

 

■分岐構文のバリエーション

・3種類のif構文

if文にはif else構文、ifのみの構文、if-else if-else構文がある。

if else構文は基本系であり、trueとfalseで別々の処理ができる。一方評価がfalseのときはなにもしないという場合elseを省略できる。これがifのみの構文。そしてもし条件が満たされなかった場合、別の条件で評価したいときは、else ifで始まるブロックをelseの前に挿入したif-else if-else構文を使用する。

if-else if-else構文は一つのif文で3つ以上のルートに分岐できる特徴を持つが次のようなルールがある。

1 else ifブロックは複数記述できるが、ifブロックより後ろ、elseブロックより前にだけ記述できる。

2 最後のelseブロックは、中身が空ならばelseごと省略可能。

 

・switch文による分岐

同じ変数に対して繰り返し比較を行っており、かつ次にあげる二つの条件も満たす場合には、if文をよりスマートなswitch文に書き換えることができる。

1 すべての条件式が「変数==値」や「変数==変数」のように左辺と右辺が一致するかを比較する式になっており、それ以外の「>」や「<」、あるいは「!=」などが使われていない。

2 比較する値が整数(byte型、short型、int型のいずれか)、文字列(String型)または文字(Char型)であり、少数や真偽値ではない。

またswitch文は条件に一致するcaseラベルまで処理をジャンプさせる命令に過ぎないため、break文で明示的に「処理を中断してswitch文を抜ける」という指示がない限り、制御構造の一つである「順次」に従って次のcase文へ処理が進んでしまう。

 

■繰り返し構文のバリエーション

・二種類にwhile文

分岐のif文に3種類あったようにwhileには二種類存在する。通常のwhile文ではブロックを実行する前に条件式を評価する一方、do-while文を使えば、ブロックを実行した後に条件式を評価する。条件式を判定するタイミングが違うため、do-while構文では最低一回はブロックが実行される。

 

・for文による繰り返し

繰り返しの指定方法には「ある条件が成立するまで繰り返す」という方法と「~回繰り返す」という方法があり、後者のような回数指定の繰り返しはfor文をつかうことでよりシンプルなコードになる。for文の基本系は

for(int i=0; i<10; i++){...

この10の部分を別の数字に書き換えればよい。

 

・for文の各部の意味

forに続くカッコの中は、上のようにセミコロンによって区切られた三つの部分(1初期化処理、2繰り返し条件、3繰り返し時処理)から構成されている。

1初期化処理 …forによる繰り返しが始まるにあたり最初に一回だけ実行される文。通常「何週目かのループかを記録しておく変数」と定義する。このような変数をループ変数と呼ぶ。

2繰り返し条件 …ブロックの内容を実行する前に評価され、このループを継続するか否かを判定する条件式。trueであれば{以降のブロックが繰り返し実行される。

3繰り返し時処理 …for文内のブロックを最後まで処理して、}まで到達した

直後に自動的に実行される文。通常は「i++」のようにループ変数の値を1だけ増やす文を書く。

 

・ループ変数

初期化処理の中で宣言する変数はいくつかのポイントを除けば普通の変数である。そしてループ変数には三つのポイントがある

ポイント1 ループ変数の名前は自由 

ポイント2 ブロック内で利用可能 …ブロック内での計算や表示に使える。

ポイント3 ブロック外では利用不可能 …ループ変数はブロック内でのみ有効である。for文を抜けるとループ変数は消失してしまう。

 

・複雑なfor文

ループ変数を2ずつ増やす

for(int i=0; i<10; i+=2){...

ループ変数を10から1まで減らしていく

for(int i=10; i>0; i--){...

ループ変数を初期化しない

for(; i<10; i++){...

繰り返し時の処理を行わない

for(int i=0; i<10;){...

(これらをどういったときに使うのかわからん)

 

■制御構文の応用

・制御構造のネスト

分岐や繰り返しの制御構造は、その中に別の制御構造を含むことができる。「分岐の中に分岐」や「繰り返しの中に分岐」などすることができ、このような多重構造を入れ子やネストという。

 

・繰り返しの中断

for文やwhile文を用いた繰り返しの中で、場合によってはその繰り返しを中断したい時がある。このようのときにJavaではbreak文とcontinue文という二種類の中断方法が用意されている。

break文はbreakを囲んでいる最も内側の繰り返しブロックが即座に中断されるため、「while文やfor文による繰り返しをすぐに中断したい」場合に利用する。一方continue文は「今の周回を中断して、同じ繰り返しの次の周回に進む」場合に使う

 

・無限ループ

強制停止されない限り永久に繰り返しを続ける制御構造のこと。無限ループの作成方法は

1while(true){...処理...}

2for(;;){...処理...}

この二つが一般的である。(一度無限ループ作ってみたけど、めちゃくちゃ重くなった。これ使って悪質なPCウィルス作れそう、やらんけど。てか既にありそう)

 

第三章、終