道歉,我只是在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_s foo)
时出现问题。它需要能够在任何给定时间接受FooRead_s
或FooWrite_s
,即使它们不同。如何允许BarFunction
同时接受FooRead_s
和FooWrite_s
?
答案 0 :(得分:2)
在C语言中,没有一些选择器参数就无法区分两个或多个结构。可以使用结构FooRead_s
,FooWrite_s
和操作选择器的并集。
选择器可以作为单独的参数传递
typedef union {
FooRead_s rs;
FooWrite_s ws;
} Foo_params;
void BarFunction(bool write, Foo_params *foo) {
if (write) {
// use foo->ws;
}
// ...
}
或嵌入到结构中
typedef struct {
bool write;
union {
FooRead_s rs;
FooWrite_s ws;
} params;
} Foo_action;
void BarFunction(Foo_action *foo) {
if (foo->write) {
// use foo->params.ws;
}
}
答案 1 :(得分:2)
如果我们纠正您的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
}