我是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;
当前回答
另一个没有指出的区别是,给struct一个名称(即struct myStruct)也允许你提供结构的前向声明。所以在其他文件中,你可以这样写:
struct myStruct;
void doit(struct myStruct *ptr);
而不需要知道定义。我建议你把这两个例子结合起来:
typedef struct myStruct{
int one;
int two;
} myStruct;
这为您提供了更简洁的类型定义名称的便利,但如果需要,仍然允许您使用完整的结构名称。
其他回答
我看需要澄清一下。C和c++没有不同的类型定义。c++最初不过是C之上的一组附加的包含。
如今几乎所有C/ c++开发人员都面临的问题是:a)大学不再教授基础知识,b)人们不理解定义和声明之间的区别。
这样的声明和定义存在的唯一原因是链接器可以计算到结构中字段的地址偏移量。这就是为什么大多数人使用实际上写得不正确的代码——因为编译器能够确定寻址。当有人试图提前做一些事情,比如队列、链表或承载O/S结构时,问题就出现了。
声明以'struct'开始,定义以'typedef'开始。
此外,结构体具有前向声明标签和已定义标签。大多数人不知道这一点,而是将forward声明标签用作定义标签。
错误的:
struct myStruct
{
int field_1;
...
};
它们只是使用forward声明来标记结构——所以现在编译器知道它了——但它不是实际定义的类型。编译器可以计算寻址——但这不是它打算使用的方式,原因我马上会说明。
使用这种形式的声明的人,必须在几乎所有的引用中都加上“struct”——因为它不是一个正式的新类型。
相反,任何不引用自身的结构都应该这样声明和定义:
typedef struct
{
field_1;
...
}myStruct;
现在它是一个实际的类型,当使用时,你可以使用at作为'myStruct',而不必在它前面加上'struct'这个词。
如果你想要一个指向该结构的指针变量,那么包括一个二级标签:
typedef struct
{
field_1;
...
}myStruct,*myStructP;
现在你有了一个指向该结构的指针变量,自定义的。
前置声明——
现在,这里有一些有趣的东西,forward声明是如何工作的。如果希望创建引用自身的类型,如链表或队列元素,则必须使用前向声明。编译器不会考虑定义的结构,直到它到达最后的分号,所以它只是在这一点之前声明。
typedef struct myStructElement
{
myStructElement* nextSE;
field_1;
...
}myStruct;
现在,编译器知道,尽管它还不知道整个类型是什么,但它仍然可以使用前向引用引用它。
请正确地声明和定义结构类型。这其实是有原因的。
如果使用struct而不使用typedef,则总是需要编写
struct mystruct myvar;
写字是违法的
mystruct myvar;
如果使用typedef,就不再需要结构体前缀了。
下面的代码创建了一个别名为myStruct的匿名结构:
typedef struct{
int one;
int two;
} myStruct;
没有别名就不能引用它,因为没有为结构指定标识符。
在C(不是c++)中,你必须像这样声明结构变量:
struct myStruct myVariable;
为了能够使用myStruct myVariable;相反,你可以对结构进行类型定义:
typedef struct myStruct someStruct;
someStruct myVariable;
你可以将结构定义和类型定义结合在一个声明匿名结构和类型定义的语句中。
typedef struct { ... } myStruct;
不同之处在于使用结构体时。
第一种方法是:
struct myStruct aName;
第二种方法允许您删除关键字struct。
myStruct aName;