rul*_*lof 3 c c++ data-structures
考虑到这种数据结构:
typedef struct {
float x;
float y;
} point;
Run Code Online (Sandbox Code Playgroud)
我正在使用此功能来置换坐标:
point permute(point M)
{
point N;
N.x = M.y;
N.y = M.x;
return N;
}
Run Code Online (Sandbox Code Playgroud)
为什么用名称(point)声明一个typedef没有给出任何错误的变量?
int main(void)
{
point A;
point B;
int point = 7;
A.x = 0;
A.y = 1;
B = permute(A);
printf("A (%.2f, %.2f)\n", A.x, A.y);
printf("B (%.2f, %.2f)\n", B.x, B.y);
printf("point = %d\n", point);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
A (0.00, 1.00)
B (1.00, 0.00)
point = 7
Run Code Online (Sandbox Code Playgroud)
Kei*_*son 10
范围.
在外部作用域中声明的标识符(在您的情况下,在文件作用域,即在任何函数之外)可以在内部作用域(在您的情况下,在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. */
}
Run Code Online (Sandbox Code Playgroud)
输出是:
p = (10, 20), point = 42
Run Code Online (Sandbox Code Playgroud)
如果我们修改上述程序以移动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);
}
Run Code Online (Sandbox Code Playgroud)
我们得到一个错误; 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
Run Code Online (Sandbox Code Playgroud)
(可能已经定义了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);
}
Run Code Online (Sandbox Code Playgroud)
这种隐藏可能不是最好的主意; 对于两个不同的东西使用相同的名称,虽然编译器没有问题,但可能会让人类读者感到困惑.但是它允许您在块范围内使用名称,而不必担心可能已经包含在您所包含的所有头文件中的所有名称.