代码之家  ›  专栏  ›  技术社区  ›  d11wtq Vadim Baryshev

创建全局“空”结构以便在C程序中重用?

  •  1
  • d11wtq Vadim Baryshev  · 技术社区  · 14 年前

    typedef struct _MyStruct {
      // ... handful of non-trivial fields ...
    } MyStruct;
    

    我希望(读,打算)程序的许多部分返回其中一个结构,但其中许多部分应该能够返回一个“null”结构,即singleton/global。确切的用例是实现函数说“我找不到您要我返回的内容”。

    // MyStruct.h
    
    // ... Snip ...
    
    MyStruct NotFoundStruct;
    

    -

    // MyStruct.c
    
    NotFoundStruct.x = 0;
    NotFoundStruct.y = 0;
    // etc etc
    

    但是编译器抱怨初始化不是常数。

    因为我不关心这个全局实际上在内存中引用了什么,我只关心所有的东西都使用同一个全局,所以我试着删除初始化并将定义留在头中。

    MyStruct thing = give_me_a_struct(some_input);
    if (thing == NotFoundStruct) {
      // ... do something special
    }
    

    编译器抱怨二进制运算符“=”(或“)的操作数!=)无效。

    如何定义全局可重用(总是相同的内存地址)结构?

    4 回复  |  直到 14 年前
        1
  •  1
  •   Matthew Flaschen    14 年前
    // MyStruct.h
    
    typedef struct _MyStruct {
      // fields
    } MyStruct;
    
    extern MyStruct NotFoundStruct;
    
    // MyStruct.c
    
    #include "my_struct.h"
    MyStruct NotFoundStruct = {0};
    

    但既然你不能用 == 接线员,你得另找一种方法来区分它。一种(不理想的)方法是 bool

    但我认为你应该考虑詹姆斯提出的解决方案

        2
  •  9
  •   James McNellis    14 年前

    这不能直接回答你的问题,但不适合评论。。。

    如果有一个函数可能需要返回某些内容或不返回任何内容,那么有几个选项比返回“null struct”或“sentinel struct”更好,特别是因为结构在C中不是等价的。

    NULL 以表明您实际上没有返回任何内容;这有一个缺点,即具有重要的内存管理含义,即谁拥有指针?你必须在堆上还没有存在的堆上创建一个对象来完成这个任务吗?

    更好的选择是将指向结构的指针作为“out”参数,使用该指针存储实际结果,然后返回 int 指示成功或失败的状态代码(或 bool

    int give_me_a_struct(MyStruct*);
    
    MyStruct result;
    if (give_me_a_struct(&result)) {
        //  yay!  we got a result!
    }
    else {
        //  boo!  we didn't get a result!
    }
    

    如果 give_me_a_struct 返回0,表示未找到结果 result 结果 对象已填充。

        3
  •  2
  •   chrisaycock spacemanspiff    14 年前

    C不允许全局非常量赋值。所以在函数中必须这样做:

    void init() {
       NotFoundStruct.x = 0;
       NotFoundStruct.y = 0;
    }
    

    == 结构的运算符。可以在C++中重载(重新定义)运算符,但不能在C.中重载(重新定义)

    因此,要查看返回值是否为空,您可以选择

    1. 让每个函数返回一个布尔值以指示是否找到,并通过参数列表中的指针返回结构的值。(例如。 bool found = give_me_a_struct(some_input, &thing); )
    2. 返回一个指向结构的指针,如果没有,它可以是null。(例如。 MyStruct* thing = give_me_a_struct(some_input);
    3. 向结构中添加一个额外的字段,指示对象是否有效。

    第三个选项对于其他情况来说是最通用的,但是需要存储更多的数据。对于你的具体问题,最好的选择是第一个。

        4
  •  -1
  •   JimR    14 年前

    // Structure definition then
    extern MyStruct myStruct;
    

    在包含全局数据的.c中

    struct MyStruct myStruct
    {
       initialize field 1,
       initialize field 2,
       // etc...
    };