Использование указателя функции внутри структуры

Я пытаюсь использовать структуру в качестве контейнера функций, но не могу этого сделать. Вот мой код для структуры с псевдонимом 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) — вызов функции.
Ian Abbott 15.08.2024 15:18

Совет: меня methods LinkedListF; очень сбивает с толку. Я ожидаю, что используемый тип будет содержать прописные буквы, и я ожидаю, что все переменные будут строчными (Methods linked_list;).

ikegami 15.08.2024 15:21

@Стивен Ньюэлл, я одобрил вопрос с подготовительной площадки, потому что предоставленный ими код - это все, что нужно для воспроизведения проблемы (хотя добавление typedef struct { int x; } LinkedList; делает ее более понятной).

ikegami 15.08.2024 15:37

Независимо от проблемы, вам следует взять за привычку всегда использовать typedef при работе с указателями на функции. То есть typedef void AddAtHead_t(LinkedList*,int); то AddAtHead_t* addAtHead;.

Lundin 15.08.2024 15:41

@ikegami - Я предполагал, что это похоже на многие вопросы, в которых копируется/вставляется какая-то случайная часть функции. Мне не пришло в голову, что спрашивающий пытался установить переменные-члены вне функции.

Stephen Newell 15.08.2024 16:31

@Стивен Ньюэлл, да, я знаю. И ты не единственный. Пытаюсь избежать закрытия вопроса из-за недостаточной детализации. (Хотя там, наверное, обман.)

ikegami 15.08.2024 16:35
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

У вас есть следующее вне функции:

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 15.08.2024 15:21

@Ian Abbott, это уже вопрос

ikegami 15.08.2024 15:22

Так и есть. Я пропустил этот момент! Тем не менее, его можно улучшить с помощью назначенных инициализаторов.

Ian Abbott 15.08.2024 15:25

@ Ян Эбботт, добавлено.

ikegami 15.08.2024 15:27

Другие вопросы по теме