変数名,関数名,ラベル,タグ,構造体や列挙体のメンバといった「識別子」(Identifiers)は,プログラム内の宣言された場所によって,プログラム内で使用可能な範囲が異なります。使用可能な範囲を有効範囲(スコープ,Scope)と言い,使用可能なときその識別子は可視(visible)であると言います。
■有効範囲(Scope)[C99, 6.2.1]
宣言された関数内。この有効範囲をもつのはラベルのみである。
プロトタイプ宣言内。この有効範囲をもつのはプロトタイプ宣言内の仮引数。
そのソースファイル内。すべてのブロックの外側で宣言されたか,或いは仮引数ではない場合。
ブロック { }
内。ブロック { }
内で宣言されたか,関数の定義における仮引数。
あるスコープの中に他のスコープがあると,前者は後者の外部有効範囲(アウター・スコープ,outer scope),後者は前者の内部有効範囲(インナー・スコープ,inner scope)となります。外部側で宣言された変数は内部側でも有効(可視)ですが,内部側にも同一名で変数宣言がある場合には,内部側では内部で宣言した方が有効となり,外部側で宣言した方は内部側では隠れた状態(hidden)となります。(内部側の変数が外部側の変数を隠すという。)
/* Example 16.1 */ // ファイル・スコープの始まり void f(int x); // プロトタイプ・スコープ: ) まで double y; int main(void) { // ブロック・スコープ1の始まり int n; { // ブロック・スコープ2の始まり char c; double y; } // ブロック・スコープ2の終わり } // ファイル・スコープとブロック・スコープ1の終わり
ブロック・スコープ1はファイル・スコープの内部,ブロック・スコープ2はファイル・スコープとブロック・スコープ1の内部になります。f
,1つ目の y
,main
はファイル・スコープ,x
はプロトタイプ・スコープ,n
はブロック・スコープ1,c
と2つ目の y
はブロック・スコープ2の有効範囲を持ちます。c
はブロック・スコープ2の外部では可視ではありません。同様のことは n
についても言えます。n
はブロック・スコープ1の外部では可視ではありません。一方,2つ目の y
は1つ目の y
をブロック・スコープ2の範囲で隠します。