一番かんたんなJava入門

これからJavaを始めようという人の為の超入門サイトです。丁寧、簡単にこだわった解説なので初心者にぴったりです。

【Java】 for文と配列とスコープ

time 2013/03/10

sponsored link

for文と配列

 for文の使い方はなんとなく掴めましたでしょうか?配列とfor文を組み合わせると非常に効果的な使い方ができます。というよりむしろ、for文というのは配列を回す為にあると言っても過言ではありません。

 この非常に有用な「配列をfor文で回す」という感覚を身につける為に、前々回に配列を使って作ったScoresクラスを改造したいと思います。
 Scoresクラスはこんなのでした。

Scores.java

public class Scores{
     public static void main(String[] args){
          int[] scores = new int[]{80,65,70,95};

          System.out.println("Aさんの点数:" + scores[0] + "点");
          System.out.println("Bさんの点数:" + scores[1] + "点");
          System.out.println("Cさんの点数:" + scores[2] + "点");
          System.out.println("Dさんの点数:" + scores[3] + "点");
     }
}

 「System.out.println(“Aさんの点数:” + scores[0] + “点”);」が4回繰り返されています。ここをfor文を使ってスマートに書き換えましょう。
 前回の2のn乗を計算するプログラムでは「answer = answer * 2;」を繰り返すだけだったのですが、この場合、繰り返しとは言うものの一回一回微妙に違いますよね?

 名前も違うし、scores[ ]の連番も違います。繰り返しの1回目はscores[0]を、2回目はscores[1]を・・、と配列の連番を進めながら繰り返すようにします。

for文で回す?

 まずは名前の方もfor文で回す為に、配列にします。どうせならAさんBさんじゃなくて、青木さんと飯田さんと上田さんと江藤さんにしておきます。別に誰でもいいんですが。。

Scores.java

public class Scores{
     public static void main(String[] args){
          String[] names = new String[]{"青木","飯田","上田","江藤"};
          int[] scores = new int[]{80,65,70,95};

          System.out.println(names[0] + "さんの点数:" + scores[0] + "点");
          System.out.println(names[1] + "さんの点数:" + scores[1] + "点");
          System.out.println(names[2] + "さんの点数:" + scores[2] + "点");
          System.out.println(names[3] + "さんの点数:" + scores[3] + "点");
     }
}

 さあ、これをfor文で書き換えると、

Scores.java

public class Scores{
     public static void main(String[] args){
          String[] names = new String[]{"青木","飯田","上田","江藤"};
          int[] scores = new int[]{80,65,70,95};

          for(int i=0; i< names.length; i++){
               System.out.println(names[i] + "さんの点数:" + scores[i] + "点");
          }
     }
}

こうなります。

 for文の( )の中の初期設定パートで宣言・初期化した「i」を実行文の中でも使うことで、ブロック内実行の1回目は配列の通し番号0番、2回目は通し番号1番・・、と言う風に配列を回しながら繰返しを実行できるわけです。

 それとfor文の( )の中の実行条件のパートが「i < names.length」こんなことになってますが、

配列名.length

で、その配列の要素数を返します(「返す」というのは「評価する」と同じことで、その値に置き換わるというようなニュアンスです)。

 つまり、

names.length

は、配列namesの要素数を返すので、「4」に置き換わります。そんなややこしい書き方しなくても「4」と書く方が早いようにも思いますが、配列を回す時は絶対「.length」を使うようにした方がいいです。

 これで配列namesと配列scoresを通し番号0番から3番まで一つづつ進めながら4回繰り返して実行するfor文になりました。(「names.length」と「scores.length」が両方4なので動作自体はこれで問題ないですが、例としてはあまりよくなかったです申し訳ない・・。)

 この配列を回す書き方を見ると、for文の繰り返しの基本形が、

for(int i=1; i<=5; i++)

ではなく、

for(int i=0; i<5; i++)

にするのかよく分かるのではないでしょうか?iを1から始めてしまうと、配列の通し番号も1から始めてしまうことになりますからね。

for文の入れ子とスコープ

 最後にちょっとした応用問題。

 for文の中にfor文が入っているやつです。配列は使ってないので今回の内容とは少しズレた問題かも知れませんが、ここまでの入門講座の内容をちゃんと理解できていたら、絶対読めるはずです。

 さてこのプログラムを実行すると、何が出力されるでしょうか??ポイントは入れ子になっているfor文のブロック(どこを繰り返すのか?)をよく見ることと、ころころ変わっていく「i」と「j」の値を常に追いかけて把握しておくことです。「i」が1、「j」が1とかメモしながら読んだらよく分かると思います。あと、変数aはStringですのでそこのところ注意して読んで下さい。

ForInFor.java

public class ForInFor{
     public static void main(String[] args){
          for(int i=1; i<=9; i++){
               String a = "";
               for(int j=1; j<=9; j++){
                    a += i * j + " ";
               }
               System.out.println(a);
          }
     }
}

 ちょっとややこしいですが、分かりますでしょうか?

「a += i * j + ” “」は、
「a = a + (i * j + ” “)」の省略形ですよ。「i * j」が数値として計算されてから文字列に変換されて連結されます。ちなみにi*jの後に足している「” “」これはスペースです。

 答えが分かったらぜひ、実行して答え合わせをしてみてください。
 このプログラムを読めた人は、次のを見て下さい。変数aの宣言と初期化「String a = “”;」の位置が、for文のブロックの中から外に変わりました。これだと思ったように出力されません。

ForInFor.java

public class ForInFor{
     public static void main(String[] args){
          String a = "";
          for(int i=1; i<=9; i++){

               for(int j=1; j<=9; j++){
                    a += i * j + " ";
               }
               System.out.println(a);
          }
     }
}

 このプログラムの実行結果を見れば、for文のブロック内で宣言された変数と、ブロックの外で宣言された変数の動きの違いがよく分かると思います。

 for文のブロック内で宣言された変数は、そのブロック内でしか存在できません。なので一度そのブロックを抜けると消えてしまいます。for文の繰り返しでもう一度そのブロック内が実行されたら、宣言&初期化からやり直しになるので、前周の値は持ち越しません。逆にブロックの外側で宣言された変数はそのブロックを抜けてもまだ値を保持していますので、こんなこと(上記の下側のプログラムの実行結果)になるんです。

 ちなみにこの仕組みはfor文に限ったことではありません。変数は、宣言された場所より内側のブロック内では生きていますが、宣言されたブロックの外側では存在できません。

 変数の有効範囲(生きている範囲)をスコープと言います。宣言する場所によってその変数のスコープが決まりますので、自分で思った通りに変数を使おうと思ったらどこで宣言したらいいかをよく考えないといけません。なんか難しい感じですが、やっているうちに分かってきますので宣言する場所を意識することだけは忘れないようにして下さい。

 次はメソッドについてやります。メソッドは覚えることも多くてややこしいですが、その分メソッドを使いこなせればいろんなことができるようになりますので頑張りましょう。

sponsored link

Androidアプリを作ろう

コメント

  • 大変勉強になっております。
    私は超初心者で非常に助かります。
    質問なのですが、このコードを最初に見たときに思ったのが、iもjも1ずつ増えていきそれを掛けるので、1×1、2×2、3×3というように9回の計算で終わることを考えてしまいました。
    なぜこうならないのでしょうか

    by ポチオ €2015/04/26 16:59

  • すみません。
    最後のForInFor.javaについての質問です。

    by ポチオ €2015/04/26 17:01

  • for文の中にfor文が入ってるからです。
    落ち着いてiとjとaの値を追っていけば分かるはずですよ。
    頑張って下さい!

    by Nobuo@管理人 €2015/04/27 08:48

  • ご返信ありがとうごさいます!
    だいたいわかりました。
    また以前の回も見直しながら理解します。

    by ポチオ €2015/04/27 15:18

  • 細かいことですが、一応書かせてもらいます。「ForInFor.java」のプログラムのforの条件式で、一つ目は上限が「9より小さい」となっているのですが、二つ目は「10以下」になっています。どちらでも良いんだとは思いますが、何も断りなくそこが変わっているのが気になるのですが…。

    by 名無し €2015/07/14 16:05

  • すみません。書き間違えました。一つ目が「9以下」なのに、二つ目は「10より小さい」になっている、でした。

    by 名無し €2015/07/14 16:08

  • ホントですね。
    修正しておきました。ありがとうございます。

    by Nobuo@管理人 €2015/07/15 12:19

  • 大変勉強になっております。質問なのですが、
    a += i * j + ” “;
    の部分で、aはstring型の変数ですよね? i * j の結果はどのようにして文字列に変換されているのでしょうか。
    string型変数の説明をもう一度読んだのですがよく分かりませんでした。

    by 権兵衛 €2016/07/15 00:29

  • >権兵衛さん
    ここを読んでみてください→ http://nobuo-create.net/stringplus/

    by Nobuo@管理人 €2016/07/15 09:19

  • 返信が遅れて申し訳ありません。ご丁寧にリンクまで貼っていただき、ありがとうございます!
    よくわかりました。

    by 権兵衛 €2016/07/19 21:29

down

コメントする



CAPTCHA


一番かんたんなJava入門

Androidアプリの作り方

忘備録

私の作ったAndroidアプリ

私の作ったWordPressテーマ

プロに教わるオンライン学習

管理人

Nobuo_CREATE

Nobuo_CREATE

WordPressテーマPrinciple、マテリアルを作ったり、Androidアプリを作ったり、Java入門サイトを作ったり、本を書いたりしています。どうぞよろしく。 [詳細]



sponsored link

オススメ書籍

[オススメpoint]

 この本は全く何も分からない初心者の方にお勧めです。プログラミングをするには覚えなければならない事が無茶苦茶いっぱいありますが、この本は教えてくれる順番、その構成が素晴らしいです。RPGのゲームを作るというストーリーにのっとってちょっとずつ難しいことを教えてもらえます。
 無機質で膨大なデータが載っているような本は読む気にならないという方は、こういうストーリー仕立ての本でチャレンジしてみてはいかがでしょうか?(注:RPGを作る為の本ではありません。)

[オススメpoint]

 ある程度、Javaを読み書きできるようになったら、オブジェクト指向について学ぶべきです。本書は、抽象的で分かったような分からんようなオブジェクト指向について、非常に分かりやすい例を出して説明してくれています。オブジェクト指向とは何なのか?という本質を掴むのにこれほど適した本はないと思います。オブジェクト志向の理念を理解できれば、より効率のいいコードをより楽に書けるようになるはずです。Java上級者を目指すなら必読の一冊!

只今、急拡大中

ゲームを作りたい人専門

個人フットサル予約サイト

ガチ専門

JavaからのRuby on Rails入門

JavaからのRuby on Rails入門