【问题标题】:placement of keyword struct in C [duplicate]在C中放置关键字结构[重复]
【发布时间】:2012-01-26 00:54:46
【问题描述】:

我有几个与 struct 和 typedef 相关的问题,有一段代码,我标记了一些我不确定语法是否正确的地方。我使用 Eclipse 编辑器,它会在编译出现问题时向我显示。我只是不明白为什么有时需要关键字结构,有时不需要。我可能在使用这个关键字时也有一些错误。所以请帮助我理解它。

让我们有结构

 typedef struct player
    {
        char *name; 
        int  gameId; 
        int  points; 
        int socketfd; //socket descriptor of player
        int state;
    } player_struct;

让我们有另一个结构

#define PLAYERSLEN 2
typedef struct game{
    struct player_struct *players[PLAYERSLEN]; //PLACE1
    //some code

} game_struct;

让我们发挥作用

player_struct *create_player()  //PLACE2
    {
    player_struct *player;  //PLACE3

    //alokace pameti
    player = (player_struct *) malloc(sizeof(player_struct)); //PLACE4
    //PLACE5

    player->gameId = -1;
    player->points = 0;
    player->state = 0;

    return player;
    }

让我们发挥作用?其实这个定义是什么意思?

void *( player_struct *player) //PLACE6
        {

        //some code

        }

问题参考:
PLACE1 - 这是正确的吗?为什么我不能只使用 player_struct *players[PLAYERSLEN]; ??
PLACE2 - 看起来 player_struct 之前不需要 struct ,对吗?为什么?
PLACE3 - 看起来也不需要 struct,对吗?为什么?
PLACE4 - 看起来也不需要 struct,对吗?为什么?
PLACE4 & PLACE5我可能应该在那儿处理错误,因为有 malloc,所以我可能应该把 PLACE4 的所有行都放在如果 malloc 失败的情况下我应该放在 PLACE 5 free(player)。我说的对吗?
PLACE6 这个函数或它是什么意思?括号内的代码没有包含在这里应该删除播放器..我只是不明白写函数的语法 - 这是什么意思?
PLACE6 - 再次与之前类似,为什么没有必要在这一行的 player_struct 之前放置关键字 struct?对吗?

非常感谢您的宝贵时间。

【问题讨论】:

    标签: c struct typedef


    【解决方案1】:

    您在初始定义中做了两件事:

    1. 您正在使用类型名称 struct player 定义结构。
    2. 您正在创建一个名为 player_struct 的 typedef,它只是 struct player 的别名。

    因此,struct playerplayer_struct 是正确的(或多或少是等价的),但 struct player_struct 指的是完全独立的类型,除非您试图混淆他人,否则可能是不正确的。

    现在,依次处理你的六个案件:

    • PLACE1:如上所述,这段代码实际上是错误的。
    • PLACE2、PLACE3、PLACE4:全部正确;请参阅上文了解说明。
    • PLACE5:是的,您可能应该在此处查看player != NULL 以确保确定。
    • PLACE6:同样,这是正确的,原因在上面。不过,我不确定void *(...) 应该是什么——如果* 实际上是一个函数名,那么它可能没问题。

    【讨论】:

    • 请问有人知道 void *(...) 是什么意思吗?参考PLACE6
    【解决方案2】:

    这是因为标签位于两个单独的命名空间中(是的,即使在 C 中也是如此)。结构有一个特殊的命名空间。

    我喜欢在两个命名空间中声明标签,使用这个:

    typedef struct mon_struct {
        int a;
    } mon_struct;
    

    那么您可以使用struct mon_struct mon = ... 或仅使用mon_struct mon = ...

    更新

    如果您只想使用一个标签,那么您可以使用以下之一:

    struct mon_struct { int a; };
    // requires namespace resolution using struct tag:
    void f(struct mon_struct p);
    
    // -= OR =-
    
    // slightly awkward declaration
    typedef struct { int a; } mon_struct;
    // but the type exists in the global namespace,
    // so we don't need to use the struct tag:
    void f(mon_struct p);
    

    但是如果您在 C 和 C++ 中都使用该结构,这会变得很混乱,特别是当声明或实现在 C 和 C++ 翻译之间移动而没有适当的保护时 (extern "C" { ...stuff... })。

    因此您可以选择在两个命名空间中声明它以最大程度地减少损坏:

    typedef struct mon_struct { int a; } mon_struct;
    void f(struct mon_struct p); // << ok
    void f2(mon_struct p); // << ok
    

    【讨论】:

    • 对不起,也许我错了,但我认为这是不正确的。但情况可能不同。有人告诉我,我在那里必须有不同的名字 - 但它与链表有关......
    • typedef struct NAME { ... } NAME; 形式没有 C 或 C++ 语言限制。它是合规的并被广泛使用。还是我误解了你?
    • 通常出于某种原因,我现在不明白为什么学校里有人告诉我 { 之前的名字应该与 } 之后的名字不同,但看起来没有必要。我查看了一些教程,他们在那里写道,一个是结构名称,一个是类型名称,他们通常使用不同的名称,但他们并没有说它不可能相同。我以前从未见过它,所以我很惊讶这是可能的......
    • 这当然是可能的。同样,它们位于不同的命名空间中。 spinellis.gr/cscout/doc/name.html
    • 谢谢,现在更清楚了。我还有一个问题: mon_struct 在那里使用了两次,所以我可以去掉其中一个,还是必须同时拥有它们并让它们相同(在这种情况下)?
    【解决方案3】:
    1. 没有。 player_structstruct player 的类型定义。在这种情况下,您不需要 struct 关键字。
    2. 正确。您创建了一个名为 player_struct 的类型定义,这意味着 struct player
    3. 原因同 2。
    4. 原因与 2 和 3 相同。
    5. 是的,您应该检查malloc() 是否返回NULL。另外,不要从malloc() 转换返回值。这样做可以隐藏#include 错误。
    6. 这不是一个有效的函数定义。您不需要struct,因为typedef - 同上。

    如果您从代码中完全删除 typedefplayer_structgame_struct 等词,您可能会发现这一切更有意义。然后,一旦您习惯了这一切的工作方式,您就可以重新引入typedefs 并可能减少一些打字。举个简单的例子,你可以把你的第一个定义分解成它的组成部分:

    struct player
    {
      char *name; 
      int  gameId; 
      int  points; 
      int socketfd; //socket descriptor of player
      int state;
    };
    
    typedef struct player player_struct;
    

    也许这会帮助你理解它?

    【讨论】:

      【解决方案4】:

      您不需要 PLACE1 中的 struct...只要 player_struct 的定义是已知的,即在它之前声明,或者从它之前的 .h 声明。

      【讨论】:

        猜你喜欢
        • 2019-01-23
        • 2020-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 2010-12-18
        相关资源
        最近更新 更多