很抱歉,如果之前有人询问,我甚至不确定要搜索什么来提出这个问题。
当我创建typedef struct
时,我通常会这样做:
typedef struct myStruct {
int a;
int b;
struct myStruct *next;
} MyStruct;
所以我最后用MyStruct
声明它。然后当我创建将其作为参数传递的函数时,我写
int doSomething(MyStruct *ptr){
}
然而,我正在与一位朋友合作完成一个项目,我遇到了他的编码风格,即也声明*MyStructP
这样:
typedef struct myStruct {
int a;
int b;
struct myStruct *next;
} MyStructR, *MyStructP;
然后他在他的函数中使用MyStructP
,所以他的参数如下:
int doSomething(MyStructP)
所以他不必在参数列表中使用*
。这让我很困惑,因为当我查看参数列表时,我总是寻找*
以确定arg是否是指针。最重要的是,我正在创建一个函数,它接受我创建的结构和他创建的结构,所以我的arg有*而他的没有。超级混乱!
有人可以就两者之间的差异提供见解/比较/建议吗?优点?缺点?哪种方式更好或更差,还是更广泛使用?任何信息都可以。谢谢!
答案 0 :(得分:12)
通常认为在typedef后面隐藏指针的风格很差,除非它们是不透明的句柄(例如SDL_GLContext
是void*
)。
这不是这里的情况,我同意你的看法,它比帮助更令人困惑。
答案 1 :(得分:9)
Linux kernel coding style表示要避免使用这类typedef:
第5章:Typedef
请不要使用“vps_t”之类的内容。
错误将typedef用于结构和指针。当你看到
vps_t a;
在来源中,它是什么意思?
相反,如果它说
struct virtual_container *a;
你实际上可以说出“a”是什么。
答案 2 :(得分:4)
有些人喜欢在命名变量时使用Hungarian Notation中的想法。有些人在命名类型时会更进一步。
我认为这是一个品味问题。
但是,我觉得它模糊了一些东西(比如你的例子),因为你必须挖掘 name 的声明才能找到它的类型。我更喜欢明显而明确的东西,我会避免使用这种类型名称。
(请记住,typedef
不会引入新类型,而只会引入新类型的新名称。)
答案 3 :(得分:2)
人们偶尔使用typedef指针的主要原因是将类型表示为"黑盒子对象"程序员,并允许其实施更容易在未来更改。
例如,也许今天类型是指向结构的指针,但明天该类型将成为某个表的索引,某种句柄/键或文件描述符。 Typedef以这种方式告诉程序员他们不应该尝试他们通常对指针做的事情,比如将它与0 / NULL进行比较,解除引用(例如 - 直接访问成员),递增它等等。 ,因为他们的代码将来可能会被破坏。当然,使用命名约定,例如你的朋友,会显示和编码底层实现实际上是指针与此目的冲突。
这样做的另一个原因是不太可能出现这种错误:
myStructR *ptr1, ptr2;
myStructP ptr3, ptr4;
这很糟糕,因为编译器通常会让你在以后误用ptr2
,但这是这样做的原因。