Я пытаюсь использовать структуру в качестве контейнера функций, но не могу этого сделать.
Вот мой код для структуры с псевдонимом methods
typedef struct {
void (*addAtHead)(LinkedList*,int);
void (*addAtTail)(LinkedList*,int);
void (*remFromHead)(LinkedList*);
void (*remFromTail)(LinkedList*);
}methods;
И здесь я указываю указатели methods
на соответствующие функции.
methods LinkedListF;
LinkedListF.addAtHead = addAtH;
LinkedListF.addAtTail = addAtT;
LinkedListF.remFromHead = remFromH;
LinkedListF.remFromTail = remFromT;
Ожидалось, что вызов функции LinkedListF.addAtHead(LinkedList *l,int value)
вызовет addAtH
, но во время компиляции выдало
LinkedList.c:43:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
43 | LinkedListF.addAtHead = addAtH;
....and more errors
Я проверил, что нет пропущенных точек с запятой или других ошибок, а также, если я попробую использовать следующий код, он правильно скомпилируется.
methods LinkedListF = {addAtH,addAtT,remFromH,remFromT};
Может кто-нибудь объяснить, где я делаю неправильно?
LinkedListF.addAtHead(LinkedList *l,int value)
не является вызовом функции. LinkedListF.addAtHead(&list,42)
— вызов функции.
Совет: меня methods LinkedListF;
очень сбивает с толку. Я ожидаю, что используемый тип будет содержать прописные буквы, и я ожидаю, что все переменные будут строчными (Methods linked_list;
).
@Стивен Ньюэлл, я одобрил вопрос с подготовительной площадки, потому что предоставленный ими код - это все, что нужно для воспроизведения проблемы (хотя добавление typedef struct { int x; } LinkedList;
делает ее более понятной).
Независимо от проблемы, вам следует взять за привычку всегда использовать typedef
при работе с указателями на функции. То есть typedef void AddAtHead_t(LinkedList*,int);
то AddAtHead_t* addAtHead;
.
@ikegami - Я предполагал, что это похоже на многие вопросы, в которых копируется/вставляется какая-то случайная часть функции. Мне не пришло в голову, что спрашивающий пытался установить переменные-члены вне функции.
@Стивен Ньюэлл, да, я знаю. И ты не единственный. Пытаюсь избежать закрытия вопроса из-за недостаточной детализации. (Хотя там, наверное, обман.)
У вас есть следующее вне функции:
methods LinkedListF;
LinkedListF.addAtHead = addAtH;
LinkedListF.addAtTail = addAtT;
LinkedListF.remFromHead = remFromH;
LinkedListF.remFromTail = remFromT;
Вне функций разрешены только объявления. Последние четыре из этих строк являются не объявлениями, а выражениями, которые можно найти только внутри функций.
Это работает внутри функции.
Желаемый эффект также можно получить, используя объявление с инициализатором.
methods LinkedListF = { addAtH, addAtT, remFromH, remFromT };
methods LinkedListF = {
.addAtHead = addAtH,
.addAtTail = addAtT,
.remFromHead = remFromH,
.remFromTail = remFromT,
};
Они работают внутри или вне функции.
И неудачный, и рабочий подходы используют =
, но =
внутри объявления обозначает инициализатор, а не присваивание.
Возможно, покажете, как его инициализировать инициализатором?
@Ian Abbott, это уже вопрос
Так и есть. Я пропустил этот момент! Тем не менее, его можно улучшить с помощью назначенных инициализаторов.
@ Ян Эбботт, добавлено.