C Typedef结构声明为两种类型:";typedef结构x{..}x,*XPointer";

C Typedef结构声明为两种类型:";typedef结构x{..}x,*XPointer";,c,pointers,struct,C,Pointers,Struct,抱歉,如果以前有人问过这个问题,我甚至不确定要搜索什么才能找到这个 当我创建一个typedef结构时,我通常会这样做: typedef struct myStruct { int a; int b; struct myStruct *next; } MyStruct; typedef struct myStruct { int a; int b; struct myStruct *next; } MyStructR, *MyStructP; 因此,我在最后用MyStr

抱歉,如果以前有人问过这个问题,我甚至不确定要搜索什么才能找到这个

当我创建一个
typedef结构时,我通常会这样做:

typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStruct;
typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStructR, *MyStructP;
因此,我在最后用
MyStruct
声明它。然后,当我创建将其作为参数传入的函数时,我写入

int doSomething(MyStruct *ptr){

}
然而,我在一个项目上与一位朋友合作,我遇到了他的编码风格,也就是像这样声明
*MyStructP

typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStruct;
typedef struct myStruct {
  int a;
  int b;
  struct myStruct *next;
} MyStructR, *MyStructP;
然后他在他的函数中使用
MyStructP
,因此他的参数如下所示:

int doSomething(MyStructP)
因此,他不必使用参数列表中的
*
。这让我很困惑,因为当我查看参数列表时,我总是查找
*
来确定arg是否是指针。除此之外,我正在创建一个函数,它接受我创建的结构和他创建的结构,因此我的arg有*而他的没有。太令人困惑了


有人能就两者之间的差异给出见解/比较/建议吗?赞成的意见?欺骗?哪种方法更好或更差,或者使用更广泛?任何信息都可以。谢谢

通常认为将指针隐藏在typedef后面是不好的风格,除非它们是不透明的句柄(例如
SDL\u GLContext
void*
)。

这里的情况并非如此,我同意你的观点,这比帮助更令人困惑。

有些人在命名变量时喜欢使用想法。有些人在命名类型时更进一步地理解了这个概念

我认为这是品味的问题

然而,我认为它掩盖了一些事情(如在您的示例中),因为您必须挖掘名称声明才能找到其类型。我更希望事情是显而易见的和明确的,我会避免这样的类型名

(请记住,并不是引入一个新类型,而只是引入一个新名称,作为新类型的别名。)

为了避免这些类型的typedef:

第5章:类型定义 请不要使用像“vps\u t”这样的东西

对结构和指针使用typedef是错误的。当你看到一个

vps_t a;
在来源中,它意味着什么

相反,如果它说

struct virtual_container *a;
你实际上可以分辨出“a”是什么


人们偶尔使用typedef指针的主要原因是将类型表示为程序员的“黑盒对象”,并允许将来更容易地更改其实现

例如,今天的类型可能是指向结构的指针,但明天该类型将成为某个表的索引、某种类型的句柄/键或文件描述符。这种方式的类型定义告诉程序员,他们不应该尝试通常对指针所做的事情,例如将指针与0/NULL进行比较、取消对指针的引用(例如直接访问成员)、递增指针等,因为他们的代码将来可能会被破坏。当然,使用命名约定(如您的朋友所做的)会揭示并编码底层实现实际上是一个指针,这与此目的冲突

这样做的另一个原因是减少此类错误的可能性:

myStructR *ptr1, ptr2;
myStructP  ptr3, ptr4;

这是一个相当薄弱的环节,因为编译器通常会在以后发现您误用了
ptr2
,但这就是为什么要这样做。

@hvd很抱歉,这是一个输入错误。它应该读取arg是指针还是指针not@krb686谢谢,这更有意义。不过,在
void f(inta[],intb())
中,
a
b
都是指针。不过,这里的语法确实表明发生了一些特殊的事情。它们是相同的。编译器甚至不会抱怨任何事情。也许你可以尝试搜索
*
,键入以
P
结尾的名称作为指针。@hvd谢谢,是的,我想我已经记下了,比如它们是如何相同的:
int main(int argc,char**argv)
int main(int argc,char*argv[])
。相关:正是我所想的!如果我在另一个文件中调用他的函数,如果我感到困惑,我必须查找声明。当然,我想这是好事,他在结尾加上了“P”,但这让我意识到有人可以选择不这样做,那就太糟糕了!这很有趣,前几天我们也就这个问题来回讨论了一下。我完全同意,并且我提出了一个不便之处,即当使用
typedef
时,它会使将来的实例在vim中不着色!!事实并非如此,应该修改的是实际的结构定义。其他任何东西都不需要更改(可能除了访问结构中各个字段的代码),即滥用typedef功能会导致混淆。在这种情况下,(typedef a struct)是个坏主意。它只是混乱了名称空间,模糊了代码,并有利于维护nightmares@user3629249如果类型是对象的不透明“引用”或“句柄”,那么这种“引用”的实现可以按照我的建议进行更改,那么,为什么要强制将该引用包装在另一个类型中,然后传递指向该包装的指针呢?