Передача структур по ссылке? [С]

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

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

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

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

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


person Blackbinary    schedule 29.03.2010    source источник


Ответы (4)


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

person Alexey B.    schedule 29.03.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;
};
person Nikolai Fetissov    schedule 29.03.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;
 }
person Hobblin    schedule 29.03.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. Вы можете использовать менее общую структуру данных. Например, вы можете пропустить индексы через объект-человек:

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

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

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

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

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

person geocar    schedule 29.03.2010