独学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ウィルス作れそう、やらんけど。てか既にありそう)
第三章、終
独学Java 一日目
この記事は私がペンを握ってノートに書く行為が嫌いであるために独学でJavaを勉強するにあたってノート替わりとして使用するものである。なおプログラミングに関しては全くのド素人である。開始日は2020 9/22
使用している学習本は「すっきりわかるJava入門第三版」
ノート
・プログラミング開発のステップは1ソースコードの作成2コンパイル3実行
ソースコードの作成 Javaの定める文法に従いPCに命令を記述。人が読める状態のプログラムをソースコード、またはソースという。ソースを書き込んだファイルのことをソースファイルといい、拡張子は「.java」にする決まりになっている。
コンパイル ソースファイルをクラスファイルに変換する処理のこと。クラスファイルの拡張子は「.class」を使い、ソースコードの各命令をPCが実行しやすいように変換したバイトコードが詰まっている。バイトコードは1と0が複雑に並んでいるもの(二進数だろうか)。なおコンパイルはコンパイラというソフトウェアを用いるがこの際にソースコードの文法チェックも行われる。ここで誤りがあるとエラーをはきだす。
実行 バイトコードではまだ実行には移せないためインタプリタと呼ばれるソフトウェアにバイトコードの変換と実行を依頼する。インタプリタは内部にJVM(Java Virtal Machine)という仕組みを持っており、クラスファイル内のバイトコードを読み込みながら、CPUが解釈できるマシンコードに翻訳し、CPUに送って処理実行される。
・次の開発環境については使用している本が提供してくれているサービスの説明が主であるため省略
・プログラムの骨格
Javaのソースには{…}が多く使われる。波かっこに囲まれた部分をブロックという。外側をクラスブロック、内側をメソッドブロックと呼びJavaのソースは必ずこれらのブロックによる二重構造を持つ。主に記述するのはメソッドブロック(内側)であり外側はあまり変わらないお決まりのパターン。
ただしお決まりのパターンとはいっても全く同じではなく「public class」の直後にこのプログラムの名前を指定する単語を書く。正式にはクラス名という。
・ソースファイルの名前
ソースファイルを保存する際、ファイル名は「クラス名.java」でなくてはならない
例:public class MyDiary{..
public static void main (String args) {
︙
}
}
この場合ファイル名はMyDiary.javaになる
・Javaプログラムの書き始め方
1どのようなプログラムを作りたいか考え
2プログラムの名前を決める(クラス名)
3「クラス名.java」でファイルを作り
4ソースの外側を記述
5ソースの内側に命令を書いていく
意識すべき点
・正確に記述 …英数字は基本半角、大文字小文字の違いも意識。o、O 0 l、1 ;、: .、, などの違い、他にもカッコや引用符の種類に気を付ける。
public static void main(String args)は一字一句間違えずにすらすらと書けるように。
・上から下ではなく外から内へ …ブロックの閉じ忘れによるエラーは「上から下へ書く」という意識がもたらしやすいエラー。ブロックを開いたらすぐ閉じる(カッコを開いたら中身を書く前に閉じる)、それから中身を書くという「外から内」の意識を定着させる
・読みやすいコードを記述する …文法的には誤りがなくても「人間が読みにくい乱雑なコード」、「複雑すぎて理解に時間がかかるコード」は修正や改良が難しくなる。誰が見てもわかりやすいようインデントとコメントを活用する。
「インデント」 ブロックの開始と終了で正確に字下げを行い、多重構造の見通しをよくする。この字下げをインデントと呼ぶ。TABキーで行うのが一般的
改行なし↓
public class main {public static void main(String args) {System.out.println("フォーマットの実験");}}
改行あり↓
public class main {
public static void main(String args) {
System.out.println("フォーマットの実験");
}
}
なおインデントはむやみやたらといれていいものではない。誤ったインデントは構造の読み間違えや致命的エラーにもつながる。
「コメント」 ソースコード中に書き込んだ解説文のこと。コンパイルと実行のときには無視される。
(ここからソースコードは提供してくれるサービスに書けばいいやんと気づき、ソースコードは気が向いたときにしかこのノートには書かなくなる)
・Mainメソッドの中身
ソースコードの二行目に「main」の表記が出てくることからこの部分はMainメソッドと呼ぶ。Mainメソッドには文を順に書いていくが文末セミコロンをつけ忘れがちなので注意。Javaには多くの種類の文が存在するが、三種類に分類して考えるとわかりやすい
1変数宣言の文(例 int version;) 2計算の文(例 version=1+5;) 3命令実行の文(例 System.out.println("ver"+version))
・変数宣言の文とは
「新たな変数を準備せよ」とPCに指示する文。変数とはデータを格納するためにPC内部に準備する箱のようなもので、数値や文字列などプログラムが扱うさまざまな情報を入れたり取り出したりできる。変数に値を入れることを代入、取り出すことを取得という。文は「型 変数名;」になっており、型とは「変数に入れることができるデータの種類」のことでintであれば整数を表す。この型の変数ageには整数しか入れることはできない。
・変数の名前
変数宣言の際に変数に名前を付ける必要があり、それらの名前として使える文字数字の並びを識別子と呼ぶ。名前は基本開発者の自由だがいくつかルールや習慣がある
■禁止されている単語を使ってはならない
「そもそも名前として使ってはならない単語」とされてる予約語が約50存在する。intやvoid、public、staticなどは予約語であり、変数名としては利用できない。(Java内で既に使い道が決まってる単語は使えないというイメージだろう)
■すでに利用している変数名を再度使ってはならない
区別つかなくなるからダブるのは禁止
■大文字、小文字、全角、半角の違いは区別される
これらの違いはダブり判定にはならない
■小文字で始まるわかりやすい名前を付けることが望ましい
習慣的に変数には小文字で始まる名詞形の名前をつけたり、複数の単語をつなげて変数名にする場合、二つ目以降の単語の先頭は大文字にする。まあかっこつけて奇抜な名前をつけるのではなく普通にしてろということだろう。
・データ型
プログラムで扱えるデータの種類のことをデータ型、または単に型という。現段階では9つを覚えればよい
整数 byte(とても小さな整数) short(小さな整数) int(普通の整数) long(大きな整数)
少数 float(少しあいまいでもよい少数) double(普通の少数)
真偽値 boolean(真か偽か)
文字 char(一つの文字)
文字列 String(文字の並び)
整数
それぞれの種類では消費するメモリ量が異なる。ただ基本的にはIntのほうが高速で処理できるPCが多いため通常はIntを使えば問題はない
少数
FloatやDoubleは「3.14」や「-15.2」といった小数部を含む数値を代入するための型。PC内部では少数を「浮動小数点」という形式で管理していることから浮動小数点型と総称されることもある。Doubleのほうがより厳密に計算できるため少数を扱う場合特別な事情がない限りはDouble型を使用する。また、浮動小数点方式には真に厳密な計算ができないという弱点があるため金額の計算などには使ってはならない。
真偽値
Boolean型は二者択一の情報を代入するための型。肯定的情報のTrue、否定的情報のFalseのどちらかの値のみ代入できる。
一文字だけ格納できるChar型、文字列を格納できるString型
Char型は全角半角を問わず「一文字」を代入できる型で、String型は文字列を代入できる型。
・定数の利用
既に値が入っている変数に代入をすると、古い値は消滅し、新しい内容に内容が書き換わる、変数の上書きというのができる。
しかし絶対に上書きしたくない変数があった場合、変数宣言前にFinalという記述を書き加えると書き換えを防止できる。Finalつきで宣言された変数を定数と呼ぶ。
final 型 定数名=初期値;
第一章、終