Typedef对于可移植名称,标记名称(typedef struct foo Foo;
)和
保持复杂(函数)声明可读(typedef int
(*cmpfunc)(const void *, const void *);
)。
但在C中是否存在真正需要typedef的情况?通过简单地写出派生类型,你无法做到这一点。
澄清一点:我的意思是语言用户,而不是实施者。整个stdint.h
是第二类的一个很好的例子。
感谢您的所有投入。我想我可以总结为:
(u)intN_t
类型。va_arg
宏时可能需要typedef,但我怀疑你在实践中会遇到这些衍生类型。答案 0 :(得分:15)
感谢大家的回答。我自己看了一些,在C99中发现了这个,J.2未定义的行为:
在以下情况下,行为未定: [...]
- 即可获得该类型
va_arg
宏的类型参数不是指向对象的指针 只需通过邮寄*
(7.15.1.1)。
因此,当您想要将复杂的派生类型传递/提取到va_arg
,例如int (*)[]
时,您需要typedef
这种类型的内容(更新/更正):
typedef int (*intarrptr)[4];
intarrptr x = va_arg(ap, intarrptr);
由于很难找到并且实际有用的案例可以得出结论,它不是typedef
的必要性的强有力论据。
答案 1 :(得分:14)
根据定义,typedef
是别名。因此,您始终可以使用实际类型替换别名。否则它不会是别名。
这并不意味着避免typedef
会是一个好主意。
答案 2 :(得分:5)
来自维基百科:
typedef是C和C ++编程语言中的关键字。 typedef的目的是为现有类型指定替代名称,通常是那些标准声明繁琐,可能令人困惑,或者可能因实现而异的那些。1
根据该定义,不是它永远不是必需,因为你总是可以写出扩展形式。但是,可能存在宏定义,其基于平台或其他选择要使用的typedef。因此,始终使用扩展形式可能不是非常便携。
答案 3 :(得分:2)
绝对需要,一个很好的例子是size_t,它在各种平台上都是typedef。
答案 4 :(得分:2)
在检查C编译器是否符合ISO-C的测试套件中肯定需要关键字typedef。
在未明确应该使用typedef的代码中(如上面的测试套件),它通常非常有用,但从不必要,因为它只建立了另一种类型的别名。它不会创建类型。
最后,我不会通过缩写typedef可以提供的数据来避免对预处理源文件大小的编译器限制。
答案 5 :(得分:1)
是。必须是固定大小的整数类型。例如int32_t
(并且您希望您的代码具有可移植性的机会)。
答案 6 :(得分:1)
offsetof()宏需要 structname 和 membername ,因此不能与内联结构定义一起使用。好吧,也许你的实现可以,但C标准不保证。
更新: 正如评论中指出的那样,这是可能的:
struct blah { int a; int b; };
x = offsetof(struct blah, a); // legal
但是内联结构定义不是:
x = offsetof(struct {int a; int b;}, a); // illegal
前者不包含关键字 typedef ,但也无法内联结构定义。 “简单写出派生类型”表示哪个版本尚不清楚。
答案 7 :(得分:1)
没有
typedef不像C ++中的类那样创建一个真正的新类型,它只是创建一个类型别名 - 一个已经存在的其他东西的单一标识符。在typedef中,您不定义任何新行为,语义,转换或操作符。
答案 8 :(得分:0)
没有。我认为我说得安全!
答案 9 :(得分:0)
我知道C中没有明确需要typedef的情况。
答案 10 :(得分:0)
不是“非常有用”意味着要求吗?
对于每个结构成员,指针,争论等都考虑struct
的项目,我甚至都不难。
答案 11 :(得分:0)
对我来说,typedef提供了抽象。它使我的代码保持干净,非常容易理解。您可以在没有typedef的情况下生活,就像没有所有高级语言并且坚持使用汇编语言或机器语言一样。
答案 12 :(得分:0)
个别程序员不需要创建自己的typedef。没有普遍的规则说我不能写像
这样的东西int *(*(*x())[5])();
如果我愿意的话(虽然我公司的编码标准可能不赞成)。
然而,它们遍布标准库(FILE
,size_t
等),因此您无法避免使用typedef名称。
答案 13 :(得分:0)
我们使用typedef来保持代码平台的独立性。例如, 我们做的事情就像
typedef unsigned char SHORT;
这使代码更易读,易于移植。
答案 14 :(得分:-1)
如果没有typedef,如果在声明中使用struct,则必须每次都使用关键字struct。使用typedef,您可以省略它。
struct Person
{
char * name;
};
struct Person p; /* need this here*/
typedef struct _Person
{
char * name;
} Person;
Person p; /* with typedef I can omit struct keyword here */