C 两种不同类型的结构-需要动态地将一种传递给函数

C 两种不同类型的结构-需要动态地将一种传递给函数,c,struct,C,Struct,提前道歉,我2个月前才开始写C,所以这对我来说是全新的 我正在开发一个代码库,它已经实现了一个需要更改的解决方案 目前,一个结构包含读/写功能的所有变量。这需要修改为两个不同的结构,一个用于读取,一个用于写入 以下是当前的实施情况 typedef struct Foo_s { int x; int y; int z; } BarFunction(Foo_s foo) { //logic } 以下是我需要做的更改 typedef struct FooRead_s { int x;

提前道歉,我2个月前才开始写C,所以这对我来说是全新的

我正在开发一个代码库,它已经实现了一个需要更改的解决方案

目前,一个结构包含读/写功能的所有变量。这需要修改为两个不同的结构,一个用于读取,一个用于写入

以下是当前的实施情况

typedef struct Foo_s
{
 int x;
 int y;
 int z;
}

BarFunction(Foo_s foo) {
 //logic
}
以下是我需要做的更改

typedef struct FooRead_s
{
 int x;
 int y;
}

typedef struct FooWrite_s
{
 int z;
}

调用
BarFunction(Foo\u s Foo)
时会出现问题。它需要能够在任何给定时间接受
FooRead\u
foorewrite\u
,即使它们不同。如何允许
BarFunction
同时接受
FooRead\u s
FooWrite\u s

在C中,如果没有一些选择器参数,就无法区分两个或多个结构。可以使用结构的并集
FooRead\u s
FooWrite\u s
和操作选择器。 选择器可以作为单独的参数传递

typedef联合{
食物;
fooswrite_s ws;
}福乌参数;
void bar函数(bool write,Foo_参数*Foo){
如果(写入){
//使用foo->ws;
}
// ...
}
或嵌入结构中

typedef结构{
布尔写;
联合{
食物;
fooswrite_s ws;
}参数;
}富奥行动;
void bar函数(Foo_action*Foo){
如果(foo->write){
//使用foo->params.ws;
}
}

在C中,如果没有一些选择器参数,就无法区分两个或多个结构。可以使用结构的并集
FooRead\u s
FooWrite\u s
和操作选择器。 选择器可以作为单独的参数传递

typedef联合{
食物;
fooswrite_s ws;
}福乌参数;
void bar函数(bool write,Foo_参数*Foo){
如果(写入){
//使用foo->ws;
}
// ...
}
或嵌入结构中

typedef结构{
布尔写;
联合{
食物;
fooswrite_s ws;
}参数;
}富奥行动;
void bar函数(Foo_action*Foo){
如果(foo->write){
//使用foo->params.ws;
}
}

如果我们纠正您的typedef并编写函数来接受指针传递的结构(正如它应该被设计的那样),那么我们最终会得到以下结果:

typedef struct 
{
  int x;
  int y;
} FooRead_s;

typedef struct 
{
  int z;
} FooWrite_s;

void BarFunction_Read (FooRead_s* foo) {
 //logic
}

void BarFunction_Write (FooWrite_s* foo) {
 //logic
}
现在,如果您可以选择使用标准C语言,则可以使用泛型编程编写函数调用:

#define BarFunction(foo)                    \
  _Generic((foo),                           \
           FooRead_s*:  BarFunction_Read,   \
           FooWrite_s*: BarFunction_Write)(foo)

int main (void)
{
  FooRead_s read = {0};
  FooWrite_s write = {0};

  BarFunction(&read);
  BarFunction(&write);
  //BarFunction(read); compiler error here as we should have
}

如果我们更正您的typedef并编写函数来接受指针传递的结构(它应该是设计的),那么我们最终会得到以下结果:

typedef struct 
{
  int x;
  int y;
} FooRead_s;

typedef struct 
{
  int z;
} FooWrite_s;

void BarFunction_Read (FooRead_s* foo) {
 //logic
}

void BarFunction_Write (FooWrite_s* foo) {
 //logic
}
现在,如果您可以选择使用标准C语言,则可以使用泛型编程编写函数调用:

#define BarFunction(foo)                    \
  _Generic((foo),                           \
           FooRead_s*:  BarFunction_Read,   \
           FooWrite_s*: BarFunction_Write)(foo)

int main (void)
{
  FooRead_s read = {0};
  FooWrite_s write = {0};

  BarFunction(&read);
  BarFunction(&write);
  //BarFunction(read); compiler error here as we should have
}

我敢打赌你的项目范围也包括拆分功能。因此,现在有两个函数,一个用于读取,一个用于写入。您必须重构代码,C中的函数可以采用
foodread\u s
foodwrite\u s
,但对于同一个参数,不能同时采用这两个函数。拆分de功能。当我向架构师询问更多信息时,他非常确定只剩下一个功能。如果架构师的建议与语言本身的工作方式相冲突,你应该回去与他们解决细节问题。也许你们之间有误会。我敢打赌你们项目的范围也包括拆分功能。因此,现在有两个函数,一个用于读取,一个用于写入。您必须重构代码,C中的函数可以采用
foodread\u s
foodwrite\u s
,但对于同一个参数,不能同时采用这两个函数。拆分de功能。当我向架构师询问更多信息时,他非常确定只剩下一个功能。如果架构师的建议与语言本身的工作方式相冲突,你应该回去与他们解决细节问题。也许你们之间有误会,这是我们期望的解决方案。操作:如果可能,请使用标记的联合(即,在结构中放置
bool write
),以减少调用方错误的风险。是的,最好将带有联合的标记保留在一个对象中。这是预期的解决方案。To OP:如果可能的话,请使用标记的联合(即在结构中放入
bool write
),以减少调用方错误的风险。是的,最好在一个对象中保留带有联合的标记。可能值得指出的是,与其他答案不同,这是一种编译时解决方案。可能值得指出的是,与其他答案不同,这是一个编译时解决方案。