Как использовать структуру в C? - PullRequest
12 голосов
/ 06 августа 2009

Это код для связанного списка на языке программирования C.

#include <stdio.h>    /* For printf */
#include <stdlib.h>   /* For malloc */

typedef struct node {
    int data;
    struct node *next; /* Pointer to next element in list */
} LLIST;

LLIST *list_add(LLIST **p, int i);
void list_remove(LLIST **p);
LLIST **list_search(LLIST **n, int i);
void list_print(LLIST *n);

Код не завершен, но я думаю, что этого достаточно для моего вопроса. Здесь в конце структурного узла используется «LLIST», и он также используется как тип возвращаемого значения в прототипировании функции list_add. Что происходит?

Ответы [ 5 ]

24 голосов
/ 06 августа 2009

Это typedef. Это на самом деле делает две вещи одновременно. Во-первых, он определяет структуру:

struct node {
    int data;
    struct node *next;
}

А затем делает typedef:

typedef struct node LLIST;

Это означает, что LLIST - это тип, такой же как int или FILE или char, который является сокращением для struct node, вашей структуры узла связанного списка. В этом нет необходимости - вы можете заменить LLIST на struct node во всех этих местах - но это немного облегчает чтение и помогает скрыть реализацию от надоедливых конечных пользователей.

10 голосов
/ 06 августа 2009

C требует, чтобы вы ссылались на структуры с префиксом "struct", поэтому обычно вводите typedef для более подробного упоминания.

То есть объявление вашей структуры состоит из двух частей и может быть переписано следующим образом:

struct node {
    int data;
    struct node *next; /* pointer to next element in list */
};

typedef struct node LLIST;

Итак, LLIST - это просто другое имя для struct node (спасибо Крис Латс).

10 голосов
/ 06 августа 2009

LLIST - это просто другое имя типа для созданной структуры. В общем, следующий формат создаст тип «NAME», который является «struct x»:

typedef struct x { ... } NAME;
6 голосов
/ 06 августа 2009

typedef создает новый «тип» в вашей программе, поэтому возвращаемое значение и типы параметров этих функций - это просто ваша структура. Это просто сокращение для использования struct node для типа.

Если бы вы создали новый узел, вы могли бы сделать это так (используя тип):

LLIST *node = malloc(sizeof(LLIST));
node->data = 4;
node->next = someOtherItem;
list_add(node, 1)

Кроме того, с прототипами функций в вашем вопросе вам не нужны двойные указатели; поскольку данные в вашей структуре просто int, вы можете сделать что-то вроде

LLIST *list_add(int data, int position);

тогда функция list_add будет обрабатывать выделение, скопировать int в структуру и добавить его в связанный список.

Поместить его в определенную позицию так же просто, как изменить указатель next в узле перед ним на адрес вновь выделенного узла и указатель next в новом узле, чтобы он указывал на следующий. (тот, на который ранее указывал узел),

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

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

3 голосов
/ 06 августа 2009

LLIST* - указатель на структуру, определенную структурой LLIST.

Вы должны сделать

LLIST* myList = malloc(sizeof(LLIST)*number_of_elements);

чтобы выделить память для этого списка. Добавление и удаление элементов требует перераспределения памяти с помощью realloc. Я уже написал некоторый кусок кода для списков (сделанный с массивами).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...