Передача структур по ссылке? [С] - PullRequest
2 голосов
/ 29 марта 2010

Я пытаюсь создать связанный список с двумя отдельными списками в одной структуре. То есть он содержит значение «имя» и «возраст». Затем программа может либо вывести список, отсортированный по имени, либо отсортированный по возрасту. Поэтому мне нужны два связанных списка, по сути.

Однако мне нужно, чтобы программа знала о корне / заголовке как списка имен, так и списка возраста.

Я не уверен, как отправить это в мою функцию.

У меня уже будет имя и возраст, который я хочу добавить в каждый список, и затем мне придется каким-то образом отправить его в начало каждого списка. Поскольку есть две головы, которые я хочу вернуть, я не могу использовать функцию возврата. Как я могу сообщить своему основному об изменениях в заголовках / корневых списках?

Надеюсь, вопрос ясен, и спасибо за ответы!

Ответы [ 4 ]

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

Вы можете связать один элемент списка в два списка и отсортировать их независимо:

/* List item is linked into two lists */
struct list
{
    struct list* name_next; /* next in name list */
    struct list* age_next;  /* next in age list */

    char*    name;
    unsigned age;
};

/* Holds both list heads */
struct book
{
    struct list* name_sorted;
    struct list* age_sorted;
};
1 голос
/ 29 марта 2010

Вы можете обернуть обе головы в одну структуру.

0 голосов
/ 29 марта 2010
  1. Вы можете использовать указатели в качестве Царства Рыб Рекомендуется . Я просто хотел добавить, что ваша документация должна указывать, что эти значения являются «выходными данными», хотя они и являются параметрами.

  2. Вы можете использовать тип данных кортежа. Вот простой:

    typedef struct Tuple{void*a,*b;}*Tuple;
    Tuple tuple(void*a,void*b){
      Tuple z=malloc(sizeof(struct Tuple));
      z->a=a,z->b=b;
      return z;
    }
    

    Однако следует помнить, что отслеживание динамического выделения памяти может быть затруднено, и, если вы не используете сборщик мусора , вам нужно быть очень осторожным.

  3. Вы можете использовать менее общую структуру данных. Например, вы могли бы пропустить индексы через person-объект:

    struct Person;typedef struct Person*Person;
    struct Person{Person*prev_by_name,*next_by_name,*prev_by_age,*next_by_age; ...};
    

    Добавление дополнительных индексов (связанных списков) становится тривиальным, и если вы подумаете над этим, вы можете заставить препроцессор выполнять большую часть работы за вас.

    Этот метод также дает вам возможность спросить «кто следующий после Дэйва младший»

    Наконец, благодаря такой обработке потоков все обновления индексов человека будут храниться вместе, что упростит избежание ошибок синхронизации.

  4. Вы можете использовать отдельные функции и просто «запомнить», чтобы вызвать их обе. Если это для домашней работы, и вы еще не рассмотрели, как вернуть несколько значений, то вы можете выбрать это «решение» просто потому, что это, вероятно, то, что ищет ваш учитель.

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

Вы можете просто передать указатель на указатель на две головы в качестве аргумента и затем без проблем изменить указатель.

 void list_add(char *name, int age, list_type *list, list_type **name_head, list_type **age_head)
 {
     /* Add the name and age and calculate the two heads. */
     (*name_head) = calculated_head;
     (*age_head) = calculated_head;
 }
...