demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 (изменено) · Жалоба Запутался. Честно скажу, с указателями я не всегда дружу. :) Помогите написать правильно. Нужно: есть массивы указателей на функцию. И переменные-состояния конечных автоматов, индексы для массивов. //************************************************************************ //************************ Главный автомат ******************************* //************************************************************************ //======================================================================== STATE (PROC_DEVICE_INIT, proc_device_init) STATE (PROC_DEVICE_WAIT_SWITCH_MODE, proc_device_wait_switch_mode) STATE (PROC_DEVICE_MANUAL, proc_device_manual_mode) STATE (PROC_DEVICE_AUTOMAT, proc_device_automat_mode) STATE (PROC_DEVICE_EMERG_MODE, proc_device_emerg_mode) //======================================================================== enum _proc_device { #define STATE(name, func) name, #include "_proc_device.h" #undef STATE PROC_DEVICE_STATES, }; //======================================================================== typedef void (*FUNC)(void); //======================================================================== __flash FUNC proc_device_func [PROC_DEVICE_STATES] = { #define STATE(name, func) func, #include "_proc_device.h" #undef STATE }; static u08 _proc_device; static u08 _proc_device_slave; void proc_device (void) { // proc_sens_pwr (SAVE_EEPROM_PARAMETERS); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! proc_device_func [_proc_device] (); // В данный момент работает так. } Мне нужна функция, у которой в качестве параметров proc_device_func и _proc_device. Что-то вроде proc_fsm_func (proc_device_func, get_proc_device_state ()) Мои пробы выдают ошибки. Изменено 29 января, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Нужно: есть массивы указателей на функцию. И переменные-состояния конечных автоматов, индексы для массивов. Мне нужна функция, у которой в качестве параметров proc_device_func и _proc_device. Что-то вроде proc_fsm_func (proc_device_func, get_proc_device_state ()) Ваш вопрос очень путанно сформулирован. Как-то так. typedef void (*t_func)(void); enum s_state{ STATE1, STATE2 }; void func_state1() { printf("func_state1\n"); } void func_state2() { printf("func_state2\n"); } t_func funcs[] = { [STATE1] func_state1 , [STATE2] func_state2 , }; void func_run(t_func* funcs, enum s_state state) { (*funcs[state])(); } int main() { func_run(funcs, STATE1); func_run(funcs, STATE2); ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Мне нужна функция, в качестве параметров которой указатель на массивы указателей на функции, и индексы-переменные-состояния КА. В вашем примере вызов функций конкретного массива по конкретному индексу. А мне нужен вызов функций по указанным в параметрах функции массивам и индексам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Мне нужна функция, в качестве параметров которой указатель на массивы указателей на функции, и индексы-переменные-состояния КА. В вашем примере вызов функций конкретного массива по конкретному индексу. А мне нужен вызов функций по указанным в параметрах функции массивам и индексам. поправил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 16 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Мне нужна функция, в качестве параметров которой указатель на массивы указателей на функции Нверное, как-то так: int func (int (*func_ptr[])(int), int y) { } Синтксис Си в отношении скобок и звёздочек непротиворечив, но с первого взгляда бывает трудно разобраться, что там к чему. Поэтому надо разбить на части. Сначала определяем тип "указатель на функцию": typedef int (*pfunc)(int x); Потом используем этот тип в определении функции int func (pfunc f[], int y) { } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Определяем тип переменной PROCEDURE - указатель на функцию typedef void (*PROCEDURE)(void); Пишем текст функций. void function1(void) { ... } void function2(void) { ... } void function3(void) { ... } Определяем, сколько у нас функций в массиве. #define STATES 3 Создаем массив указателей на функции в программной памяти, что у нас, AVR.. __flash const PROCEDURE function[STATES_QTY] = { function1, function2, function3 }; Все, в программе вызываем вызываем функцию, соответствующую номеру состояния state: function[state](); Мне нужна функция, у которой в качестве параметров proc_device_func и _proc_device. Что-то вроде proc_fsm_func (proc_device_func, get_proc_device_state ()) А зачем так сложно - в функцию передавать указатель на функцию? Чтобы вызвать? Ну так вызовите добавлением скобок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба А зачем так сложно - в функцию передавать указатель на функцию? Чтобы вызвать? Ну так вызовите добавлением скобок. Покажите, как. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Покажите, как. Уже сделано! Функция вызывается по индексу в таблице: function[state](); Что не устраивает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Все приведенные примеры по сути повторяют то, что написано в первом сообщении. Излишняя навороченность кода в том сообщении, по сути enum и массив, обвернутые в макросы. И вызов функции один в один как у вас. proc_device_func [_proc_device] (); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Все приведенные примеры по сути повторяют то, что написано в первом сообщении. Излишняя навороченность кода в том сообщении, по сути enum и массив, обвернутые в макросы. И вызов функции один в один как у вас. Правильно, макросы вредны, а все остальное - классика, которую использует каждый второй. Что не устраивает то? Вам то зачем дополнительная прослойка в виде функции, в которую будете передавать указатель на функцию? Будьте проще, пишите как есть, все же работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 (изменено) · Жалоба Вроде решил вопрос. //======================================================================== typedef void (*FUNC)(void); //======================================================================== void proc_fsm_func (FUNC __flash *ptr_func, u08 s); void func_1 (void); void func_2 (void); void func_3 (void); void func_4 (void); extern FUNC __flash list_func []; void __flash * get_list_func (void); void func_1 (void) { } void func_2 (void) { } void func_3 (void) { } void func_4 (void) { } __flash FUNC list_func [4] = { func_1, func_2, func_3, func_4, }; void proc_fsm_func (FUNC __flash *ptr_func, u08 s) { ptr_func [s] (); } void __flash * get_list_func (void) { return list_func; } proc_fsm_func (get_list_func (), 2); Задумка такая: что-то вроде ядра обработчика конечных автоматов. Можно было и так оставить, как сделано в первом сообщении. Для каждого автомата своя строка вызова функции по индексу. А когда задумал ядро обработчика, тут и возникли трудности. Честно говоря, я еще думаю, стоит ли дальше работать над этим ядром и применять его в проектах. Изменено 29 января, 2017 пользователем demiurg1978 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Для каждого автомата своя строка вызова функции по индексу. Это реализуется очень просто - одним массивом всех функций, но группы индексов массива для каждого автомата не должны перекрываться. Например, первые 6 функций - автомат А, следующие 19 функций автомат B, и еще 9 функций автомата C. тогда если массив называется f, обработка всех автоматов будет выглядеть так: f[stateA](); f[stateB](); f[stateC](); Я так делал один раз в очень специфическом проекте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg1978 1 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Еще на ассемблере я использовал функции очистки ОЗУ. В сишные компиляторах это заложено как стандарт. И это дает нам замечательную штуку. Нулевое состояние конечного автомата используем для инициализации ввода-вывода, периферии, переменных. До использования КА я использовал для этого флаги. В вашем случае есть начальные состояния КА, которые не равны нулю. А это неудобно. Должна быть обязательная функция инициализации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
psL 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Например, первые 6 функций - автомат А, следующие 19 функций автомат B, и еще 9 функций автомата C. Я так делал один раз в очень специфическом проекте. Допустим нужно добавить еще несколько состояний в автомат A, что делать? Менять условия всякий раз?;) Насколько понимаю, ТС разбивает весь код на задачи и у каждой задачи - свой автомат состояний. Т.е. при переключении на соответствующую задачу должен подключаться соответствующий автомат состояния. В принципе, очень типичная задача. Ничего специфического. Даже тема была https://electronix.ru/forum/index.php?showt...=136908&hl= Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 29 января, 2017 Опубликовано 29 января, 2017 · Жалоба Менять условия всякий раз?;) Дифайны и енумы уже отменили? ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться