标签:
在编程语言中,命名空间是一种特殊的作用域,且本身也用一个标识符来表示, 这样便将一系列在逻辑上相关的标识符用一个标识符组织了起来。
一、命名空间是为了解决“在相同作用域内如何区分相同的标识符”。
说明:
(1) 只有在相同作用域的情况下才能使用到命名空间去区分标识符,在嵌套的作用域、不同的作用域区分标识符都用不到命名空间的概念。
(2)在相同的作用域内,
如果命名空间相同,标识符必须不同;
如果命名空间不同,标识符可以相同。
二、按照C99,命名空间分为四种:
(1) 所有的标签(label)都属于同一个命名空间。
(2) struct、union和enum的名称,在C99中称之为tag,所有的tag属于同一个命名空间。
也就是说,如果你已经声明struct A { int a }; 就不能再声明 union A { int a };
说明:之所以让所有的tag组成一个命名空间,由于tag前面总是带struct、union和enum关键字,所以编译器可以将它们与其他的标识符区分开。
(3) struct和union的成员位于它们各自struct或union命名空间下,相互独立互不影响,并且可以形成递归的命名空间(如struct中在定义struct)。
例如:如果你已经声明 struct A { int a };其成员的名称为a,你仍然可以声明 struct B { int a}; 或者 union B { int a };
说明:之所以让struct和union成员各自成为一个命名空间,是因为它们的成员访问时,需要通过"."或"->"运算符,而不会单独使用,所以编译器可以将它们与其他的标识符区分开。由于枚举类型enum的成员可以单独使用,所以枚举类型的成员不在这一名称空间类。
(4) 其他所有的标识符,属于同一个命名空间。包括变量名、函数、函数参数,宏定义、typedef的类型名、enum的成员等等。
注意:如果标识符出现重名的情况,宏定义覆盖所有其它标识符,这是因为它在预处理阶段而不是编译阶段处理。除了宏定义之外其它类别的标识符,处理规则是:内层作用域会隐藏掉外层作用域的标识符。
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct A
{
int A;
};
union B
{
int A;
};
struct A A;
union B B;
int my_label = 1;
A.A = 1;
B.A = 20;
printf("B.A == %d \n\n", B.A);
my_label:
printf("A.A == %d \n", A.A);
A.A += 1;
if(A.A <= 5)
{
goto my_label;
}
system("pause");
return EXIT_SUCCESS;
}
实例2:
#include <stdio.h>
typedef struct A {
//int A;
struct A *A; //tag和结构体成员
} A;
void main()
{
A A;
// int B = 3;
// A->A = (struct)&B;
// printf("%d\n", *(A->A));
//
int B = 3;
A.A = &B;
printf("%d\n",*(A.A));
// A.A = 3;
// printf("%d\n", A.A);
}
标签:
原文地址:http://www.cnblogs.com/htmlphp/p/5004622.html