Перейти к содержимому

Как в функции вызвать другую функцию c

  • автор:

Как в функции вызвать другую функцию c

В языке Си указатель на функцию может передаваться в другую функцию в качестве параметра. Например:

#include int sum(int x, int y) < return x+y; >int subtract(int x, int y) < return x-y; >int operation(int (*op)(int, int), int a, int b) < return op(a, b); >int main(void)

Здесь в функции operation первый параметр — указатель int (*op)(int, int) представляет функцию, которая возвращает значение типа int и принимает два параметра типа int . Результатом функции является вызов той функции, на которую указывает указатель.

Определению указателя соответствуют две функции: sum и subtract, поэтому их адрес можно передать в вызов функции operation: operation(sum, a, b); .

Другой пример — функция, которая может принимать в качестве параметра некоторое условие:

#include int isEven(int x) < return x%2==0; >int isPositive(int x) < return x>0; > void action(int (*condition)(int), int numbers[], int n) < for(int i=0; i> > int main(void) < int nums[] = ; int n = sizeof(nums)/sizeof(nums[0]); printf("Even numbers: "); action(isEven, nums, n); printf("\nPositive numbers: "); action(isPositive, nums, n); return 0; >

Первый параметр функции action — указатель int (*condition)(int) представляет функцию, которая принимает целое число и в зависимости от того, соответствует оно условию или нет, возвращает 1 (если соответствует) или 0. На момент определения функции action точное условие может быть неизвестно.

В текущей программе условия представлены двумя функциями. Функция isEven() возвращает 1, если число четное, и 0, если число нечетное. А функция isPositive() возвращает 1, если число положительное, и 0, если отрицательное.

При вызове функции action() в нее можно передать нужное условие: action(isEven, nums, n); . В итоге программа выведет на экран числа из массива nums, которые соответствуют переданному условию:

Even numbers: -4 -2 0 2 4 Positive numbers: 1 2 3 4 5

Но применение указателей на функцию в качестве параметров ухудшает читабельность определения функции. В этом случае можно определить псевдоним для типа функции:

#include typedef int (binary_op)(int, int); int sum(int x, int y) < return x + y;>int subtract(int x, int y) < return x - y;>int operation(binary_op op, int a, int b) < return op(a, b); >int main(void) < printf("result = %d \n", operation(sum, 10, 5)); // result = 15 printf("result = %d \n", operation(subtract, 10, 5)); // result = 5 return 0; >

В данном случае для функций, которые имеют два параметра типа int и возращают значение типа int, определен псевдоним binary_op .

typedef int (binary_op)(int, int);

И далее мы можем использовать этот псевдоним как тип для определения параметров:

int operation(binary_op op, int a, int b)

функция может вызывать другую функцию?

Author24 — интернет-сервис помощи студентам

Может ли функция иметь аргументом другую функцию или объект?
Внимание тупой вопрос )) А может ли функция иметь аргументом другую функцию или объект?

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

Создать функцию, которая будет вызывать другую функцию
Доброго времени суток. Изучаю PHP и вот столкнулся с такой практикой, не знаю как реализовать.

Как вызывать функцию в другую функцию?
в одной функции пытаюсь вызывать другую функцию следующей строкой: m = newdate(pdate) сама.

Регистрация: 25.10.2009
Сообщений: 32
Регистрация: 04.11.2009
Сообщений: 366
Регистрация: 25.10.2009
Сообщений: 32

1 2 3 4
void func1() { func2(); }

686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722

1 2 3 4 5
void someFunc(void){ //do smtn } void anotherSomeFunc(void) {someFunc();}

1080 / 1007 / 106
Регистрация: 28.02.2010
Сообщений: 2,889

Если первая функция объявлена после второй — да.
Если заголовок второй функций описан в начале файла — да.

Добавлено через 32 секунды
Если первая функция объявлена до второй — не знаю.

Добавлено через 3 минуты

ЦитатаСообщение от Евгений М. Посмотреть сообщение

Если первая функция объявлена до второй — не знаю.
Узнал. Ответ — нет.
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722

Евгений М., вы бы пояснили какая из функция какую вызывает. А то первая, вторая. Так и мой пример неправилен будет, смотря с какой точки рассмотреть где первая, где вторая.

1080 / 1007 / 106
Регистрация: 28.02.2010
Сообщений: 2,889
Первая вызывает вторую. Ваш пример правильный.
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722

Да я то знаю что он правильный
Просто я к тому, что человек не писал где первая, а где вторая, и если их поменять местами, они будут вторая и первая, и работать не будут ))
Ну или это уже мои бзики на почве немощи сделать CheckComboBox на c++ 😐

Эксперт С++

5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448

Может, ТС имел в виду вызов переданной в качестве аргумента функции? Вот пример (простой целочисленный калькулятор):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#include #include #define CNT 4 typedef int (*oper)(int, int); int o_add(int, int); int o_sub(int, int); int o_mul(int, int); int o_div(int, int); oper operators[CNT] = { o_add, o_sub, o_mul, o_div }; void processAction(int, int, oper); int main()  exit(255); } int o_add(int a1, int a2) { return a1 + a2; } int o_sub(int a1, int a2) { return a1 - a2; } int o_mul(int a1, int a2) { return a1 * a2; } int o_div(int a1, int a2) { if(a2 == 0) { fputs("Error: division by zero\n", stderr); exit(1); } return a1 / a2; } void processAction(int a1, int a2, oper o) { printf("Given arguents are `%d' and `%d', and the result is `%d'\n", a1, a2, o(a1, a2)); }

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Длительное нажатие кнопки должно вызывать другую функцию, нежели обычное
Добрый день! Подскажите может кто-то уже с этим сталкивался, как реализовать длительное нажатие.

Батарейка на материнской плате может вызывать тормоза ?
Имею мамку. Вес комп вот. Играю в игру, допустим, Lineage II. При большом скоплении народу.

Видимость переменных. Может ли метод вызывать сам себя?
Такой вот вопросец появился. Имеем гипотетический метод с циклом for, который обрабатывает строку.

ASUS M51Tr: утилита Power4Gear может вызывать перегрев ?
После установки Win7 на нойтбук "ASUS M51Tr" владелец сказал, что чувствует нагрев (видимо держал.

Или воспользуйтесь поиском по форуму:

Как в функции вызвать другую функцию c

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

#include int add(int, int); int subtract(int, int); int operation(int(*)(int, int), int, int); // первый параметр — указатель на функцию int main() < int a; int b; int result = operation(add, a, b); std::cout int add(int x, int y) < return x + y; >int subtract(int x, int y) < return x - y; >int operation(int(*op)(int, int), int a, int b)

В данном случае первый параметр функции operation — int (*op)(int, int) — представляет указатель на функцию, которая возвращает значение типа int и принимает два параметра типа int . Результатом функции является вызов той функции, на которую указывает указатель.

Определению указателя соответствуют две функции: add и subtract, поэтому их адрес можно передать в вызов функции operation: operation(add, a, b); .

Результат работы программы:

result: 16 result: 4

Функция, передаваемая другой функции в качестве аргумента, называется функцией обратного вызова или коллбек (callback). А функция, которая принимает другую функцию в качестве аргумента, является функцией высшего порядка. Таким образом, в примере выше функция operation представляет функцию высокого порядка, а функции add и subtract — функции обратного вызова.

Рассмотрим другой пример — определим функцию, которая может принимать в качестве параметра некоторое условие и вычислять все элементы массива, которые соответствуют этому условию:

#include // функции, которые представляют условия bool isEven(int); // если число четное bool isPositive(int); // если число положительное // Функция для определения элементов массива, которые соответствуют некоторому условию // функция принимает условие — bool(*)(int) // массив — int[] // размер массива — unsigned void action(bool(*)(int), int[], unsigned); int main() < int numbers[]< -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 >; const unsigned n < std::size(numbers)>; // находим длину массива std::cout bool isEven(int x) < return x % 2 == 0; >bool isPositive(int x) < return x >0; > void action(bool(*condition)(int), int numbers[], unsigned n) < // перебираем массив for (unsigned i<>; i < n; i++) < // если число (numbers[i] соответствует условию condition if (condition(numbers[i])) < std::cout > std::cout

Функция action в качестве первого параметра принимает некоторую функцию, которая задает условие, которому должны соответствовать элементы массива. Это условие представляет указатель bool (*condition)(int) . То есть это некоторая функцию, которая принимает целое число и в зависимости от того, соответствует оно условию или нет, возвращает значение типа bool ( true , если число из массива соответствует условию, и false , если не соответствует). На момент определения функции action точное условие может быть неизвестно.

В текущей программе условия представлены двумя функциями. Функция isEven() возвращает true, если число четное, и false, если число нечетное. А функция isPositive() возвращает true, если число положительное, и false, если отрицательное.

Второй параметр функции action — массив чисел int, для которых вызываем условие. А третий параметр — размер массива. Если число соотвествует условию, то выводим это число на консоль

void action(bool(*condition)(int), int numbers[], unsigned n) < // перебираем массив for (unsigned i<>; i < n; i++) < // если число (numbers[i] соответствует условию condition if (condition(numbers[i]))

При вызове функции action() в нее можно передать нужное условие:

action(isEven, nums, n); action(isPositive, numbers, n);

В итоге программа выведет на экран числа из массива nums, которые соответствуют переданному условию:

Even numbers: -4 -2 0 2 4 Positive numbers: 1 2 3 4 5

Язык С: можно ли вернуть функцию из другой функции?

В С++ этот вопрос решается возвращением функционального объекта с перегруженным оператором (). Можно ли в чистом си сделать так, чтобы функция в виде своего результата возвращала другую функцию, что-то на подобии этого:

void (*message) (void) function(int args)

Или еще проще:

message function(int args)
  • c
  • функции
  • функциональное-программирование

Отслеживать
задан 13 апр 2020 в 23:06
430 2 2 серебряных знака 8 8 бронзовых знаков
Конечно, можно. См., например, man dlsym
14 апр 2020 в 9:03

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Можно вернуть указатель на функцию (в С++ это тоже работает):

void a() <> // Вариант 1 void (*b(int args))() < (void)args; return a; >// Вариант 2 typedef void func_t(); func_t *c(int args) < (void)args; return a; >// Вариант 3 typedef void (*func_t2)(); func_t2 d(int args)

Отслеживать
ответ дан 13 апр 2020 в 23:18
HolyBlackCat HolyBlackCat
27.1k 3 3 золотых знака 27 27 серебряных знаков 40 40 бронзовых знаков
Интересно, а каррирование автору надо или нет?)
13 апр 2020 в 23:26
@Qwertiy про карирование я узнал только сейчас. Про него так же хотелось бы спросить.
13 апр 2020 в 23:37

@zurn, у меня нет ни малейшей идеи, как это можно было бы сделать в си. За счёт времени жизни переменной получается, что аргумент должен быть частью возвращаемого значения. В плюсах — это поле класса, потому и работает. А вот в си уже вряд ли получится. Ну или надо возвращать структуру с метолдом call, но это уже немного не то, чего хотелось бы? Или пойдёт?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *