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

时间:2010-11-07 03:25:44

标签: objective-c c struct global

不确定我在这里做错了什么。我有一个通过我的程序大量使用的结构。

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

我希望(读取,打算)程序的很多部分返回其中一个结构,但是其中许多应该能够返回一个“null”结构,它是一个单例/全局结构。具体的用例是执行功能说“我找不到你要我回来的东西”。

我假设这是一个在头文件中定义变量并在.c文件中初始化它的简单例子。

// 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 个答案:

答案 0 :(得分:9)

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

如果你有一个可能需要返回某个函数或者什么都不返回的函数,那么有几个选项比返回“null struct”或“sentinel struct”更好,特别是因为结构在C中不是相等的。

一个选项是返回一个指针,这样你就可以实际返回NULL来表示你真的没有返回任何东西;这有一个缺点,即具有重要的内存管理含义,即谁拥有指针?你是否必须在堆上创建一个尚未存在的对象才能执行此操作?

更好的选择是将指向结构的指针作为“out”参数,使用该指针存储实际结果,然后返回表示成功或失败的int状态代码(或{{1如果你有一个C99编译器)。这看起来像是:

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对象。如果它返回非零值,则表示它确实找到了结果并填充了result对象。

答案 1 :(得分:2)

C不允许全局非常量赋值。所以你必须在一个函数中执行此操作:

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

至于比较,C不知道如何将==运算符应用于结构。您可以在C ++中重载(重新定义)运算符,但不能在C中重载。

因此,要查看返回值是否为空,您的选项是

  1. 让每个函数返回一个布尔值来表示是否找到,并通过参数列表中的指针返回结构的值。 (例如bool found = give_me_a_struct(some_input, &thing);
  2. 返回指向结构的指针,如果不存在则可以为NULL。 (例如MyStruct* thing = give_me_a_struct(some_input);
  3. 在结构中添加一个附加字段,指示对象是否有效。
  4. 第三个选项对于其他情况是最通用的,但需要存储更多数据。对于您的具体问题,最好的选择是第一个选项。

答案 2 :(得分:1)

// MyStruct.h

typedef struct _MyStruct {
  // fields
} MyStruct;

extern MyStruct NotFoundStruct;

// MyStruct.c

#include "my_struct.h"
MyStruct NotFoundStruct = {0};

但是由于你不能使用==运算符,你必须找到另一种方法来区分它。一种(不理想的)方式是保留bool标志以指示有效性。这样,只有必须检查它以确定它是否是有效的实例。

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

答案 3 :(得分:-1)

在标题中:

// Structure definition then
extern MyStruct myStruct;

在包含全局数据的.c中

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