【问题标题】:return static structure array pointer with get()使用 get() 返回静态结构数组指针
【发布时间】:2014-08-26 00:42:13
【问题描述】:

我的项目中有一个文件,该文件具有定义为 MyStruct_t myStruct[SIZE] 的本地结构数组,我可以在该模块中很好地使用它。现在我想让它可以被不同的代码模块访问,所以我想出了一个函数:

MyStruct_t *GetStruct(void) {
  return myStruct;
}

但是当我从我的不同模块调用它时,我收到一个错误expression must be a modifiable lvalue。我的来电者看起来像:

void myFunc(void) {
    MyStruct_t locStruct;
    locStruct = GetStruct();
}

我怎样才能做到最好?

【问题讨论】:

    标签: c pointers struct return-value


    【解决方案1】:

    GetStruct 返回指向myStruct[SIZE] 元素的指针,而不是MyStruct_t。除非您真的需要副本,否则将 locStruct 设为指针,如下所示:

    MyStruct_t *locStruct = GetStruct();
    

    注意locStructMyStruct_t数组,大小为SIZE

    如果您确实想复制,请取消引用 GetStruct() 的结果:

    MyStruct_t locStruct = *GetStruct();
    

    这将生成myStruct 数组的初始元素的副本。

    由于GetStruct 除了访问myStruct 之外不提供其他服务,因此您不妨将myStruct 设为全局(extern)而不是static

    最后,您可以更改 GetStruct 以访问特定元素。这也将负责检测溢出 - 即尝试让元素超过 SIZE 或负索引:

    bool GetStruct(int index, MyStruct_t *ptr) {
        if (index < 0 || index >= SIZE) {
            return false;
        }
        *ptr = myStruct[index];
        return true;
    }
    

    现在GetStruct() 的调用如下所示:

    MyStruct_t locStruct;
    if (GetStruct(5, &locStruct)) {
        // All good
    } else {
        // Error
    }
    

    【讨论】:

      【解决方案2】:

      例如你可以这样做

      void myFunc( void ) 
      {
         MyStruct_t locStruct[SIZE];
         MyStruct_t *p = GetStruct();
         memcpy( locStruct, p, SIZE * sizeof( MyStruct_t ) );
      }
      

      或者有一个指向数组第一个元素的指针就足够了

      void myFunc( void ) 
      {
         MyStruct_t *locStruct = GetStruct();
      }
      

      在这种情况下,访问数组元素的语法将与例如 locStruct[i] 相同

      【讨论】:

      • 我不认为他想要数组的副本!
      【解决方案3】:

      GetStruct 返回一个指针,所以你的locStruct 变量也应该是一个指针。

      void myFunc(void) {
          MyStruct_t *locStruct;
          locStruct = GetStruct();
      } 
      

      【讨论】:

        【解决方案4】:

        如果myStruct 在其他模块中是全局的,那么您可能正在寻找extern 关键字。只需将其放在另一个模块中即可:

        extern MyStruct_t myStruct[];
        

        (我假设 MyStruct_t 是一个 typedefed 名称。当然,否则您需要将关键字 struct 放在它前面。)

        这也需要访问MyStruct 的声明。把它放在一个头文件中并包含在两个模块中。

        这是一个简单的例子:

        // main.h ------------------------------------------------
        
        typedef struct {
          int a, b, c;
        } AStruct;
        
        // func.h ------------------------------------------------
        
        void func(void);
        
        // main.c ------------------------------------------------
        
        #include <stdio.h>
        #include "main.h"
        #include "func.h"
        
        AStruct as[100];
        
        int main(void) {
            func();
            printf("%d,%d,%d\n", as[0].a, as[0].b, as[0].c);
            return 0;
        }
        
        // func.c ------------------------------------------------
        
        #include "main.h"
        #include "func.h"
        
        extern AStruct as[];
        
        void func(void) {
            as[0].a = 1;
            as[0].b = 2;
            as[0].c = 3;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 2013-08-02
          • 1970-01-01
          • 2014-12-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多