C 返回带有get()的静态结构数组指针

C 返回带有get()的静态结构数组指针,c,pointers,struct,return-value,C,Pointers,Struct,Return Value,我的项目中有一个文件,它有一个定义为MyStruct\u t MyStruct[SIZE]的本地结构数组,我可以在该模块中很好地使用它。现在我想让它可以被其他代码模块访问,所以我提出了一个函数: MyStruct_t *GetStruct(void) { return myStruct; } 但是当我从不同的模块调用它时,我得到一个错误表达式必须是可修改的左值。我的来电者看起来像: void myFunc(void) { MyStruct_t locStruct; locS

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

MyStruct_t *GetStruct(void) {
  return myStruct;
}
但是当我从不同的模块调用它时,我得到一个错误
表达式必须是可修改的左值。我的来电者看起来像:

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

如何才能做到最好?

GetStruct
返回指针,因此
locStruct
变量也应该是指针

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

GetStruct
返回指针,因此
locStruct
变量也应该是指针

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

例如,您可以使用以下方法

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]

相同。例如,您可以通过以下方式执行

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]
GetStruct
返回指向
myStruct[SIZE]
元素的指针相同,而不是
myStruct\t
。除非您确实需要副本,否则请将
locStruct
制作为指针,如下所示:

MyStruct_t *locStruct = GetStruct();
MyStruct_t locStruct;
if (GetStruct(5, &locStruct)) {
    // All good
} else {
    // Error
}
请注意,
locStruct
是一个大小为
size
MyStruct\t
数组

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

MyStruct_t locStruct = *GetStruct();
这将生成
myStruct
数组初始元素的副本

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

最后,您可以更改
GetStruct
以访问特定元素。这还可以检测超限-即尝试使元素超过
大小
或负索引:

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

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

MyStruct_t *locStruct = GetStruct();
MyStruct_t locStruct;
if (GetStruct(5, &locStruct)) {
    // All good
} else {
    // Error
}
请注意,
locStruct
是一个大小为
size
MyStruct\t
数组

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

MyStruct_t locStruct = *GetStruct();
这将生成
myStruct
数组初始元素的副本

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

最后,您可以更改
GetStruct
以访问特定元素。这还可以检测超限-即尝试使元素超过
大小
或负索引:

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

如果另一个模块中的
myStruct
是全局的,那么您可能正在查找
extern
关键字。把这个放在另一个模块中:

extern MyStruct_t myStruct[];
(我假设MyStruct\t是一个
typedef
ed名称。否则您当然需要在它前面加上关键字
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;
}
//main.h------------------------------------------------
类型定义结构{
INTA、b、c;
}AStruct;
//函数h------------------------------------------------
无效函数(void);
//main.c------------------------------------------------
#包括
#包括“main.h”
#包括“func.h”
AStruct为[100];
内部主(空){
func();
printf(“%d,%d,%d\n”,作为[0].a,作为[0].b,作为[0].c);
返回0;
}
//职能c------------------------------------------------
#包括“main.h”
#包括“func.h”
外部结构为[];
无效函数(无效){
as[0].a=1;
as[0].b=2;
as[0].c=3;
}

如果另一个模块中的
myStruct
是全局的,那么您可能正在查找
extern
关键字。把这个放在另一个模块中:

extern MyStruct_t myStruct[];
(我假设MyStruct\t是一个
typedef
ed名称。否则您当然需要在它前面加上关键字
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;
}
//main.h------------------------------------------------
类型定义结构{
INTA、b、c;
}AStruct;
//函数h------------------------------------------------
无效函数(void);
//main.c------------------------------------------------
#包括
#包括“main.h”
#包括“func.h”
AStruct为[100];
内部主(空){
func();
printf(“%d,%d,%d\n”,作为[0].a,作为[0].b,作为[0].c);
返回0;
}
//职能c------------------------------------------------
#包括“main.h”
#包括“func.h”
外部结构为[];
无效函数(无效){
as[0].a=1;
as[0].b=2;
as[0].c=3;
}

我想他不想要阵列的副本!我想他不想要阵列的副本!