补遗篇之struct(enum/union)多种定义方式

    结构体(struct)是各种变量组合形成的新数据类型,struct有多种定义形式,总结下来可分四种,初学者容易混淆。下面一并整理区分,其中要特别留意区分三个元素:结构标签名,结构变量名,结构别名。

形式1

    struct 结构标签名

    {

      类型成员变量名;

      ......

    }结构变量名;

实例:

    struct tagPERSON

    {

      char name[8];

      int age;

    } person;

    这个例子同时定义了一个结构标签名tagPERSON和结构变量person。如果不想放在一起,可选择另一种形式:先定义结构标签,再用结构标签去定义结构变量,如:

形式2

    struct 结构标签名

   {

      类型成员变量名;

      ......

    };                                                          //先定义结构标签

    sruct 结构标签名结构变量名集合;   //再struct+结构标签来定义结构体变量

    实例:

    struct tagPERSON

    {

      char name[8];

      int age;

    };

    struct tagPERSON person;

    这种方式好处是可以用结构标签一次定义多个同类型结构变量,如:struct tagPERSON Tianyr,Liuqi,Wangming; 但定义时,tagPERSON前面挂个struct多不爽啊,和普通变量的定义还是不一样。要想进一步去掉struct,就要用到typedef,如:

形式3

    typedef struct 结构标签名

    {

      类型成员变量名;

      ...

    }结构别名;                            //先定义结构别名

    结构别名结构变量名集合;  //再用结构别名直接定义变量集合,无需形式2中的struct前缀

    实例:

    typedef struct tagPERSON

    {

      char name[8];

      int age;

    } person_struct;

    person_struc person;

    这种方式为结构体标签tagPERSON另外定义了一个结构体别名person_struc,可以用这个别名直接定义一个或多个结构体变量,如:string_struc Tianyr,Liuqi,Wangming; 不再需要struct前缀了,并且既然有结构别名,标签名也就可有可无了,于是进一步简化得到:

    typedef struct

   {

      char name[8];

      int age;

    }string_struc;

    实际使用时,这种形式最常见。

形式4

    最后一种,省略形式1中的结构标签,直接定义结构变量,称为无名结构,例如:

    struct

    {

      char name[8];

      int age;

    }Liuli,Liuqi;

直接定义结构体变量,没有标签名,也没有别名。对于临时结构,这种方式简洁而不留痕迹,适合在函数内部等小作用域使用。

结构体定义的一个常见问题:

    用下面代码定义结构时,编译器报错,为什么?

    typedef struct tagNode

    {

      char *pItem;

      pNode pNext;

    }*pNode;

    实现链表时,很多人都碰到同样问题,莫非C不允许结构中包含指向它自身的指针?No,当然允许,这是实现链表的基础。问题在于,一些编译器不支持typedef结构体别名过早使用:pNext的类型是pNode,但pNode是结构体指针的别名,结构体定义完成前,这个别名还不存在。或者说定义pNext时,编译器不认识pNode这似乎是“鸡生蛋还是蛋生鸡”的死结,其实有以下解决方法:

1

    typedef struct tagNode

    {

      char*pItem;

      struct tagNode *pNext;

    }*pNode;

2)

    typedef struct tagNode*pNode;

    struct tagNode

    {

      char *pItem;

      pNode pNext;

    };

    用typedef给一个还未定义的类型起新名,C编译器支持这种做法。

3)规范做法:

    struct tagNode

    {

      char *pItem;

      struct tagNode *pNext;

    };

    typedef struct tagNode *pNode;

    三种做法利用同一点:标签名在结构体定义初始就可以识别,而结构体别名有时要等结构体定义完之后才能用。所以成员变量类型最好用结构体标签名来定义,不要用别名。

总结

    结构标签名、结构变量名以及typedef 重定义的结构别名,三者容易混淆。初学者使用时常常张冠李戴,编译报错后也不知所措,所以要加以重视和区分。

    另外enumunion等自定义类型,和struct类似,可参考struct前3种定义形式及“标签/别名/变量名”的概念区分和理解,不重复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值