У меня есть функция add, которая добавляет два целых числа, как показано ниже:
int add(int a, int b){
return a + b;
}
и я хотел создать указатель на мою функцию с именем a и вызвать мою функцию с ее помощью
printf("The sum of 45, 23: %d\n", a(45, 23));
Я сделал это, создав тип для своей функции с помощью typedef.
typedef int (*Aptr) (int, int);
Aptr a = &add;
printf("The sum of 45, 23: %d\n", a(45, 23));
The sum of 45, 23: 68
Но когда я попытался использовать тип в операторе typedef с моей переменной, это вызвало ошибку, и я также попытался удалить замещающее имя, но оно выдает ошибку. Если целью typedef является просто создание нового имени для существующего типа данных, почему это не работает?
int (*Aptr) (int, int) a = &add;
int (*) (int, int) a = &add;
Для обоих случаев:
[Error] 'a' undeclared (first use in this function)
[Note] each undeclared identifier is reported only once for each function it appears in
[Warning] implicit declaration of function 'a' [-Wimplicit-function-declaration]
Есть ли другой способ указать тип данных функции для указателя функции?
Почему вы хотите сделать это без typedef? Как вы заметили, сложно расписывать это полностью. typedef
упрощает это.
Обратите внимание, что &
перед add
является лишним. Строка int (*Aptr) (int, int); a = &add;
объявляет переменную Aptr
типа указателя на функцию и присваивает указатель на функцию для add
переменной a
, которая, вероятно, не определена. Должно быть написано: int (*a) (int, int) = add;
(хотя &add
допустимо, как и *add
, **add
и другие бессмысленные декораторы). Первая часть строки int (*) (int, int); a = &add;
бессмысленна — это объявление без имени объявленного объекта. Его можно было бы использовать в гипсе, но это все.
Примечание: гораздо чаще можно прийти в эту область с противоположной стороны. Во-первых, как мне, исходя из первых принципов, объявить указатель на функцию. Затем, зная, как написать объявление указателя функции, короткий шаг к объявлению псевдонима typedef
для типа указателя функции и преимущества, которые иногда можно получить таким образом.
Вам может оказаться полезным Понимание определений типов для указателей функций в C.
Я сделал это, создав тип для своей функции с помощью typedef.
Придирка: вы сделали это, используя typedef для объявления псевдонима типа функции. Это не создает тип.
Если целью typedef является просто создание нового имени для существующего типа данных, почему это не работает?
Потому что ты делаешь это неправильно.
Добавление typedef
к допустимому объявлению означает, что вместо объявления о том, что указанный идентификатор обозначает объект или функцию указанного типа, этот идентификатор будет служить псевдонимом для этого типа. Если вместо этого вы хотите объявить реальный объект или функцию, все, что вам нужно сделать, это удалить typedef
:
int (*Aptr) (int, int);
Вы, конечно, можете выбрать другой идентификатор:
int (*a) (int, int);
Каждый из них объявляет указатель на функцию, имеющую два параметра типа int
и возвращающую int
.
Этот вариант:
int (*Aptr) (int, int); a = &add;
содержит как декларацию (int (*Aptr) (int, int);
), так и оператор (a = &add;
). Первый вариант — вполне допустимое объявление Aptr
как указателя на функцию, как уже обсуждалось. Часть после первой точки с запятой выделена отдельно, это попытка присвоить значение необъявленной переменной a
.
Этот вариант:
int (*) (int, int); a = &add;
похоже, но немного дальше. int (*) (int, int)
— допустимое имя типа, и его можно использовать в этой форме в приведении типов, но чтобы объявить переменную этого типа, вам нужно поместить имя переменной в соответствующую точку внутри. Форма, которую вы хотите:
int (*a) (int, int) = &add;
или альтернативно,
int (*a) (int, int);
a = &add;
или любое из вышеперечисленных значений без &
, что необязательно (но не неправильно), когда add
идентифицирует функцию.
Без определения типа:
int (*a)(int, int) = func;
С typedef (два метода):
typedef int func_type(int,int);
typedef int (*func_ptr_type)(int, int);
func_type *fptr = func;
func_ptr_type fptr= func;
Где func
— функция, принимающая два параметра int
и возвращающая int
Если целью typedef является просто создание нового имени для существующего тип данных, почему это не работает?
int (*Aptr) (int, int); a = &add;
int (*) (int, int); a = &add;
И то, и другое не имеет смысла. Второй можно записать как int (*) (int, int) a = &add;
, но язык C не поддерживает этот синтаксис (правда, я не знаю почему — по моему мнению, так и должно быть ради последовательности). int (*)(int, int)
можно использовать в приведениях, но не в объявлениях
В C23 и выше вы можете использовать typeof
:
typeof(add) *a = add;
Когда typeof
в качестве операнда передается тип функции, результатом является тип функции, а не тип указателя функции. См. также: Эквивалентны ли эти два объявления указателей функций?
int(*a) (int, int) = &add;