передавая различные структуры функции в с - PullRequest
0 голосов
/ 23 марта 2010

У меня разные структуры, которые нужно заполнять одинаково. Разница лишь в том, что они заполняются на основе разных данных.

Мне было интересно, возможно ли передать различные структуры определенной функции. Я имею в виду что-то вроде:

struct stu1 {
    char *a;
    int  b;
};

struct stu2 {
    char *a;
    int  b;
};

static struct not_sure **some_func(struct not_sure **not_sure_here, original_content_list)
{
        // do something and return passed struct
        the_struct = (struct not_sure_here **)malloc(sizeof(struct not_sure_here *)20);
        for(i=0; i<size_of_original_content_list; i++){
           //fill out passed structure
        }
    return the_struct; 
}

int main(int argc, char *argv[]) 
{
        struct stu1 **s1;
        struct stu2 **s2;
        return_struct1 = some_func(stu1);
        return_struct2 = some_func(stu2);
        // do something separate with each return struct...
}

Любые комментарии будут благодарны.

Ответы [ 3 ]

3 голосов
/ 23 марта 2010

Вы можете сделать своего рода «наследование» в C, используя вложенные структуры.

Примерно так:

struct Derived {
  struct Base b;
  int another_i;
  char another_c;
};

struct Derived_2 {
  struct Base b;
};

Тогда это безопасно:

struct Derived d;
struct Derived_2 d2;
set_base( (struct Base*)&d );
set_base( (struct Base*)&d2 );

Это безопасно, потому что это первый участник.Конечно, в другое время вы можете вызывать их более безопасным для типов способом, например

set_base( &d.b );

Но это может быть неудобно в цикле по указателям на неизвестные типы объектов.

1 голос
/ 23 марта 2010

В C указатель на структуру - это просто указатель памяти. Итак, да, можно передать указатель на любую структуру функции. Однако для того, чтобы сделать полезную работу над ней, функция должна знать макет структуры.

В вашем примере макет такой же, поэтому он будет "безопасным" ... но это может быть рискованно, если одна из структур внезапно изменила формат, и функция не была обновлена ​​для учета этого изменения.

0 голосов
/ 23 марта 2010

Полагаю, вы имеете в виду, что структуры содержат одинаковые типы данных и отличаются только имена полей? Если это так, у вас есть два варианта:

1) Создайте тип объединения, который содержит обе эти структуры, и передайте его в some_func. Затем он может заполнить любого из членов объединения - не имеет значения, какой из них, так как схема памяти этих двух элементов абсолютно одинакова, поэтому он будет иметь тот же эффект.

2) Просто заставьте some_func взять одну из структур в качестве параметра, а когда вы хотите передать другую, приведите ее к первой. Опять же, поскольку расположение памяти одинаково, оно будет работать нормально, т. Е.

static struct stu1 **some_func(struct stu1 *not_sure_here, original_content_list)
{
  ...
}

int main(int argc, char *argv[]) 
{
        return_struct1 = some_func(stu1);
        return_struct2 = (struct stu2)some_func((struct stu1)stu2);
}
...