我是C编程的初学者,但我想知道在定义结构时使用typedef与不使用typedef之间有什么区别。在我看来,这两者并没有什么区别,它们实现的目标是一样的。
struct myStruct{
int one;
int two;
};
vs.
typedef struct{
int one;
int two;
}myStruct;
我是C编程的初学者,但我想知道在定义结构时使用typedef与不使用typedef之间有什么区别。在我看来,这两者并没有什么区别,它们实现的目标是一样的。
struct myStruct{
int one;
int two;
};
vs.
typedef struct{
int one;
int two;
}myStruct;
当前回答
与其他构造一样,typedef用于为数据类型赋予新名称。在这种情况下,这样做主要是为了使代码更干净:
struct myStruct blah;
vs.
myStruct blah;
其他回答
如果使用struct而不使用typedef,则总是需要编写
struct mystruct myvar;
写字是违法的
mystruct myvar;
如果使用typedef,就不再需要结构体前缀了。
常用的习语是两者都用:
typedef struct S {
int x;
} S;
它们是不同的定义。为了使讨论更清楚,我将把句子分开:
struct S {
int x;
};
typedef struct S S;
在第一行中,您在结构名称空间(不是c++意义上的)中定义标识符S。你可以使用它并通过将参数的类型定义为struct S来定义新定义类型的变量或函数参数:
void f( struct S argument ); // struct is required here
第二行在全局名称空间中添加了一个类型别名S,因此允许你这样写:
void f( S argument ); // struct keyword no longer needed
请注意,由于两个标识符名称空间是不同的,所以在结构和全局空间中定义S并不是错误,因为它不是重新定义相同的标识符,而是在不同的位置创建了不同的标识符。
为了让区别更清楚:
typedef struct S {
int x;
} T;
void S() { } // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
当标识符保存在不同的空格中时,可以定义与结构同名的函数,但当标识符冲突时,不能定义与typedef同名的函数。
在c++中,它略有不同,因为定位符号的规则发生了微妙的变化。c++仍然保留了两个不同的标识符空间,但与C不同的是,当你只在类标识符空间中定义符号时,你不需要提供struct/class关键字:
// C++
struct S {
int x;
}; // S defined as a class
void f( S a ); // correct: struct is optional
更改的是搜索规则,而不是定义标识符的位置。编译器将搜索全局标识符表,在没有找到S后,它将在类标识符中搜索S。
前面给出的代码以同样的方式运行:
typedef struct S {
int x;
} T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
在第二行定义了S函数之后,编译器不能自动解析结构体S,要创建该类型的对象或定义实参,必须返回到包含struct关键字:
// previous code here...
int main() {
S();
struct S s;
}
在C语言中,结构、联合和枚举的类型说明关键字是强制性的,也就是说,当引用类型时,你总是必须在类型名(它的标记)前面加上struct、联合或enum。
您可以通过使用typedef来摆脱关键字,这是一种信息隐藏的形式,因为在声明对象时,对象的实际类型将不再可见。
因此建议(参见Linux内核编码风格指南,第5章)只在以下情况下这样做 实际上,您希望隐藏这些信息,而不仅仅是为了节省一些按键。
你应该使用typedef的一个例子是不透明类型,它只与相应的访问器函数/宏一起使用。
不同之处在于使用结构体时。
第一种方法是:
struct myStruct aName;
第二种方法允许您删除关键字struct。
myStruct aName;
下面的代码创建了一个别名为myStruct的匿名结构:
typedef struct{
int one;
int two;
} myStruct;
没有别名就不能引用它,因为没有为结构指定标识符。