Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/40: Рейтинг темы: голосов - 40, средняя оценка - 4.95
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18

Указатель на функцию

25.12.2014, 23:58. Показов 8082. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер! Недавно приспичило сделать программу с использованием указателя на функцию. Попытался разобраться сам, но большинство статей и форумов содержат, скорее, особенности использования. В связи с этим просьба: кто-нибудь может объяснить, что это за указатель такой и с чем его едят? Может какую-нибудь банальную программу в три строчки кинете, чтоб понятней было? Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.12.2014, 23:58
Ответы с готовыми решениями:

Как сделать функцию, возвращающую указатель на функцию (которая в свою очередь возвращает указатель на массив)
Изучаю c++ по одной книжке.Она говорить не умеет.. Так вот понадобилось написать функцию,которая как параметр получает указатель на...

В функцию-метод передать указатель на другую функцию-метод и вызвать через переданный указатель
Друзья! Всем привет. Вот код: class otets { public: void f (void (otets::*p)()); private: void echo_f (){}; ...

Функция, получающая указатель на обычную функцию, получает указатель на метод класса
Здравтсвуйте. Имеется вопрос по указателям на методы класса. Допустим, есть функция( f ), которая принимает указатель на функцию и...

15
 Аватар для IrineK
2023 / 1641 / 425
Регистрация: 23.02.2011
Сообщений: 6,002
Записей в блоге: 25
26.12.2014, 00:05
Цитата Сообщение от Hearteater Посмотреть сообщение
Может какую-нибудь банальную программу в три строчки кинете
Выводим таблицу значений для трех функций от Х
C
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
//указатель на функцию
 
#include <stdio.h>
#include <math.h>
 
typedef double (*PFunction) (double argument);
 
double F1 (double x)
{   return sin(x);
}
 
double F2 (double x)
{   return 1/(1-x*x);
}
 
double F3 (double x)
{   return tan(x);
}
 
void Print (PFunction f, double xmin, double xmax, double step)
{   printf("\tx\tf(x)\n");
    printf("========================\n");
    double x = xmin;
    while (x < xmax)
    {   printf("%7.2lf%7.2lf\n", x, f(x));
        x += step;
    }
    printf("========================\n\n");
 
}
 
 
int main() 
{   PFunction F[] = {F1, F2, F3};
 
    for (int i = 0; i<3; i++)
    {   printf("Function %d\n", i+1);
        Print (F[i], -5, 5, 0.5);
    }
 
    getchar();
    return 0;
}
2
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 01:09
Цитата Сообщение от Hearteater Посмотреть сообщение
но большинство статей и форумов содержат, скорее, особенности использования.
Как насчёт книг? Там это всё разжёвано.

Добавлено через 14 минут
Цитата Сообщение от Hearteater Посмотреть сообщение
Может какую-нибудь банальную программу в три строчки кинете, чтоб понятней было?
Есть, например, у нас две такие функции (принимают один int, возвращают void):
C++
1
2
3
4
5
6
7
8
9
void foo(int x)
{
    cout << x * 2 << endl;
}
 
void foo2(int x)
{
    cout << x * 3 << endl;
}
Указатель на такие функции объявляется так:
C++
1
void (*pfoo)(int x); // pfoo - указатель на функцию, которая принимает один int и возвращает void
Этот указатель можно инициализировать именем (адресом) любой функции, которая принимает один int и возвращает void:
C++
1
2
3
4
        pfoo = foo; // инициализируем указатель именем (адресом) функции foo
        pfoo(3); // выведет 6, равнозначно foo(3) (другая запись: (*pfoo)(3))
        pfoo = foo2; // инициализируем указатель именем (адресом) функции foo2
        pfoo(3); // выведет 9, равнозначно foo2(3) (другая запись: (*pfoo)(3))
1
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18
26.12.2014, 19:03  [ТС]
lss, а каково тогда его назначение? куда проще просто вызывать функцию, разве нет? или же все таки есть рациональное объяснение, почему так лучше?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
26.12.2014, 19:41
Hearteater, например, функции обратного вызова
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 19:53
Цитата Сообщение от Hearteater Посмотреть сообщение
а каково тогда его назначение? куда проще просто вызывать функцию, разве нет? или же все таки есть рациональное объяснение, почему так лучше?
Тут дело не в лучше или хуже, а в том, когда это может быть нужно. Пример - код во 2-м посте. Там функция Print() принимает первым параметром указатель на функцию, поэтому в неё можно передавать указатели на разные функции (F1(), F2(), F3()), и в зависимости от того, с какой функцией связан этот указатель, будет вызываться та или иная функция. Без указателей на функции, под каждую из этих трёх функций, пришлось бы писать свою Print().
0
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18
26.12.2014, 19:54  [ТС]
lss, Croessmah, немного разобрался. в моем случае это нужно для передачи функции как параметра. но как мне прописать правильно параметры исходной функции? опираясь на пример IrineK сделал пока просто вариант с передачей одной функции в другую, но не соображу, как правильно прописать вызов в мэйне
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef double (*PFunction) (double argument);
 
double function(double n, double m, double v, double x)
{
    double s;
    s=(x*x*n+x*m+v);
    return s;
}
 
double pr(PFunction f, double g, double h)
{
    double s;
    for(double i=g+0.01; i<=h-0.01;i+=0.01)
    s+=f(n,m,v,x)*0.01;
    return s;
}
0
zzzZZZ...
 Аватар для dzrkot
527 / 358 / 94
Регистрация: 11.09.2013
Сообщений: 2,041
26.12.2014, 19:56
могу кинуть такой пример - использую в проектах для микроконтроллеров
смысл в том, что есть некий массив указателей на функции
и 2 функции - addTask( void (*pf)()) , и detelteTask() , они занимаются тем, что добавляют и удаляют эти самые задачи. Скажем у нас случилось прерывание(пришло сообщение по CAN или UART выполнить каку-нибудь команду), мы принимаем это сообщение, расшифровываем, и на основе его содержимого вызываем addTask(*(f)()) с тем что нам нужно, функция сама добавит задачу в очередь, когда мы вернёмся из прерывания то number_of_tasks будет !=0 , и мы выполним нашу задачу
C++
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
void addTask( void (*pf)())     // добавление задачи на выполнение
   {
   if(tail_of_tasks==32)
      tail_of_tasks=0;
   buffer_of_tasks[tail_of_tasks]=pf;
   tail_of_tasks++;
   number_of_tasks++;
   }
 
void deleteTask()             // удаление задачи
    {
    if(head_of_tasks==32)
        head_of_tasks=0;
    buffer_of_tasks[head_of_tasks]=0;
    head_of_tasks++;
    number_of_tasks--;
    }
// это уже в main
coid main(){
// инициализация переферии итп
// ...
// далее основной цикл работы
while(1)
    {
    while(!number_of_tasks)
        {
        }
    (*buffer_of_tasks[head_of_tasks])();
    deleteTask();
    }
}
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 19:58
Цитата Сообщение от Hearteater Посмотреть сообщение
но не соображу, как правильно прописать вызов в мэйне
Объявляешь указатель этого типа: PFunction, инициализируешь его именем функции function, делаешь вызов функции pr(), где первым параметром этот указатель.
0
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18
26.12.2014, 20:01  [ТС]
lss, но мне надо задать параметры у function. но я ее не вызываю напрямую. как тогда это делать? прописать три cin в теле function? тогда она же будет каждый шаг запрашивать эти параметры
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 20:08
Цитата Сообщение от Hearteater Посмотреть сообщение
но мне надо задать параметры у function. но я ее не вызываю напрямую
Задавай, в чём проблема? Можно до вызова pr(), и передавать туда эти параметры, можно в самой pr().
0
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18
26.12.2014, 20:14  [ТС]
lss, попробовал так:

C++
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
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
typedef double (*PFunction) (double argument);
 
double function(double n, double m, double v, double i)
{
    double s;
    s=(i*i*n+i*m+v);
    return s;
}
 
double pr(PFunction f, double g, double h)
{
    double n,m,v;
    cin>>n>>m>>v;
    double s;
    for(double i=g+0.01; i<=h-0.01;i+=0.01)
    s+=f(n,m,v,i)*0.01;
    return s;
}
 
void main() 
{
    PFunction F[] = {function};
        cout<<pr (function, -5, 5);
    _getch();
}
однако принимать в мэйне на вход function он не хочет:

4 IntelliSense: значение типа "double (*)(double n, double m, double v, double i)" нельзя использовать для инициализации сущности типа "PFunction" f:\New Project\Source9.cpp 27 19
5 IntelliSense: аргумент типа "double (*)(double n, double m, double v, double i)" несовместим с параметром типа "PFunction" f:\New Project\Source9.cpp 29 19

и еще почему-то ругается на m здесь:
C++
1
2
for(double i=g+0.01; i<=h-0.01;i+=0.01)
    s+=f(n,m,v,i)*0.01;
говорит, что слишком много переменных
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 20:26
Не нужно тупо коды переписывать, голову включай.
C++
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
#include <iostream>
#include <conio.h>
using namespace std;
 
typedef double (*PFunction) (double, double, double, double);
 
double function(double n, double m, double v, double i)
{
    double s;
    s=(i*i*n+i*m+v);
    return s;
}
 
double pr(PFunction f, double g, double h)
{
    double n,m,v;
    cin>>n>>m>>v;
    double s = 0;
    for(double i=g+0.01; i<=h-0.01;i+=0.01)
        s+=f(n,m,v,i)*0.01;
    return s;
}
 
int main() 
{
    PFunction F = function;
        cout << pr (function, -5, 5);
    _getch();
}
1
0 / 0 / 0
Регистрация: 09.12.2014
Сообщений: 18
26.12.2014, 20:41  [ТС]
lss, точно, завозился с функциями и забыл совсем про указатель. мне надо еще добавить две функции с исходной внутри, но в каждой объявлять параметры - не вариант. поэтому опять вопрос: как их задать в мэйне? к тому же в этом случае переменные становятся неописанными в функциях
0
 Аватар для Zedapp
45 / 31 / 18
Регистрация: 15.11.2014
Сообщений: 169
26.12.2014, 21:03
Вот наверно самый простой пример какой может быть

C++
1
2
3
4
5
6
7
8
9
10
11
double calc(double x, double (*f)(double))
{
    return f(x);
}
 
int main()
{
    int a;
    a = calc(2.5, sin);
   return 0;
}
Смысле в этом примере конечно нет, можно было бы сразу написать sin(2.5), но как пример показываютщий, что такое указатель на функцию пойдет.
0
lss
941 / 869 / 355
Регистрация: 10.10.2012
Сообщений: 2,706
26.12.2014, 22:23
Цитата Сообщение от Hearteater Посмотреть сообщение
как их задать в мэйне?
В чём проблема? Как, вообще, задаются переменные в main()? Так и задай. Писал уже:
Цитата Сообщение от lss Посмотреть сообщение
Можно до вызова pr(), и передавать туда эти параметры,
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.12.2014, 22:23
Помогаю со студенческими работами здесь

Указатель на функцию, которая принимает в качестве параметра указатель на массив
я не понимаю. вроде делаю правильно, но выходит ошибка. есть функция. int foo(int *mas){}; cоздаю на нее указатель. int...

Передача умного указателя в функцию принимающую указатель на указатель
Итак имеется функция со следующим параметром: HRESULT __stdcall Function(SomeClass **param); В случае, когда создаём обычный...

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

Передать в неуправляемую функцию указатель на указатель
Неуправляемая функция типа FUNC(int ** r); Делаю так fixed (int* ptr = arr) { FUNC((int **)ptr); ...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru