Passing two different structs into same function

我们两清 提交于 2020-06-11 03:10:24

问题


I have 2 different sized structs and I would like to have one function in which I can pass them into. However, I do not know how to define the parameter of the function to accept 2 different structs.

My structs are below

struct {
    int a;             // 2 byte
    int b;             // 2 byte
    int c;             // 2 byte
    int d;             // 2 byte
}  person1;                // 8 bytes


struct {
    int a;            // 2 byte
    DeviceAddress b;  // 8 bytes
    int c             // 2 bytes
    float d;      // 4 bytes
}  person2;               // 16 bytes

function print_struct(struct& ?????)
{
     actions here....
}


print_struct(person1);
print_struct(person2);

回答1:


Unfortunately, the only choice for unrelated structures in C is to pass pointers to the structures untyped (i.e. as void*), and pass the type "on the side", like this:

struct person1_t {
    int a;             // 2 byte
    int b;             // 2 byte
    int c;             // 2 byte
    int d;             // 2 byte
}  person1;

struct person2_t {
    int a;            // 2 byte
    DeviceAddress b;  // 8 bytes
    int c             // 2 bytes
    float d;      // 4 bytes
}  person2;

void print_struct(void* ptr, int structKind) {
    switch (structKind) {
        case 1:
            struct person1 *p1 = (struct person1_t*)ptr;
            // Print p1->a, p1->b, and so on
            break;
        case 2:
            struct person2 *p2 = (struct person2_t*)ptr;
            // Print p2->a, p2->b, and so on
            break;
    }
}

print_struct(&person1, 1);
print_struct(&person2, 2);

This approach is highly error-prone, though, because the compiler cannot do type checking for you.




回答2:


It's not really possible. You could create a union that holds the two structs plus some kind of identifier. You then pass the union in and use the identifier to work out which struct is contained in it.

typedef struct sp1 {
    int a;             // 2 byte
    int b;             // 2 byte
    int c;             // 2 byte
    int d;             // 2 byte
}  person1_t;          // 8 bytes


typedef struct sp2 {
    int a;            // 2 byte
    DeviceAddress b;  // 8 bytes
    int c             // 2 bytes
    float d;          // 4 bytes
}  person2_t;         // 16 bytes

typedef union {
    person1_t person1;
    person2_t person2;
} people;

function print_struct(people *p, int id) // e.g. id == 1, struct is person1
{
    switch (id)
    {
         case 1: // Do person 1 things
         break;

         case 2: // Do person 2 things
         break;

         default: // Error
         break;
    }
}



回答3:


As dasblinkenlight put it, if you wanted to be able to pass two different structs into the functions, using void * to pass a generic pointer would be the way to go, however, doing so is not type safe and could easily lead to error-prone code.

What functionality are you trying to achieve by having two separate structs? You could consider combining the information into a single struct instead, and having a print function that prints out all non zero values?

Forgive the perhaps non-optimal c code, I am far from an expert, this is just to illustrate the point :)

typedef struct datastruct {
    int a;
    int b;
    float c;
} datastruct;

void printData(datastruct *d){

    printf("Data:\n")
    printf((d->a) ? "a=%d", a : "");
    printf((d->b) ? "b=%d", b : "");
    printf((d->c) ? "c=%.2f", c : "");
    printf("\n");
}

int main(void) {

    datastruct data = {0};
    /* now set values as needed */

    printData(&data);

    return 0;
}



回答4:


typedef struct p1 {
    int a;             // 2 byte
    int b;             // 2 byte
    int c;             // 2 byte
    int d;             // 2 byte
} person1;                // 8 bytes


typedef struct p2{
    int a;            // 2 byte
    DeviceAddress b;  // 8 bytes
    int c             // 2 bytes
    float d;      // 4 bytes
} person2;               // 16 bytes

typedef enum ptypes {
    PERSON1,
    PERSON2
} person_type;

typedef union p1_or_p2 {
    person1 p1;
    person2 p2;
} person1_or_person2;

typedef struct p {
    person1_or_person2 person;
    person_type type;
} person;

// Creating a person struct variable:
person p;
person1 p1;
p1.a = 5;
p1.b = 2;
p.type = PERSON1;
p.person = (person1_or_person2) p1;

void print_struct(person p) {
     switch (p.type) {
        case PERSON1:
            // actions for person1 here....
              // you can access person1 like this:
                 p.person.p1;
        break;
        case PERSON2:
            // actions for person2 here....
              // you can access person2 like this:
                 p.person.p2;
        break;
     }
}


来源:https://stackoverflow.com/questions/14324182/passing-two-different-structs-into-same-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!