名前スコープ

名前は、定義されたポイントからそのスコープが終了するポイントまで、およびそのスコープに含まれるすべてのスコープ内でアクセス可能である。この点において、すべてのスコープは名前スコープを定義する。

名前は、そのスコープの終了点を超えては利用できない:

void main() {
    int outer;

    if (aCondition) {  // ← 波括弧は新しいスコープを開始する
        int inner = 1;
        outer = 2;     // ← ここでは'outer'を使用できる

    } // ← この点より先では'inner'は使用できない

    inner = 3;  // ← コンパイルエラー
                //   'inner'は外側のスコープでは使用できない
}
D
name_space.1

innerは、if条件内のスコープで定義されているため、そのスコープ内でのみ利用可能だ。一方、outerは、外側のスコープと内側のスコープの両方で利用可能だ。

同じ名前を内側のスコープで定義することはできない:

size_t length = oddNumbers.length;

if (aCondition) {
    size_t length = primeNumbers.length; // ← コンパイルエラー
}
D

スコープは文に関連付ける必要はない。関数 (およびその他のほとんどの構文) 内の自由な中括弧のペアで定義することができる。

void main() {
    // このスコープはどの文とも関連付けられていない:
    {
        int a;
    }

    // もう1つ:
    {
        int a;    // この'a'は前の'a'とは異なる
    }
}
D
name_space.2

ただし、このような関連付けられていないスコープは、モジュールスコープ(ソースコードの最上位レベル)では定義できない:

void main() {
    // ...
}

{    // ← コンパイルエラー
}
D
name_space.3
最初の使用に最も近い位置での名前の定義

これまでのすべてのプログラムでそうしてきたように、変数は最初の使用前に定義する必要がある:

writeln(number);     // ← コンパイルエラー
                     //   数値がまだ不明
int number = 42;
D

このコードがコンパイラで受け入れられるためには、numberwritelnで使用される前に定義されている必要がある。定義する行数は制限されていないが、変数は最初の使用場所にできるだけ近い場所で定義することが良いプログラミング慣行とされている。

ユーザーから入力された数値の平均を表示するプログラムで、これを確認しよう。他のプログラミング言語に慣れているプログラマーは、スコープの先頭で変数を定義することに慣れているかもしれない:

int count;                                 // ← ここ
int[] numbers;                             // ← ここ
double averageValue;                       // ← ここ

write("How many numbers are there? ");

readf(" %s", &count);

if (count >= 1) {
    numbers.length = count;

    // ... 計算はここにあると仮定する ...

} else {
    writeln("ERROR: You must enter at least one number!");
}
D

上記のコードと、変数を後で定義し、各変数が実際にプログラムに参加し始める以下のコードを比較しよう:

write("How many numbers are there? ");

int count;                                 // ← ここ
readf(" %s", &count);

if (count >= 1) {
    int[] numbers;                         // ← ここ
    numbers.length = count;

    double averageValue;                   // ← ここ

    // ... 計算はここにあると仮定する ...

} else {
    writeln("ERROR: You must enter at least one number!");
}
D

すべての変数をスコープの先頭で定義する方が構造的に見栄えが良いように見えるかもしれないが、可能な限り遅く定義するメリットがいくつかある: