C 两种不同类型的结构-需要动态地将一种传递给函数
提前道歉,我2个月前才开始写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;
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
),以减少调用方错误的风险。是的,最好在一个对象中保留带有联合的标记。可能值得指出的是,与其他答案不同,这是一种编译时解决方案。可能值得指出的是,与其他答案不同,这是一个编译时解决方案。