Функция возвращающая указатель на функцию

Функция возвращающая указатель на функцию

Я хочу присвоить адрес функции указателю на функцию, но функция, к которой нужно обратиться, возвращает указатель на функцию с той же самой сигнатурой, что и сама, вызывая его рекурсию таким образом, что я вообще не могу написать возвращаемый тип для указатель на функцию или даже само объявление функции …

Я предполагаю способ упростить проблему, чтобы она не смущала:

Как я могу написать объявление функции таким образом, чтобы оно могло возвращать указатель на себя (или любую другую функцию с такой же сигнатурой)?

редактировать:

Пока у меня есть решение, хотя я не буду публиковать его как ответ, потому что оно агрессивно безобразно. Он избавляется от рекурсии, просто возвращая сырой void* указатель в качестве возвращаемого типа и в итоге принимает следующую форму:

edit2:

Кажется, приведение между указателями на функции и обычными указателями является UB, поэтому я не могу использовать void* в этом случае…

Чтобы ответить на один из комментариев, это для передачи управления между несколькими «основными» циклами в моей программе, причем каждый цикл получает свою собственную функцию. Есть много способов сделать это, но возвращая указатели на функции (или NULL для завершения программы) в середине цикла казалось как самый простой метод, но я не ожидал, что указатели на данные и указатели на адреса функций будут несовместимы друг с другом. Я думаю, что возвращение объектов полиморфной функции в этом случае будет более разумным вариантом.

Решение

Не использовать void* , потому что нет гарантии, что void * может содержать указатель на функцию. Ты можешь использовать void(*)() в качестве обходного пути:

Указатель на void должен иметь те же требования к представлению и выравниванию, что и указатель на символьный тип. Аналогично, указатели на
квалифицированные или неквалифицированные версии совместимых типов должны иметь
одинаковые требования к представлению и выравниванию. Все указатели на
типы конструкций должны иметь одинаковое представление и выравнивание
требования как друг к другу. Все указатели на типы объединения должны иметь
те же требования к представлению и выравниванию, что и у других. указатели
для других типов не нужно иметь такое же представление или выравнивание
требования.

Указатель на функцию одного типа может быть преобразован в указатель на функцию другого типа и обратно; результат должен сравниться
равно оригинальному указателю.

Другие решения

Хитрость в C заключается в том, чтобы использовать тот факт, что любой тип указателя на функцию может быть приведен к любому другому виду указателя на функцию:

Читайте также:  Домашние роботы хестера fallout 4

Каждый указатель на стратегию всегда имеет тип, который можно вызвать один раз, а возвращаемое значение возвращается в форму, которую можно вызвать еще раз.

В C ++ вы бы объявили объект функции:

Экземпляр этого класса может быть вызван как функция.

Я подозреваю, что вы пытаетесь сделать более сложную версию чего-то вроде этого:

Обходной путь — обернуть указатель функции в структуру:

Домашняя страница

Circuit designer engineer blog

О блоге

Контактная информация и описание деятельности. Разработка схемотехники. Трассировка печатных плат. Разработка встраиваемого программного обеспечения. Работа на заказ.

Описание и пояснения по указателям на функции и переменные;

Решено написать эту маленькую заметку, ибо уже несколько раз мне задавали вопрос, что это и зачем. Помню и сам не знал этого, хотя вполне себе мог писать простенькие программы.

Что такое указатели и как их готовить вы наверное уже в курсе, если нет, то быстренько объясню.

Указатель — это переменная, которая содержит в себе адрес другой переменной, на которую указывает. Если проводить грубую аналогию с файловой системой в Windows, то указатель — это ярлык, а файл на который он указывает — переменная, размышляя дальше можно сказать что функция — это программа на компьютере, а ярлык для запуска программы — указатель на функцию.

Объявляются указатели следующим образом:

Здесь в первой строке объявляется указатель на тип uint16_t (целый без знаковый тип размером в 16 бит) и говорится что он ссылается на переменную variable. Как уже заметили есть ещё оператор &, он то как раз и возвращает адрес нашей переменной.

То есть, для доступа к данным на которые ссылается указатель необходимо написать знак "*". С этим вроде разобрались.

Читайте также:  Защита wpa wpa2 wps

Теперь о функциях. С ними тоже не сильно сложно. Для начала пример объявления, рассмотрим всего 4:

  • указатель на функцию ничего не возвращающую и с неизвестным количеством и типом параметров;
  • указатель на функцию ничего не возвращающую и ничего не принимающую;
  • указатель на функцию ничего не возвращающую, но принимающую два аргумента типами uint8_t и int16_t;
  • указатель на функцию возвращающую значение типа uint16_t и принимающую два аргумента типами uint8_t и int16_t

Главное не забыть окружить скобками указатель, иначе получится не указать на функцию, а функция возвращающая указатель:

Принцип использования можно посмотреть в примере:

Получается что мы динамически изменили логику программы. Согласитесь не плохо и довольно интересно.

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

Для более глубокого понимания советую почитать книгу Брайана Кернигана и Денниса Ритчи (ссылка), либо освежить знания.

CDEblog

Блог инженера-схемотехника, конструктора и немного программиста

Хотя функции, возвращающие указатели, обрабатываются точно так же, как и функции с другим типом, следует рассмотреть несколько важных понятий.

Указатели на переменные — это не целые числа и не беззнаковые целые. Это адрес памяти некоторого типа данных. Причина такого разделения состоит в том, что когда выполняются арифметические действия с указателем, изменения происходят с учетом базового типа, то есть, если указатель на целое увеличивается, он будет содержать значение на 2 больше по сравнению с предыдущим (предполагается использование 2-байтных целых). Каждый раз при увеличении указателя он указывает на следующий элемент базового типа. Поскольку каждый тип данных может иметь различную длину, компилятор должен знать, на какой тип данных указывает указатель, чтобы правильно осуществить переход к следующему элементу данных.

Читайте также:  Как поменять днс адрес

Ниже показана функция, возвращающая указатель на строку в месте, где найдено соответствие символов:

char *match(char с, char *s)
<
register int count;
count = 0;
while(c!=s[count] && s[count]) count++;
return(&s[count]);
>

Функция match() пытается вернуть указатель на позицию в строке, где первый раз найден символ с. Если не найдено соответствие, возвращается указатель, содержащий NULL. Ниже показана небольшая программа, использующая match():

char *match(char c*, char *s);

int main(void)
<
char s[80], *p, ch;
gets (s) ;
ch = getche();
p = match(ch, s);
if (p) /* совпадение */
printf("%s ", p);
else
printf("No match found.");
return 0;
>

Данная программа осуществляет чтение строки, а затем символа. Если символ содержится в строке, то выводится строка, начиная с момента совпадения. Иначе выводится «No match found».

Ссылка на основную публикацию
Формат записи видео mov
MOV против MP4 Существует много форматов файлов, которые можно использовать для хранения ваших видео в зависимости от ваших потребностей. MOV...
Усилитель pioneer a 405r
Вероятно, госпожа Симметрия владела умами дизайнеров Pioneer, когда они разрабатывали внешний вид этой серии усилителей. Но, расположив в центре регулятор...
Усилитель амфитон у 002 характеристики
усилитель Амфитон -002 . Доработан по статье Жуковского '' Оверклоккинг Амфитона . '' и по рекомендациям Вова мастер звук. T.е....
Формат ммгг как писать
Сбербанк Онлайн позволяет проводить различные платежи прямо из дома с любого устройства, имеющего доступ в Интернет. Это существенно экономит время...
Adblock detector