Flutter Tips
【Java超初心者編 #5】変数なんて簡単だ!
涼羽02
先生、こんにちは! 今日も今日とて、前回の復習はバッチリです。

前回の記事はこちら↓↓↓

涼羽01
今回もよろしくお願いします!
先生01
姫野さんはいつも元気ですね。よろしくお願いします。
涼羽28
バイトの面接も元気のおかげで受かりました。元気だけが取り柄です!
先生02
そうでしたか。そんな元気で天才の姫野さんに、今回は「変数」の話をしたいと思います。

変数とは

涼羽21
へんすう……ですか……。何だか数学のほろ苦い思い出が蘇ります……。
先生01
プログラミングにおける変数は、数学とは少し違うイメージを持っていただけるとよいかと思います。例えばコンビニのレジのシステム。
涼羽11
コンビニのレジ、週4でいじってます!
先生01
(コンビニでバイトしてるんだ……)
コンビニでは、色々なお客さんが色々なものを買いますね。
涼羽05
そうですねー。常連さんに10円する棒状のお菓子を3つだけ買ってく人がいます。絶対30円ぴったり出してくれるので楽なんですけど、それも変数なんですか?
先生04
1つ10円のお菓子を3つで30円、30円支払ったのでお釣りは0円。
涼羽04
あとは、週2くらいで100円のコーヒーと150円の菓子パンを買う人もいますね。いつも300円払うんですよ。ちゃんとぴったり用意しておけばいいのに。そんなに50円が欲しいんでしょうか?
先生04
1杯100円のコーヒーを1杯、1つ150円の菓子パンを1つ。合計250円。300円支払ったので、お釣りは50円。
涼羽06
……ええと、先生、さっきからレジの物真似ですか?
先生02
変数の話をしていますよ。レジは様々な品物、数量、価格に対応していますが、それぞれの状況に合わせた会計をするためには、「お菓子1つ10円」「(10円のお菓子を)3つ買う」「30円支払った」「お釣りは0円」「コーヒー1杯100円」「(100円のコーヒーを)1つ買う」「菓子パン1つ150円」「(150円の菓子パンを)1つ買う」「300円支払った」「お釣りは50円」などの細かな情報が必要になります。
涼羽03
確かに。
先生01
その細かな情報が変数なのです。
涼羽04
なるほど……!?
先生01
身近な例をもう一つ挙げると、お天気アプリがありますね。
涼羽02
今日の東京の天気は晴れです、気温は15度です、みたいなやつですね! わたしも毎日チェックしてます。
先生02
日付、場所、天気、気温が変数ですね。姫野さんの挙げた例は、変数と文字を組み合わせて、「【日付の変数】の【場所の変数】の天気は【天気の変数】です。気温は【気温の変数】です」のように表示されています。
涼羽26
言われてみれば。天気も気温も、いつも同じじゃないですもんね。変数のこと、ちょっとだけわかってきたかもしれません。
先生01
それでは、話の本題に入っていきましょう。プログラミングにおける変数は、データを入れたり取り出したりする器、箱のようなものです。変数を決めるイメージは、箱の中に入れるデータの種類と箱の名前を決めるイメージです。
涼羽01
変数を決めるということは、データの種類と箱の名前を決めるということ……。
先生01
はい。データの種類のことを「型」といいます
現時点で知っておくべき型
・int型(整数型)
・boolean型(真偽型)
・String型(文字列型)
涼羽11
int型の箱には整数を入れるってことですね!
先生01
はい。そして「型 変数;」とすることで、変数を作成することができます。これを「変数の宣言」と呼びます。
涼羽23
「わたしこれからこの変数を使います!!」って宣言するってことですかね。へえ……。変数は好きな名前にしていいんですか?
先生02
変数の命名にはふつう半角英数字を用います大文字と小文字は区別されます数字から始めることはできません
涼羽09
int nenrei; とか、String namae; みたいな感じですか?
先生01
ローマ字ですと少し読みにくいので、ageやnameなど、基本的には英語の名詞を用いた分かりやすい名前を付けるといいでしょう。ただし、英単語があまりにもわかりにくい場合(一般的でない用語など)は、あえてローマ字表記にすることもあります。
涼羽10
英語かあ……。英語も数学とどっこいどっこいだったなあ。変数の名前は2単語以上にしてもいいんですか?
先生02
はい。2単語以上にする際は、fullNameやfamilyNameのように、2単語目以降の単語の先頭を大文字にします。
涼羽01
なるほど、読みやすい。単語は小文字スタートにするわけですね。
先生01
途中で登場する大文字がラクダのコブに見えることから、この慣習は「キャメルケース」と呼ばれています。
涼羽11
それはおもしろいですね!
変数の宣言について
int age; →int型のageという名前の変数を宣言
String name; →String型のnameという名前の変数を宣言
boolean isDone; →boolean型のisDoneという名前の変数を宣言
涼羽09
あれ? boolean型は文っぽくなってますね……。
先生02
boolean型は、「それが○○されたかどうか」「○○済みかどうか」などを表すため、過去分詞や形容詞を用いて変数の命名を行なうこともよくあります。
boolean型の変数の宣言によく使われる変数名
boolean isStarted;
boolean isPlayed;
boolean isRead;
boolean isWritten;
boolean isPlayable;
boolean isCloneable;
涼羽15
何か、ひとつずつ宣言するの、結構めんど……大変ですね。
先生01
実は、String name, tel, address, email; のように、カンマで区切ることで、複数の同じ型の変数を同時に宣言することができます。複数行に分けて書いても構いません。
涼羽01
それならよかった! 他に注意することってありますか?
先生02
同じスコープ(ブロックとも。{から}までの区間)では、型が同じであろうとなかろうと、同じ名前の変数は1つしか作れません。例えば、
int age;
String age;
boolean age;
int age;
のように変数を宣言することはできません。ふつう年齢を真偽型で表すことはありませんが。
涼羽23
真実がいつも1つであるように、同じ変数はいつも1つなんですね!
先生06
そ、そうですね……。

データの種類を「型」といいます。型には、int型(整数型)、boolean型(真偽型)、String型(文字列型)などがあります。
「型 変数;」と宣言することで変数を作成できます(例 int age;)。変数名は分かりやすい名前にしましょう。
同じ型の変数なら、String name, tel, address, email; のように、カンマを用いて複数の変数を同時に宣言できます。

代入とは

先生01
次は代入について説明します。
涼羽12
だいにゅう……数学でさんざんやらされた記憶が……。
先生02
代入には数学と同様に「=」を用います。しかし、プログラミングの代入は、数学とは全く異なります。
涼羽16
そうなんですね! 「A = B」とか言ってるけど、実はAとBは同じではない……みたいな?
先生01
その通りです。「A = B」は、「値Bを変数Aに書き込む(すでにデータが存在する場合は上書きする)」と翻訳できます。左から右ではなく、「右から左」です。「A←B」というイメージを持ってくださいね。
涼羽27
代入は右から左……覚えました!
先生02
宣言と代入を行なうと、次のようになります。
int age;
age = 30;
System.out.println(age);
実行結果30

 

boolean isDone;
isDone = true;
System.out.println(isDone);
System.out.println(!isDone);
実行結果true
false

 

String name;
name = "福沢"
System.out.println(name);
実行結果福沢
涼羽09
これって、public static void main(String[] args){ }の中に書くってことで合ってますか?
先生01
はい。今後、特に理由がない限りは簡略化して表記することとします。
涼羽02
こっちのほうが見やすいですしね。わかりました!

public static void mainについての記事はこちら↓↓↓

先生01
さて、話を変数に戻します。変数を扱う際は、まず変数を宣言したうえで、「=」を用いて任意の値を代入します。変数を宣言しないと代入はできません。
涼羽09
なるほど……。宣言と代入って一緒にできるんですか?
先生02
はい。宣言時の代入のことを「初期化」といいます。
int age = 30;
System.out.println(age);
実行結果30
String familyName, givenName;
familyName = "福沢";
givenName = "諭吉";
System.out.println(familyName + givenName);
実行結果福沢諭吉
涼羽11
変数、思ってたより簡単ですね!
先生01
では、ここで問題です。以下のプログラムはどのような実行結果になると思いますか?
int age;
age = "30";
age = true;
涼羽17
ええと……。状況としては、まずint型で変数ageを宣言して、そのあとString型やboolean型のものを代入してますよね。つまり、intの種類の箱の中に、intじゃないデータを入れてる。これ、Eclipseでちゃんと実行できるんでしょうか……?
先生02
お察しの通りです。原則として、型が異なる場合は変数の代入ができないので、注意しましょう。Eclipseでは「型の不一致」としてエラーが出ます。
涼羽02
わかりました!
先生01
では、int型の変数ageに数値を代入したうえで、それらを文字列として表示させるにはどのようにすればよいと思いますか?
涼羽09
そんなことできるんですか?
先生01
はい、可能です。まずは以下の実行結果を予想してみましょう。
int age1, age2;
age1 = 30;
age2 = 40;
System.out.println(age1 + "歳と" + age2 + "歳");
涼羽26
それなら簡単です! 「30歳と40歳」ですよね!
実行結果30歳と40歳
先生02
この時、age1とage2は文字列扱いされていますね。
涼羽24
確かに! 途中に文字列があると、数値も文字列になるんでした!
先生02
その通りです。そのルールを利用すれば、int型の変数ageに数値を代入し、そのうえで文字列として表示させることができます。
涼羽23
途中で文字列を入れる……。前にやった空文字列を使って、
System.out.println(age1 + "" + age2);
でどうでしょうか!
System.out.println(age1 + "" + age2);
実行結果3040
先生05
正解です。
涼羽28
やったー!
先生01
では、次の話に進みましょう。
涼羽27
どんと来いです!
先生02
以下のプログラムの実行結果はどうなると思いますか?
int age;
age = 10;
age = 50;
System.out.println(age);
涼羽20
2回も代入してますね……。どっちを優先すればいいんでしょうか?
先生01
いい質問です。変数Aにある数Bを代入した時、それまで変数Aにどんな値が入っていても、変数Aの値はBになります。新しいものに上書きされるのです。
涼羽25
なるほど! ってことは、実行結果は後から代入したほうの「50」ですね!
実行結果50
先生02
その通りです。int型のageという器の中には元々10が入っていた。けれど50に上書きされた。新たな代入のイメージは「上書き」です。このことを念頭に置いて、今度は以下のプログラムの実行結果を予想してみましょう。
int a, b;
a = 100;
b = 200;
System.out.println(a + b);
涼羽02
これは文句なしの300です!
先生01
そうですね、100+200を計算しました。では、次はどうでしょう?
int a, b;
a = 100;
b = 200;
System.out.println(a + b);
a = 50;
System.out.println(a + b);
涼羽03
1つ目は300でいいとして、2つ目は……。途中でaが50に変わったので、50+200で250でしょうか?
先生02
はい。初め変数aには100が代入されていたため、4行目では100+200を計算しました。しかし、5行目で変数aに50が新たに代入されたため、6行目では50+200を計算しました。
涼羽02
ですよね! わたしはまだまだいけますよ!
先生01
次はどうでしょうか?
int a, b;
a = 100;
b = 200;
System.out.println(a + b);
a = 50;
System.out.println(a + b);
a = b;
System.out.println(a + b);
涼羽21
300と250と……問題は3つ目ですよね……。「a = b」をどうしたものか。
先生04
「a = b」とは、どのような意味でしょうか?
涼羽02
それならわかります。代入は右から左。「bをaに代入します」ですよね。
先生04
ということは、何を何に代入しましたか?
涼羽24
bは200だから、200をaに代入したんですね! ってことは、200+200で400でしょうか……?
先生05
ご名答。さすがは天才の姫野さんですね。
涼羽18
(先生、もしかして「天才の姫野さん」って言葉、気に入ってる……?)
先生01
では、追加でもう1問。
int a, b;
a = 100;
b = 200;
System.out.println(a + b);
a = 50;
System.out.println(a + b);
a = b + 30;
System.out.println(a + b);
先生02
実行結果を予想してみてください。
涼羽08
300と250はいい……問題は……「a = b + 30」だ……!
先生10
そ、そうですね。
涼羽09
さっきと同じように考えればいいんですよね。代入は右から左。「aにb+30を代入します」だから、aは230になる。ええと、確認なんですけど、bの中身って何か変わりましたか?
先生02
非常にいい質問ですね。aには変更が加えられましたが、bの中身には変更が加えられていないことに注意しなければなりません。
涼羽26
読みが当たった! そうすると、230+200を計算すればいいから、答えは430です!
実行結果300
250
430
涼羽28
やったー! やっぱりわたしって天才!
先生04
(今回はそっとしておこう……)
ここまではint型の変数の代入について見てきましたが、String型も少しだけ見ておきましょう。次のプログラムの実行結果はどうなると思いますか?
String familyName, givenName, fullName;
familyName = "福沢";
givenName = "諭吉";
fullName = familyName + givenName;
System.out.println(familyName + givenName);
System.out.println(fullName);
涼羽11
何かカッコいいプログラムになりましたね!
先生01
変数名のご利用は計画的に。
涼羽21
その変数名のおかげで、名字と名前を組み合わせて「福沢諭吉」を表示させたいんだなーっていうのは何となくわかるんですが……。
実行結果福沢諭吉
福沢諭吉
先生02
実行結果については仰る通りです。なぜそうなるのか考えてみましょう。
涼羽01
まず3つの変数を宣言して、その次にそれぞれ文字列を代入してますよね。で、fullNameにはfamilyNameとgivenNameの文字列結合をした「福沢諭吉」が代入されてます。
先生05
その通りです。
涼羽28
代入、結構わかってきました!

値Bを変数Aに上書きすることを代入といい、「A = B」と表記します。代入する向きは常に右から左(A←B)です。
変数Aに値Bを代入する時、それまで変数Aにどのような値が入っていても、変数Aの値は新しく代入するBに上書きされます。
代入の際はまず変数を宣言する必要があります。宣言と代入を同時に行うことを「初期化」といいます。
原則として、変数の型と異なる型の値を代入することはできません。例えば、int型の変数に文字列や真偽値を代入することはできません。

自己代入とは

先生02
次は「自己代入」の話をしましょう。
涼羽03
じこだいにゅう。
先生01
変数を今までと異なる値に上書きせずに、これまでの値を保持したまま何らかの計算をして、これまでの値に変更を加えることです。
涼羽16
んー。なるほどわからん。
先生01
例を挙げます。
int a;
a = 100;
a = a + 30;
System.out.println(a);
実行結果130
先生01
姫野さん、いかがでしょうか?
涼羽26
「a = a + 30」は「a+30を変数aに代入します」ですね。……あ、だから100+30で130になったんですね! 自己代入、意外と簡単だった。
涼羽09
でもこれ、そんなに使い道あるんでしょうか?
先生02
先程、全く別のものに上書きする代入を扱いましたね。僕の体感では、先程の代入よりもこちらの自己代入のほうがプログラミングではよく出てきます。
涼羽10
そうなんですね。例えばどういう時に使えるんでしょう?
先生01
コンビニで会計をする時、例えば「コーラ150円」「お弁当600円」「袋3円」の順番でバーコードを読み取るとします。
涼羽02
お弁当とコーラ、買ってく人いますね。わたしはお弁当だったらお茶派です。あと、最後の袋3円、地味に大事です。時々忘れそうになります。
先生01
(僕はココナッツミルク派、とは言わないでおこう)
この時、全く別のものに上書きする代入を用いると、合計金額はどうなるでしょう?
int total;
total = 150; //コーラ
total = 600; //お弁当
total = 3; //袋
System.out.println(total);
実行結果3
涼羽19
最後に代入したものに上書きするから……え、3円!?
先生04
そうです。しかしそれでは困ってしまいますよね。
涼羽08
コーラとお弁当……どこ行った……?
先生01
そこで自己代入を用います。自己代入ならば、今までに足した数値が消えないように計算することができるため、コーラ、お弁当、袋の合計をきちんと出せるのです。
涼羽03
なるほど。バーコードが1つずつ商品を読み取ってくイメージで……こんな感じでしょうか?
int total = 0; //最初は合計ゼロ円
total = total + 150;
total = total + 600;
total = total + 3;
System.out.println(total);
実行結果753
先生05
実際は商品の情報も変数なのでもう少し複雑になりますが、姫野さんは自己代入を上手に使いこなせていますね。
涼羽27
何といっても天才の姫野さんですからね!

変数が持つそれまでの値を保持したまま、それまでの値に変更を加えることを、自己代入といいます。自己代入では、例えばa = a + 30 のように、代入する相手の変数(この場合はa)に、同一の変数を含む式(この場合は a + 30)を代入します。
単なる代入では、代入するたびに値が上書きされてしまいます。一方、自己代入では、今までに計算した数値が消えないように計算することができます

変数の応用

先生05
そんな天才の姫野さんに、今回も問題を用意しました。
涼羽13
ひえー、調子に乗ってごめんなさい!
先生01
与えられた条件を満たす計算式を正しく出力する問題です。
①「100+200=300です」を全て文字列として出力する
②「100+200=」までは文字列として出力し、「300」は計算して出力する
③「100+200=」までは文字列として出力し、「300」は変数を用いて計算して出力する
④変数と文字列を用いて「100+200=300です」を出力する
⑤変数と文字列を用いて「200-100=100です」を出力する
⑥変数と文字列を用いて「-10×20=-200です」を出力する
涼羽25
①はダブルクォーテーションで囲めばいいですよね。②は……あ、計算の優先順位が高い () を使うやつか!
System.out.println("100+200=300です");
System.out.println("100+200=" + (100 + 200) + "です");
実行結果100+200=300です
100+200=300です
涼羽08
(ドヤァ)
先生02
ここまでは前回の復習ですね。③はどうでしょうか? 変数名はa, bとしましょう。
涼羽21
まずは変数を宣言して100と200を代入して……。=の前までは①②と変えずに、=の後ろを変数にして……。
int a, b;
a = 100;
b = 200;
System.out.println("100+200=" + a + b + "です");
実行結果100+200=100200です
涼羽17
あれー?
先生04
「a + b」よりも前に文字列があるので、「a + b」の部分が文字列結合になってしまっていますね。この問題を解決するためにはどうすればいいでしょうか?
涼羽24
……あ! さっき②でやったみたいに、() を使うとか?
先生01
思いついたら、実行してみましょう。
int a, b;
a = 100;
b = 200;
System.out.println("100+200=" + (a + b) + "です");
実行結果100+200=300です
涼羽28
やった、できましたー!
先生01
いい調子です。次は④ですね。なるべく変数だけを用いて「100+200=300です」を表示させます。
涼羽21
③の「100」と「200」を変数に直せばいいのかな? 「+」「=」「です」は文字列だから……。
int a, b;
a = 100;
b = 200;
System.out.println(a + "+" + b + "=" + (a + b) + "です");
実行結果100+200=300です
涼羽27
よし、きたー!
先生05
姫野さん、とても筋がいいですね!
涼羽03
今気付いたんですけど、①から④って、初めは文字列だけだったのをちょっとずつ変えて、最終的には変数にしてますね。何か導かれてる感じがします!
先生01
とても重要な点に気付きましたね。仰る通り、初めから全て変数で考えるのではなく、出力したいものをまずイメージしてから、各所を変数に置き換えていくのがポイントです。
涼羽09
ってことは、⑤と⑥は④をちょっと変えるだけでよかったりしますか?
先生02
思い立ったら、書いて実行です。
涼羽01
はい! まずは⑤の「200-100=100です」から……。
int a, b;
a = 200;
b = 100;
System.out.println(a + "-" + b + "=" + (a - b) + "です");
実行結果200-100=100です
涼羽02
算術演算子の+を-に変えただけなのにちゃんと動いた! すごいですね!
先生05
仰る通りです。正しい式を一度作ってしまえば、変数や式を少し書き換えることで、自由自在に計算させたり表示させたりすることが可能なのです。
涼羽01
プログラミングって感じがして楽しいです!
先生01
では、⑥はどうでしょうか?
涼羽04
「-10×20=-200です」だから、掛け算にするだけじゃなくて変数もいじらなくちゃ……。
int a, b;
a = -10;
b = 20;
System.out.println(a + "×" + b + "=" + (a * b) + "です");
実行結果-10×20=-200です
先生05
素晴らしいです。
涼羽21
今日のわたし、調子よすぎ……? 才能に溢れる自分がいっそ恐ろしい……。
先生06
そ、そうですね……。
涼羽18
(予想外に引かれた……)
先生01
最後は、実行結果を考える問題です。
boolean a, b;
a = true;
b = false;
System.out.println(a && b);
先生02
論理演算の復習も兼ねています。才能に溢れる姫野さんの見解をお聞かせください。
涼羽23
ええと……。「a && b」に変数を代入するとtrue && false になるから、「「true・false」は両方ともtrueですか」になりますよね。実際はそうじゃないから、実行結果はfalseです!
実行結果false
先生02
よくできました。int型、String型、boolean型の変数を使いこなしていきましょう。
涼羽27
はい、頑張ります!

今回のまとめ

①変数とは
・データの種類を「型」という(int型、boolean型、String型など)。
・int age; のように、「型 変数;」と宣言することで変数を作成できる。変数は分かりやすい名前にすること。
・同じ型の変数なら、String name, tel, address, email; のように、カンマを用いて複数の変数を同時に宣言できる。

②代入とは
・値Bを変数Aに上書きすることを代入といい、「A = B」と表記する。代入する向きは常に右から左。「A←B」のイメージを持つこと。
変数Aに値Bを代入する際、それまで変数Aにどのような値が入っていても、変数Aの値は新しく代入するBに上書きされる
・原則として、変数の型と異なる型の値を代入することはできない。

③自己代入とは
・変数が持つそれまでの値を保持したまま、それまでの値に変更を加えることを、「自己代入」という。例えばa = a + 30 のようなもの。
・単なる代入では代入するたびに値が上書きされるが、自己代入では今までに計算した数値が消えないようにすることができる

④変数を扱う際のポイント
・初めから全て変数で考えるのではなく、出力したいものをまずイメージしてから、各所を変数に置き換えていくとよい。

おすすめの記事