范围。
在外部范围(在您的情况下,在文件范围内,即在任何函数之外)声明的标识符可以在内部范围内(在您的情况下,在 main 函数内)重新声明。内部声明隐藏外部声明,直到到达内部范围的末尾。
这通常适用于声明,而不仅仅是typedef 名称。
一个简单的例子:
#include <stdio.h>
typedef struct { int x, y; } point;
int main(void) {
point p = { 10, 20 };
/* p is of type point */
int point = 42;
/* This hides the typedef; the name "point"
now refers to the variable */
printf("p = (%d, %d), point = %d\n", p.x, p.y, point);
/* p is still visible here; its type name "point" is not
because it's hidden. */
}
输出是:
p = (10, 20), point = 42
如果我们修改上述程序,将typedef 移动到与变量声明相同的范围内:
#include <stdio.h>
int main(void) {
typedef struct { int x, y; } point;
point p = { 10, 20 };
int point = 42;
printf("p = (%d, %d), point = %d\n", p.x, p.y, point);
}
我们会得到一个错误; gcc 说:
c.c: In function ‘main’:
c.c:5:9: error: ‘point’ redeclared as different kind of symbol
c.c:3:34: note: previous declaration of ‘point’ was here
(C 语言可以 已被定义为允许这样做,point 的第二个声明在其余范围内隐藏了第一个声明,但设计者显然认为隐藏了外部声明范围可能很有用,但在单个范围内这样做会导致更多的混乱而不是它的价值。)
一个稍微复杂一点的例子:
#include <stdio.h>
int main(void) {
typedef struct { int x, y; } point;
{ /* Create an inner scope */
point p = { 10, 20 };
/* Now the type name is hidden */
int point = 42;
printf("p = (%d, %d), point = %d\n", p.x, p.y, point);
}
/* We're outside the scope of `int point`, so the type name is
visible again */
point p2 = { 30, 40 };
printf("p2 = (%d, %d)\n", p2.x, p2.y);
}
这种隐藏可能不是最好的主意;对两个不同的事物使用相同的名称,虽然这对编译器来说没有问题,但可能会让人类读者感到困惑。但它允许您在块范围内使用名称,而不必担心您包含的所有标头可能在文件范围内引入的所有名称。