接收指向不同调用中不同结构的指针作为参数(或类似的东西)

时间:2014-05-12 04:28:47

标签: c struct

例如,假设我有这样的事情:

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;字段...

5 个答案:

答案 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结构的实例是OneTwoThree的第一个成员。当您只想参考公共部分时,请使用类型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;
}

希望这是有道理的。