例如,假设我有这样的事情:
typedef struct one
{
int data;
int dogs;
}One;
typedef struct two
{
int data;
int birds;
}Two;
typedef struct three
{
int data;
int cats;
}Three;
void swapData(???* elem1, ???* elem2) //<- the problem is here
{
int temp = elem1->data;
elem1->data = elem2->data;
elem2->data = temp;
}
int main()
{
One dog;
Two bird;
Three cat;
dog.data = 1;
bird.data = 2;
cat.data = 3;
swapData(&dog, &cat);
swapData(&dog, &bird);
swapData(&bird, &cat);
return 0;
}
我必须用什么代替 ??? 才能接受指向 One , Two 或<的指针的函数em>三个结构作为参数? 我试过 void ,但后来我无法访问结构&#39;字段...
答案 0 :(得分:0)
你不能这样做,你要写3个独立的功能来实现这个目标......
void swapData13(one *elem1, three*elem2)
{
int temp = elem1->data;
elem1->data = elem2->data;
elem2->data = temp;
}
void swapData12(one *elem1, two*elem2)
{
int temp = elem1->data;
elem1->data = elem2->data;
elem2->data = temp;
}
void swapData23(two *elem1, three*elem2)
{
int temp = elem1->data;
elem1->data = elem2->data;
elem2->data = temp;
}
你在main
中传递参数的方式也是错误的......
你可以做......
swapData13(&dog, &cat);
swapData12(&dog, &bird);
swapData23(&bird, &cat);
出于好奇,你想通过编写这样的代码来实现什么目标?
答案 1 :(得分:0)
有几种选择。其中:
切换到C ++。然后,您可以从包含data
成员的公共基础结构派生您的三个结构。或者使用类而不是结构并执行相同的操作。 (这并不像听起来那么无益 - 大多数C编译器现在也编译C ++,切换可能就像更改文件扩展名或编译器标志一样简单。)
对第二个成员使用包含union的单个结构。这样,你只有一种类型可以处理。
使用不带联合的单个结构并命名第二个成员animals
。
创建一个包含Data
成员的结构data
,然后将其他任何成员“搭载”到该成员上。也就是说,确保Data
结构的实例是One
,Two
和Three
的第一个成员。当您只想参考公共部分时,请使用类型struct Data *
。
研究simulate OO-style polymorphism in C的方法。警告:它不漂亮。
将指针传递给每个结构中的data
成员,而不是指向整个结构的指针。
这是最后一个策略的一个例子:
void swapData(int* data1, int* data2)
{
int temp = *data1;
*data1 = *data2;
*data2 = temp;
}
// call it like this:
swapData(&(dog->data), &(cat->data));
任何你切片的方式,swapData()
函数都需要知道它正在处理什么。普通的旧C不提供继承多态,因此没有一种直接的方法来创建包含所有三个结构的单个基类型。因此,您必须求助于传递结构的一部分,或将结构转换为更简单的类型等。由于data
成员实际上是每个结构中的第一个项目,因此您可以使用{{ 1}}我在上面提供了但稍微简化了调用:
swapData()
虽然它更短,但是很难理解(或者更容易误解)。
答案 2 :(得分:0)
创建另一个这样的数据结构:
struct typee{
int ele1;
int ele2;
}id;
填充元素时:
id.ele1 = DOGS; // #define DOGS 1
id.ele2 = CATS; // #define CATS 2
功能定义:
void swapData(void* elem1, void* elem2, struct typee id) //<- addind new argument
{
//using id, type cast the ele1 and ele2 to theier structures
...
}
我的建议:
typedef struct generic //only One structure at all
{
int data;
int specie;
}all;
main()
{
struct generic dog;
struct generic cat;
.... // filling structure elements
swapData(&dog, &cat);
...
}
功能定义:
void swapData(struct generic * elem1, struct generic* elem2)
{
int temp = elem1->data;
elem1->data = elem2->data;
elem2->data = temp;
}
答案 3 :(得分:0)
要明确我不明白这个的确切需要,但如果只有3个案例,那么你可以编码这样的东西,
void swapData(void* elem1, void* elem2, int type)
{
if( type == 0 ) //type == 0 corresponds to comparison of One & Two
{
One *e1 = (One*)elem1;
Two *e2 = (Two*)elem2;
int temp = e1->data;
e1->data = e2->data;
e2->data = temp;
}
else if(type == 1) //type == 1 corresponds to comparison of One & Three
{
One *e1 = (One*)elem1;
Three *e2 = (Three*)elem2;
int temp = e1->data;
e1->data = e2->data;
e2->data = temp;
}
else
{
//type == 2 corresponds to comparison of Two & Three
}
}
使用第三个参数
从主函数调用swapData(&dog,&bird,0);
对于较高的情况,这种方法效率不高
答案 4 :(得分:0)
如果您始终在每个结构中首先定义data
,并且data
始终是int,那么您可以执行以下操作:
void swapData(void* elem1, void* elem2) //<- the problem is here
{
int* e1 = (int*) elem1;
int* e2 = (int*) elem2;
int temp = e1[0];
e1[0] = e2[0];
e2[0] = temp;
}
这样做的原因是因为当你传递一个void *时,你会得到大小为sizeof(One)
的内存或者你输入的内容。因为data
是第一个,我们可以假装你传入一个整数数组,并取第一个。如果你有一个更复杂的结构,你可以构建一个结构,其中前几个元素与你传入的任何结构的类型相同。这样你就可以操作多个对象。看起来像这样:
typedef struct {
int data;
char * name;
...
} complicated;
typedef struct {
int data;
char * name;
int something_else;
} simple;
typedef struct { // least common denominator
int data;
char * name;
} common;
void swap(void * e1, void* e2){
common* c1 = (common*) e1;
common* c2 = (common*) e2;
int tmp = c1->data;
char * tmpn = c1->name;
c1->data = c2->data;
c1->name = c2->name;
c2->data = tmp;
c2->name = tmp;
}
希望这是有道理的。