Определение typedef для указателя на функцию?
Я изучаю, как динамически загружать DLL, но не могу понять следующую строку кода:
typedef void (*FunctionFunc)();
У меня есть несколько вопросов. Буду признателен, если кто-то сможет на них ответить.
- Зачем используется
typedef? - Синтаксис выглядит странно; после
voidне должно быть имени функции или что-то подобное? Это выглядит как анонимная функция. - Создается ли указатель на функцию для хранения адреса памяти функции?
В данный момент я в замешательстве; не могли бы вы прояснить эти моменты для меня?
5 ответ(ов)
typedef — это конструкция языка, которая связывает имя с типом.
Вы используете его так же, как и исходный тип, например:
typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();
И затем можно использовать эти типы следующим образом:
myinteger i; // эквивалентно int i;
mystring s; // то же самое как char *s;
myfunc f; // компилируется как void (*f)();
Как вы можете видеть, можно просто заменить имя, заданное с помощью typedef, на его определение, приведенное выше.
Сложность заключается в синтаксисе указателей на функции и читаемости в C и C++, и typedef может улучшить читаемость таких объявлений. Тем не менее, этот синтаксис оправдан, так как функции — в отличие от других более простых типов — могут иметь возвращаемое значение и параметры, что приводит к иногда длинным и сложным объявлениям указателей на функции.
Читаемость может стать действительно проблемной с указателями на массивы функций и другими еще более косвенными вариантами.
Теперь отвечая на ваши три вопроса:
Для чего используется
typedef? Чтобы облегчить чтение кода — особенно для указателей на функции или имен структур.Синтаксис выглядит странно (в объявлении указателя на функцию)
Этот синтаксис не очевиден для восприятия, особенно для начинающих. Использование объявленияtypedefоблегчает понимание.Является ли указатель на функцию созданием для хранения адреса функции?
Да, указатель на функцию хранит адрес функции. Это не связано с конструкциейtypedef, которая лишь упрощает запись/чтение программы; компилятор просто подставляет определениеtypedefдо компиляции реального кода.
Пример:
typedef int (*t_somefunc)(int,int);
int product(int u, int v) {
return u * v;
}
t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456); // вызов product() для вычисления 123*456
typedefиспользуется для создания псевдонимов типов; в этом случае вы создаете псевдонимFunctionFuncдля типаvoid(*)().Действительно, синтаксис может показаться странным, посмотрите на это:
typedef void (*FunctionFunc) ( ); // ^ ^ ^ // возвращаемый тип имя типа аргументыНет, это просто сообщает компилятору, что тип
FunctionFuncбудет указателем на функцию, это не определяет его, как в примере:FunctionFunc x; void doSomething() { printf("Hello there\n"); } x = &doSomething; x(); // выводит "Hello there"
Без слова typedef в C++ объявление будет задавать переменную FunctionFunc как указатель на функцию без аргументов, возвращающую void.
С использованием typedef вместо этого определяется FunctionFunc как имя для этого типа.
Если вы можете использовать C++11, имеет смысл воспользоваться std::function и ключевым словом using. Это позволит вам создать алиас для функционального типа, что упростит чтение и использование кода. Например:
using FunctionFunc = std::function<void(int arg1, std::string arg2)>;
Таким образом, FunctionFunc теперь является типом, представляющим функцию, которая принимает два аргумента: int и std::string, и не возвращает значения. Вы сможете удобно использовать этот алиас в дальнейшем в вашем коде для объявления переменных или параметров функций нужного типа.
Ваша задача заключается в том, чтобы понять, как использовать typedef для определения новых типов в языке C. В приведенном вами коде используются различные примеры использования typedef, включая примитивные типы, структуры, массивы и функции. Давайте рассмотрим их подробнее.
Определение примитивного типа:
Здесь мы создаем новый тип данных дляdouble, который названdistance:typedef double distance;Определение структуры:
Мы определяем новую структуруpoint, которая содержит две целочисленные координатыxиy:typedef struct { int x; int y; } point;Определение массива структур:
Мы создаем типpoints, который является массивом из 100 структурpoint:typedef point points[100];Определение указателя на функцию:
Здесь мы создаемtypedefдля указателя на функцию, которая принимает два параметра типаpointи возвращаетdistance:typedef distance (*distanceFun_p)(point, point);Прототип функции:
Мы объявляем функциюfindDistance, которая будет находить расстояние между двумя точками:distance findDistance(point, point);Главная функция:
Вmainмы объявляем указатель на функциюfunc_p, инициализируем его адресомfindDistance, создаем две точкиp1иp2и вызываем функцию через указатель:distance d = func_p(p1, p2);Определение функции:
В функцииfindDistanceмы вычисляем расстояние между двумя точками, используя теорему Пифагора:return sqrt((xdiff * xdiff) + (ydiff * ydiff));
Таким образом, используя typedef, вы можете делать ваш код более читабельным и удобным для работы с новыми типами данных.
Разница между const int*, const int * const и int * const?
Как изменить цвет вывода echo в Linux
`unsigned int` против `size_t`: когда и что использовать?
Статические глобальные переменные в C++
Что такое ** в C++?