У меня есть PIC18F46K22 , и я программирую его с помощью компилятора XC8. В конце концов, у меня будет система, похожая на компьютер с stdin
и stdout
. Таким образом, в основном цикле будет функция, которая проверяет, есть ли новый ввод. Если есть ввод, функция будет вызвана соответствующим образом. Так, например, когда я ввожу A на stdin
, PIC будет запускать функцию, подобную function_A
той function_B
, которая вызывается, когда я ввожу B.
Когда PIC будет выполнен с функцией, я хочу, чтобы новый ввод был отправлен в функцию. Таким образом, при нажатии A открывается передатчик RS232, с этого момента каждый ввод будет отправляться через RS232. В итоге проект представляет собой автономный текстовый редактор. Поэтому при нажатии A открывается файловая система, с этого момента вы больше не редактируете текст, а просматриваете список файлов. Это означает, что нажатие клавиш «Вверх» и «Вниз» означает нечто иное, чем в среде редактирования текста.
Я много думал о том, как запрограммировать это на C. Я придумал это прошлой ночью и хотел бы знать, возможно ли это, и если да, то как. Что я хочу сделать, так это:
main
вызывает функцию типаfunction_A
function_A
изменяет глобальную переменную function_addr
на указатель адреса функцииin_function_A
main
вызывает функцию function_addr
при появлении нового ввода.Так что мне нужна main
функция, которая проверяет, является ли function_addr
она нулем. Если это так, следует вызвать «нормальную» функцию, например function_A
. Если это не так, function_addr
следует вызвать функцию at. Мне также нужен , function_A
который изменяет function_addr
указатель на in_function_A
.
Примечание: когда функция файловой системы должна быть закрыта, is_function_A
ее следует просто изменить function_addr
на 0.
Итак, в основном мой вопрос заключается в том, как я могу
Функция
int f(int x){ .. }
Получить адрес функции (и сохранить его в переменной)
int (*fp)(int) = f;
Вызов функции по указанному адресу
int x = (*fp)( 12 );
fp(12)
не увеличивает читаемость по сравнению с (*fp)(12)
. У них разная читабельность. (*fp)(12)
напоминает читателю, что fp
это указатель, а также напоминает объявление fp
. На мой взгляд, этот стиль связан со старыми исходными кодами, такими как внутреннее устройство X11 и K&R C. Одна из возможных причин, по которой он может быть связан с K&R C, заключается в том, что в ANSI C можно объявить fp
с использованием синтаксиса функции, если fp
это параметр: int func(int fp(double)) {}
. В K&R C это было бы int func(fp) int (*fp)(double); { ... }
.Хотя ответ Воутера абсолютно правильный, он, возможно, более удобен для начинающих и является лучшим примером относительно вашего вопроса.
int (*fp)(int) = NULL;
int FunctionA(int x){
return x + x;
}
int FunctionB(int x){
return x * x;
}
void Example(void) {
int x = 0;
fp = FunctionA;
x = fp(3); /* after this, x == 6 */
fp = FunctionB;
x = fp(3); /* after this, x == 9 */
}
Если не очевидно, что указателю функции действительно назначен целевой адрес функции, целесообразно выполнить проверку NULL.
if (fp != NULL)
fp(); /* with parameters, if applicable */
fp
оказывается занимаемым, изначально равно NULL. Я бы сделал int (*fp)(int) = NULL;
комбинированное объявление и инициализацию, чтобы быть уверенным - вы не хотите переходить к какой-то случайной ячейке памяти из-за какого-то глупого значения, которое только что там оказалось. Затем просто назначьте fp
как в вашей Example()
функции.fp
это «глобальная переменная» (как в приведенном выше коде), то она гарантированно будет инициализирована NULL
(без необходимости делать это явно).
пользователь207421
Адам Лоуренс
Кортук
Каз
пользователь207421
пользователь17592
Дэвидкари