The common idiom is using both:
(常见用法同时使用:)
typedef struct X {
int x;
} X;
They are different definitions.
(它们是不同的定义。)
To make the discussion clearer I will split the sentence: (为了使讨论更加清晰,我将拆分句子:)
struct S {
int x;
};
typedef struct S S;
In the first line you are defining the identifier S
within the struct name space (not in the C++ sense).
(在第一行中,您将在结构名称空间中定义标识符S
(不是C ++含义)。)
You can use it and define variables or function arguments of the newly defined type by defining the type of the argument as struct S
: (您可以使用它并通过将参数的类型定义为struct S
来定义新定义类型的变量或函数参数:)
void f( struct S argument ); // struct is required here
The second line adds a type alias S
in the global name space and thus allows you to just write:
(第二行在全局名称空间中添加类型别名S
,从而使您可以编写:)
void f( S argument ); // struct keyword no longer needed
Note that since both identifier name spaces are different, defining S
both in the structs and global spaces is not an error, as it is not redefining the same identifier, but rather creating a different identifier in a different place.
(请注意,由于两个标识符名称空间都不相同,因此在结构和全局空间中定义S
都不是错误,因为它不是在重新定义相同的标识符,而是在不同的地方创建不同的标识符。)
To make the difference clearer:
(为了使区别更加清楚:)
typedef struct S {
int x;
} T;
void S() { } // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
You can define a function with the same name of the struct as the identifiers are kept in different spaces, but you cannot define a function with the same name as a typedef
as those identifiers collide.
(您可以定义一个具有相同结构名称的函数,因为标识符被保存在不同的空间中,但是您不能定义一个与typedef
相同名称的函数,因为这些标识符会发生冲突。)
In C++, it is slightly different as the rules to locate a symbol have changed subtly.
(在C ++中,由于定位符号的规则已经微妙地改变了,因此它略有不同。)
C++ still keeps the two different identifier spaces, but unlike in C, when you only define the symbol within the class identifier space, you are not required to provide the struct/class keyword: (C ++仍然保留两个不同的标识符空间,但是与C语言不同,当您仅在类标识符空间中定义符号时,不需要提供struct / class关键字:)
// C++
struct S {
int x;
}; // S defined as a class
void f( S a ); // correct: struct is optional
What changes are the search rules, not where the identifiers are defined.
(什么是搜索规则更改,而不是定义标识符的位置。)
The compiler will search the global identifier table and after S
has not been found it will search for S
within the class identifiers. (编译器将搜索全局识别符表后S
尚未发现它会搜索S
的类标识符内。)
The code presented before behaves in the same way:
(前面提供的代码的行为方式相同:)
typedef struct S {
int x;
} T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
After the definition of the S
function in the second line, the struct S cannot be resolved automatically by the compiler, and to create an object or define an argument of that type you must fall back to including the struct
keyword:
(在第二行中定义了S
函数之后,编译器将无法自动解析struct S,要创建对象或定义该类型的参数,您必须使用struct
关键字:)
// previous code here...
int main() {
S();
struct S s;
}