Инициализация массива структур в C затем разыменовывается позже

Я пытаюсь построить последовательный интерпретатор команд, поэтому я хочу сохранить мои команды в массиве. Я хочу, чтобы каждая команда имела имя и указатель на функцию, чтобы я мог сравнить имя команды с тем, что я ввел, а затем вызвать функцию. Я не так хорош с C, поэтому, пожалуйста, помогите! Вот что я до сих пор.

Массив команд будет массивом структур. Каждая структура будет содержать строку и указатель на функцию. Здесь есть ошибки, но я не знаю, как их исправить. Это делается до основного.

typedef struct cmdStruct {
    char cmd[16];
    void (*cmdFuncPtr)(void);
}CmdStruct;

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

//build array of structs
CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

Позже я перейду через массив struct, чтобы сравнить его с полученной командой.

// go through the struct array to do string comparison on each struct's string member
for (int i = 0; i < sizeof(cmdStructArray); i++) {
   //string comparison of received command and string of struct
    if(strcmp(cmdStructArray[i].cmd, receivedCmd)==0) {
       //dereference function pointer
        (*cmdStructArray[i].cmdFuncPtr)(void);
    }
}

Какие части я делаю неправильно, и как их исправить?

0
nl ja de
Вы выполняете итерацию i до sizeof (CmdStructArray), т.е. 16 * sizeof (char) + размер указателя (на вашем компьютере). который определенно больше, чем в вашем случае.
добавлено автор Sibi Rajasekaran, источник
Каковы ошибки?
добавлено автор OldProgrammer, источник

2 ответы

sizeof(cmdStructArray) is not in elements, but rather in bytes.

Используйте sizeof (cmdStructArray)/sizeof (cmdStructArray [0]) .

4
добавлено

Как уже отмечалось, ваш цикл делает неправильное количество итераций. sizeof array дает вам количество элементов в массиве, а скорее количество байтов в массиве. Вы должны вычислить sizeof array/sizeof * array , чтобы получить количество элементов.

Кроме того, ваш синтаксис вызова функции недействителен

 (*cmdStructArray[i].cmdFuncPtr)(void);

Вышеуказанное не будет компилироваться. Вы не можете указать void как аргумент в вызове функции. Синтаксис (void) может использоваться только в объявлениях функций. Если функция не принимает никаких параметров, вызов должен выглядеть так:

 (*cmdStructArray[i].cmdFuncPtr)();

Кроме того, это также не будет компилироваться

CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

Почему вы дважды упоминаете cmdStructArray в этом объявлении?


Некоторые дополнительные, по существу косметические замечания:

Во-первых, поскольку ваши команды, вероятно, будут строковыми литералами, известными во время компиляции, вы можете объявить первый член своей структуры как указатель const char * вместо char array

typedef struct cmdStruct {
  const char *cmd;
  void (*cmdFuncPtr)(void);
} CmdStruct;

Синтаксис инициализации не изменяется. Это избавит вас от необходимости беспокоиться о размере массива ( 16 ), который у вас там есть.

Во-вторых, непонятно, почему вам нужно было объявить промежуточные указатели на функции ledFuncPtr и cmd2FuncPtr вместо инициализации вашего массива напрямую. Какова была цель этого

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

CmdStruct cmdStructArray[] = { {"led",   ledFuncPtr  },
                               {"cmd2",  cmd2FuncPtr }, };

когда вы могли бы просто сделать это

CmdStruct cmdStructArray[] = { {"led",   &LedFunction  },
                               {"cmd2",  &Cmd2Function }, };

(без ввода ledFuncPtr и cmd2FuncPtr вообще)?

Thirdly, you don't have to use * а также & operators with function pointers. This will work too

CmdStruct cmdStructArray[] = { {"led",   LedFunction   },
                               {"cmd2",  Cmd2Function  }, };

а также

cmdStructArray[i].cmdFuncPtr();

Во всяком случае, это чисто косметическая проблема, вопрос личных предпочтений.

3
добавлено
@ user1294203: Да, я пропустил эту деталь. Добавлено в ответ. Благодарю. В коде OP первый = , вероятно, будет интерпретироваться как инициализация, а второй = - как назначение. Однако синтаксис правой части недействителен для присваивания, даже не говоря о том, что массивы не назначаются.
добавлено автор AnT, источник
К сожалению, двойное назначение было ошибкой с копированием.
добавлено автор Jack, источник
Я хотел бы добавить, что CmdStruct cmdStructArray [] = cmdStructArray = {{"led", LedFunction}, {"cmd2", Cmd2Function},}; , т.е. двойное присвоение не является законным в C. I Также не уверен, какова первоначальная цель этого двойного назначения.
добавлено автор Grieverheart, источник