Часть проблемы в том, что вы объявили один указатель и одну структуру. Ваши объявления эквивалентны:
struct node *list;
struct node root;
Именно поэтому '*
', указывающий на указатель, принадлежит имени переменной ( объявитель в стандартном), а не типу.
Другая часть проблемы заключается в том, что вы можете инициализировать переменную только в глобальной области видимости с (постоянным) инициализатором; Вы не можете писать назначения в глобальной области видимости.
Есть несколько способов исправить это:
typedef struct node *NodePtr;
NodePtr list = NULL, root = NULL;
struct node *list = NULL, *root = NULL;
struct node *list = NULL;
struct node *root = NULL;
Обратите внимание, что одной из многих причин не использовать #define
вместо typedef
является то, что:
#define NodePtr struct node * // BAD!
NodePtr list = NULL, root = NULL; // BAD!
создает именно ошибочную ситуацию в вопросе.
Обращение к некоторым сообщениям об ошибках:
kbc.c:8: warning: data definition has no type or storage class
Это относится к строке:
list = NULL;
Поскольку вы пишете в глобальной области видимости, это интерпретируется как определение переменной без явного типа. В настоящее время это ужасный стиль, но он был разрешен в оригинальном (предварительно стандартном) C с использованием правила «implicit- int
» для вывода типа - что также объясняет некоторые из последующих сообщений. Интерпретация 'implicit- int
' устарела в C89 и официально не поддерживается C99, но компиляторы по-прежнему распознают ее (с предупреждением, по крайней мере, в режиме C99).
Итак, это интерпретируется как:
int list = NULL;
Эти сообщения теперь поясняются:
kbc.c:8: error: conflicting types for ‘list’
kbc.c:7: note: previous declaration of ‘list’ was here
Вы написали код, который компилятор должен интерпретировать как второе объявление list
.
kbc.c:8: warning: initialization makes integer from pointer without a cast
И это объясняется; поскольку второй list
является int
и NULL
является константой нулевого указателя в этой реализации (вероятно, #define NULL ((void *)0)
), происходит преобразование из указателя в целое число без приведения.
Второй набор предупреждений применяется аналогично root
.