一番かんたんな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(“○さんの点数:” + scores[○] + “点”);」というようによく似た処理が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文が入っているやつです。配列は使ってないので今回の内容とは少しズレた問題かも知れませんが、ここまでの入門講座の内容をちゃんと理解できていたら、絶対読めるはずです。

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);
          }
     }
}

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

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

 答えが分かったらぜひ、実行して答え合わせをしてみてください。

 このプログラムを読めた人は、次のを見て下さい。

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);
          }
     }
}

 「String a = "";」の位置が、for文のブロックの中から外に変わっただけなのですが、これだと思ったように出力されません。

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

 for文のブロック内で宣言された変数は、そのブロック内でしか存在できません。なので一度そのブロックを抜けると消えてしまいます。

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

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

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

 なんか難しい感じですが、やっているうちに分かってきますので宣言する場所を意識することだけは忘れないようにして下さい。

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

sponsored link

Androidアプリを作ろう

コメント

  • 参考にさせてもらっているのですが、
    2つ目のForInForについての質問なのですが
    一行目が1 2 3・・・
    となるのは理解できるのですが
    二行目が1 2 3・・・
    となる理由がわかりません
    なぜなのですか?

    by 超初心者 €2016/12/12 00:56

  • >超初心者さん
    よく読んで、スコープについて理解すれば分かると思います。

    by Nobuo@管理人 €2016/12/12 09:08

  • ありがとうございます理解できました
    変数の値が残るから
    1 2 3・・・9 に付け足すということですね!
    ありがとうございます

    by 超初心者 €2016/12/16 23:27

  • 学習に利用させてもらっています。
    疑問に感じた点があるのですが、最後の項の応用問題で変数の宣言と初期化の行を移動させると実行結果がおかしくなりましたが、
    これはスコープが変化したからではなく、外側のfor文のブロックに変数aを空で上書きする代入がなくなったせいではないのですか?
    試しにa = “”;という行を外側のfor分のブロックに追加すると正しく表示されました。

    by ユーザー €2017/03/13 18:16

down

コメントする



一番かんたんなJava入門

Androidアプリの作り方

忘備録

私の作ったAndroidアプリ

おすすめ入門書

おすすめプログラミングスクール

無料で試せる今がチャンス!

管理人

Nobuo_CREATE

Nobuo_CREATE

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



sponsored link

オススメ書籍

[オススメpoint]

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

[オススメpoint]

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

只今、急拡大中

JavaからのRuby on Rails入門

JavaからのRuby on Rails入門

COBOLからのJAVA習得