10.ブロックとスコープ

ifやforなどの記述は、{}でくくられています。

if(a > 10) {
   処理...
}

この{から}で囲まれた部分を「ブロック」といいます。

ブロックによって、スコープが変化します。
スコープとは、変数にアクセスできるプログラムの範囲のことです。

下記のようなコードがあります。

int a = 10;
if(a <= 10) {
   int sum = 0;
   for(int i=0; i<a; i++) {
      sum += i;
   }
}

2~7行目がifのブロック、その中で4~6行目がforのブロックになっています。
変数は、それが宣言されたブロックの外側ではアクセスすることができないことになっています。

上記コードの変数宣言は3か所です。

  • 1行目の int a
  • 3行目の int sum
  • 4行目forの初期値としての int i

これらの変数のスコープは全て異なります。

例えば、以下のコードになると、

int a = 10;
if(a <= 10) {
   int sum = 0;
   for(int i=0; i<a; i++) {
      sum += i;
   }
}
Print(sum);

8行目に変数sumを表示するPrint処理を追加していますが、これはエラーとなります。
変数sumが宣言されたのは、ifのブロックの中ですので、そのブロックの外側では変数sumは存在しないことになっています。

変数iは、forの初期値として宣言されているので、forのブロック内でのみ有効です。
変数aは、ifのブロックよりも外側で宣言されているため、どこでも有効です。

また、ブロックが異なると変数の上書きが可能になります。

int a = 10;
if(a <= 10) {
   int a = 0;
   for(int i=0; i<10; i++) {
      a += i;
   }
   Print(a);
}
Print(a);

1行目で宣言された変数aが、3行目でも宣言されています。
同名の変数を同ブロック内に宣言するとエラーになりますが、上記のようにブロックが異なればエラーになりません。

3行目で宣言された変数aのスコープは、ifブロックの中に限定されています。
対して1行目で宣言された変数aのスコープは、コード全体です。

5行目や7行目で記述されている変数aは、どちらの変数aなのかというと、予想はついていると思いますが、3行目で宣言されたものです。
ブロック違いで同名の変数が宣言され、両方のスコープが重複している場所では、より内側のブロックで宣言された変数が優先されます(外側の変数は隠れてしまいます)。

よって上記コードでは、7行目のPrint処理では「45」が表示され、9行目のPrint処理では「10」が表示されます。
プログラム的にはエラーではないのですが、1行目に宣言した変数aにアクセスしているつもりだったのに、実は3行目で宣言されたものにアクセスしてしまっていた、といった勘違いがあるとプログラムが意図していない動作をしてしまうことになりかねません。

変数名はなるべく被らないように命名してあげた方が無難だと言えます。

なお、このブロックとスコープの考え方は、次回から解説する関数でも同じです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

コメントする