C99標準から:
6.2.1 / 2
識別子が指定するさまざまなエンティティごとに、その識別子は、そのスコープと呼ばれるプログラムテキストの領域内でのみ表示されます(つまり、使用できます)。同じ識別子で指定された異なるエンティティは、スコープが異なるか、名前空間が異なります。
エンティティと識別子(オブジェクトの名前である可能性があることを知っています)と混同しています。例を挙げたこの引用によると、エンティティは正確には何ですか?
エンティティは変数、関数、タイプなどです。識別子はそれらのエンティティの名前です。例えば:
#include <stdlib.h>
#include <stdio.h>
static int foo()
{
static int x = 0; // "x" is an identifier, the variable "x" inside
// this function "foo()" is an entity.
return x++;
}
int main()
{
int x = 1; // "x" is an identifier as well, and it is the same name "x"
// as of that used inside "foo()". However, this entity
// (variable) is not the same as in "foo()", it has different
// scope and is a totally different entity.
printf("foo()+x++ = %d\n", foo()+x++);
printf("foo()+x++ = %d\n", foo()+x++);
printf("foo()+x++ = %d\n", foo()+x++);
return EXIT_SUCCESS;
}
エンティティは変数です。つまり、データを含むメモリ(またはレジスタ)、またはサイズやコンポーネントフィールドなどのプロパティを持つ型や列挙型などのコンパイルオブジェクトを意味します。識別子は、エンティティの名前にすぎません。 。
2つの区別されたエンティティは(スコープに応じて)同じ名前を持つことができますが、プログラムのどの時点でも、名前は1つのエンティティにのみ一致します。
次のCプログラムを検討してください
#include<stdio.h>
int main(void)
{
int var1, var2;
.....
.....
}
int newfun(void)
{
int var1;
float var2;
....
....
}
したがって、異なるエンティティ(変数と見なすことができます)ごとに、その識別子(変数名、上記:var1、var2)をプログラムテキストの領域内で使用できます。つまり、main()関数で定義されたvar1とvar2は、その中でのみ使用できます。
ただし、関数main()とnewfun()の両方の識別子は同じです。つまり、intvar1とfloatvar2です。これらは、機能ごとに異なる方法で処理されます。
現在、main()関数の変数(または識別子)はint型です。それらはまとめてエンティティと呼ぶことができます。ただし、次の関数の同じ変数var2はfloat型であり、これは異なる型であり、したがって異なるエンティティです。
1つの識別子で同時に異なるエンティティを指定できることに注意してください。
#include <stdio.h>
static int x = 42; // 1
struct x { int x; }; // 2 & 3
int func(struct x x) // 4
{
if (x.x > 10) goto x; // 5
int y = x.x;
{
int x = 37; // 6
printf("%d %d\n", x, y);
}
x: // 7
return(x.x);
}
x
完全に酷使された識別子であることに同意できると思います。
x
int
ファイルスコープでの型の静的変数です。x
構造タグです。x
構造体のメンバーです。x
タイプのパラメータ/ローカル変数ですstruct x
(ファイルスコープ変数を非表示にします)。x
ラベルへの参照です。x
は新しいローカル変数です(ファイルスコープ変数とパラメーターの両方を非表示にします)。x
ラベルの定義です。識別子が指定するさまざまなエンティティごとに、その識別子は、そのスコープと呼ばれるプログラムテキストの領域内でのみ表示されます(つまり、使用できます)。同じ識別子で指定された異なるエンティティは、スコープが異なるか、名前空間が異なります。
構造タグx
は、ファイルの最後を最初に参照した場所から表示されます。これはタグ名前空間にあるため、。の他の使用法と競合しませんx
。ラベルx
はラベル名前空間にあるため、。の他の使用法と競合しませんx
。構造体メンバーx
はstruct x
'名前空間の'メンバーにあり、他の使用法と競合しませんx
。これらは3つの特別な名前空間です。
への他の参照x
はすべて「通常の識別子」名前空間にあります。Typedef名も通常の名前空間にあります。だから私はを使用しませんでしたtypedef
。と呼ばれる3つの異なる変数はx
、異なるスコープを持っています。
私はマクロ名前空間を見捨てました。最初に追加#define x z
した場合、私が言っていることはすべて「前処理後」x
について言わなければならないでしょう。z