#c #struct
Вопрос:
у меня есть следующая структура:
struct node {
char *data;
struct node *next;
};
Я хочу инициализировать его некоторыми уже известными значениями.
Например:
struct node {
char *data;
struct node *next;
} *root = amp;(struct node){"data1", amp;(struct node){"data2", NULL}};
Можно ли получить адрес структуры, содержащей «data2»?
или назначить root структуре, содержащей «data2»?
Редактировать:
Я хочу сделать следующее во время компиляции с составными литералами:
struct node *b = amp;(struct node){"data2", NULL};
struct node *a = amp;(struct node){"data1", b};
a = b;
Правка2:
что-то вроде того:
struct node {
char *data;
struct node *next;
};
struct node *tmp, *root = amp;(struct node){"data1", tmp = amp;(struct node){"data2", root}};
root = tmp;
но я не хочу, чтобы tmp существовал во время выполнения
Комментарии:
1. Вопрос довольно неясен. Работает ли ваш код? Если нет, то в чем заключается ошибка или нежелательное поведение?
2.
root
имеет типstruct node *
, поэтому он не может указывать на поляnext
илиdata
экземпляраstruct node
, не обходя систему типов (и даже если бы это было возможно, это было бы бесполезно). Если у вас есть фактический экземплярstruct node
(в отличие от простого указателя), вы можете указать на него указатель или присвоить указателю текущее значениеnext
поля. Но в опубликованном коде нет экземпляра.3. Осурсолл, как насчет
struct node root1 = {"Hello World", amp;root1};
.amp;root1
может быть использован в более позднем коде, где требуется указатель.4.
static struct node {...} a = { 'a', 0 }, b = { 'b', amp;a }, c = { 'c', amp;b };
работаетclang -Wall -Wextra -pedantic -Weverything
, но я все еще не уверен, что использование адреса переменных таким образом переносимо. Хороший вопрос.
Ответ №1:
Я думаю, вы ищете что-то вроде:
#include<stdio.h>
struct node { char *data; struct node *next; }
b = {"data2", NULL}, a = {"data1", amp;b}, *root = amp;b;
int
main(void)
{
printf("%sn", root->data);
return 0;
}
или, может быть,:
struct node { char *data; struct node *next; };
struct node *a = amp;(struct node){"data1", amp;(struct node){"data2", NULL}} ;
int
main(void)
{
struct node *b = a->next;
return 0;
}
Комментарии:
1. Я не уверен, что понимаю. Я изменил код; вы хотите сказать, что хотите
struct node *root = amp;c
?2. @OsourceAll отредактировал решение, чтобы, возможно, дать вам то, что вы хотите. Хотя это не совсем так.
3. Но я не понимаю, почему вы объявляете свой объект типами указателей, а не просто делаете:
struct node { char *data; struct node *next; } b = {"data2", NULL}, a = {"data1", amp;b};
Ответ №2:
Если вы хотите статически инициализировать два разных указателя на один и тот же объект, вам необходимо назвать этот объект и использовать его адрес. Например:
struct node {
char *data;
struct node *next;
};
char last_data[] = "last_data";
char* last_data_ptr = last_data;
struct node last_node = (struct node){last_data, NULL};
struct node* last_node_ptr = amp;last_node;
struct node* list = amp;(struct node){"first_data", amp;last_node};
Здесь amp;last_node
используется дважды: один раз для инициализации last_node_ptr
и один раз для инициализации поля в безымянной структуре, которое используется для инициализации list
. Аналогично, last_data
используется дважды, один раз для last_data_ptr
и один раз для поля в last_node
. Вы не можете сделать это с буквальным. Он может инициализировать только одну переменную.
Вот как можно создать циклический связанный список:
struct node
{
char* data;
struct node* next;
} list = {"one", amp;(struct node){"two", amp;(struct node){"three", amp;list}}};
struct node *root = amp;list;
Комментарии:
1. «инициализировать корень до значения его следующего поля», похоже, не имеет для меня никакого смысла. Корень и его следующее поле-это две разные вещи. Если вы хотите иметь узел со следующим полем, указывающим на какой-либо «следующий» узел, и другим указателем с именем «корень», указывающим на тот же «следующий» узел, прочитайте ответ еще раз. Если вы хотите
root
быть указателем на указательstruct node
и указывать на адрес поля какого-либо узла, то нет, это невозможно.2. Если вам нужен круговой связанный список, почему бы не сказать, что вам нужен круговой связанный список прямо в вопросе?
3. Пример наличия адреса последнего узла был в ответе с самого начала. Ваши обновления не имеют для меня особого смысла, извините. Они пропускают статическую память и создают неинициализированные указатели.
4.
struct node last_node = (struct node){last_data, NULL};
Оно есть и было там все время. Но это правда, что я понятия не имею, чего ты на самом деле хочешь.