Форум программистов, компьютерный форум CyberForum.ru

Расскаэите о указателях на функции - C++

Восстановить пароль Регистрация
 
 
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 15:02     Расскаэите о указателях на функции #1
Всем дорого времени суток.
Объясните нубу для чего необходимы указатели на функции и как и где их правильно применять... Что-то до меня не доходит из книг.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.09.2013, 15:02     Расскаэите о указателях на функции
Посмотрите здесь:

C++ ошибка в указателях
C++ обьясните простым языком о указателях * и &
C++ Об указателях
C++ немного об указателях
написать стёк на указателях C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Raali
572 / 276 / 12
Регистрация: 06.07.2013
Сообщений: 917
Завершенные тесты: 1
18.09.2013, 15:08     Расскаэите о указателях на функции #2
для того, чтобы функцию передавать в качестве параметра другой функции, например, чтобы по таймеру выполнилась какая то твоя функция - ты передаешь ее в таймер, который написан совершенно другим человеком, и он не знает какая фукция должна выполниться после окончания таймера, а ты , в свою очередь без понятия - где и куда вставлять свою функцию в его коде, в таком случае делают функции, которые принимают в качестве параметра заведомо неизвестные функции
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 15:10  [ТС]     Расскаэите о указателях на функции #3
почему нельзя вызвать функцию сразу после завершения функции таймер следующей строкой кода?
Raali
572 / 276 / 12
Регистрация: 06.07.2013
Сообщений: 917
Завершенные тесты: 1
18.09.2013, 15:11     Расскаэите о указателях на функции #4
Цитата Сообщение от h_wolf Посмотреть сообщение
после завершения функции таймер
если таймер например не ты писал и просто не знаешь куда вставлять, либо это вообще библиотека, в которой код даже не поменять будет, как например Windows для окна использует оконную процедуру, полностью заданную пользователем, которая передается в класс окна в качестве указателя
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 15:15  [ТС]     Расскаэите о указателях на функции #5

Не по теме:

простите если туплю



Raali, Таймер функция? Почему нельзя сделать так:

C++
1
2
Timer(Amount); //заканчивается действие функции таймер
MyFunction(Arg, Arr, Tmp); //Вызывается моя функция


Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
18.09.2013, 15:22     Расскаэите о указателях на функции #6
Небольшой пример:
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
44
45
46
47
48
49
50
51
52
#include <iostream>
 
template < typename T , int size >
void out_array ( const T ( & arr ) [size] ){
  for ( int i = 0 ; i < size ; ++i )
    std :: cout << arr [ i ] << " " ;
  std::cout << std::endl ;
}
 
 
 
template< class T , int size >
void bubbleSort(T ( & arr ) [size], bool (*cmp_func) ( const T & , const T & ) )
{
    T tmp;
 
    for(int i = 0; i < size - 1; ++i)
    {            
        for(int j = 0; j < size - 1; ++j)
        {     
            if ( cmp_func ( arr[j + 1] , arr[j] ) )  //Сравнение с помощью той функции, адрес которой передали. Волшебство, не правда ли? )))
            {
                tmp = arr[j + 1]; 
                arr[j + 1] = arr[j]; 
                arr[j] = tmp;
            }
        }
    }
}
 
 
 
template < typename T >
bool cmp_less ( const T & first , const T & second ) {
  return first < second ;
}
 
template < typename T >
bool cmp_great ( const T & first , const T & second ) {
  return first > second ;
}
 
 
 
int main( ) {
  int arr [] = {6,8,7,5,3,2,9,0,1,4} ;
  out_array ( arr ) ;
  bubbleSort ( arr , cmp_less ) ;
  out_array ( arr ) ;
  bubbleSort ( arr , cmp_great ) ;
  out_array ( arr ) ;
}
алгоритм сортировки взят из темы Алгоритмы сортировок
Raali
572 / 276 / 12
Регистрация: 06.07.2013
Сообщений: 917
Завершенные тесты: 1
18.09.2013, 15:25     Расскаэите о указателях на функции #7
Цитата Сообщение от h_wolf Посмотреть сообщение
Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
ну вобщем да, когда тело передаваемой функции либо не известно самой функции, либо когда тело может меняться (например функция вызова заклинания на игрока - она сама по себе не знает что это за заклинание, но инициирует его на нужного игрока, а там уже какое заклинание пользователь выбрал такой и эффект будет - либо полечит , либо подамажит)
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 15:28  [ТС]     Расскаэите о указателях на функции #8
Croessmah, К сожаления для понимания этого примера у меня мало знаний я не знаю ни шаблонов, ни классов пока, так что Ваш пример мне не ясен...

Raali, спасибо, картинка начинает проясняться, дальше думаю сам дожую
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
18.09.2013, 15:40     Расскаэите о указателях на функции #9
Цитата Сообщение от h_wolf Посмотреть сообщение
я не знаю ни шаблонов, ни классов пока, так что Ваш пример мне не ясен...
Вот почти тоже самое без шаблонов
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
44
45
46
47
48
49
50
#include <iostream>
//Функция вывода массива - можно даже не смотреть
void out_array ( const int * arr , int size ){
  for ( int i = 0 ; i < size ; ++i )
    std :: cout << arr [ i ] << " " ;
  std::cout << std::endl ;
}
 
 
 
void bubbleSort ( int * arr , int size , bool (*cmp_func) ( const int & , const int & ) ) //Третий параметр - указатель на функцию, с помощью которой будут сравниваться элементы
{
    int tmp;
 
    for(int i = 0; i < size - 1; ++i)
    {            
        for(int j = 0; j < size - 1; ++j)
        {     
            if ( cmp_func ( arr[j + 1] , arr[j] ) ) //Сравниваем элементы с помощью функции, указатель на которую передали
            {
                tmp = arr[j + 1]; 
                arr[j + 1] = arr[j]; 
                arr[j] = tmp;
            }
        }
    }
}
 
 
 
bool cmp_less ( const int & first , const int & second ) {
  return first < second ;
}
 
bool cmp_great ( const int & first , const int & second ) {
  return first > second ;
}
 
 
 
int main( ) {
  const int size = 10 ;
  int arr [ size ] = {6,8,7,5,3,2,9,0,1,4} ;
  out_array ( arr , size ) ; //Вывод массива
  bubbleSort ( arr , size , cmp_less ) ; //Сортировка. Третий параметр - указатель на функцию, с помощью которой будут сравниваться элементы
  out_array ( arr , size ) ; //Смотрим результат
  bubbleSort ( arr , size , cmp_great ) ; //Опять сортируем, но теперь передаем указатель на другую функцию
  out_array ( arr , size ) ; //Смотрим теперь что получилось
  //Таким образом с помощью одной функции сортировки. мы смогли отсортировать массив и по возрастанию и по убыванию, передавая указатель на функцию сравнения элементов
}
User409368
191 / 168 / 6
Регистрация: 09.09.2013
Сообщений: 524
18.09.2013, 16:29     Расскаэите о указателях на функции #10
Допустим, есть функция F(), которая принимает 3 аргумента.
два числа типа double и указатель на другую функцию:

C++
1
2
3
4
double F(double a, double b, double (*pf)(double, double) ) 
{ 
    return pf(a, b); 
}
Эта функция в свою очередь вызывает другую через указатель (в нее передаются первые два аргумента)

Но у тебя нет исходника этой функции и ее невозможно изменить.

И тут нам нужно использовать ее в своей программе, передав третьим аргументом
свою собственную функцию Z()
C++
1
double Z(double a, double b)        { return 2*(a+b); }
Тогда мы пишем вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
double Z(double a, double b);
 
int main()
{
    cout << F(2.0, 3.0, Z);
 
 
    _getch();
    return 0;
}
 
 
double Z(double a, double b)        { return 2*(a+b); }
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 16:47  [ТС]     Расскаэите о указателях на функции #11
_, Я так понимаю пример из учебника Праты?

спасибо за развернутый ответ. Я уже понял где и как это может понадобиться.
еще только одно уточнение - разве вопрос применения разных функций в разное время не решается перегрузкой функции? Или вызовом непосредственно по имени функции в коде?
User409368
191 / 168 / 6
Регистрация: 09.09.2013
Сообщений: 524
18.09.2013, 16:57     Расскаэите о указателях на функции #12
Цитата Сообщение от h_wolf Посмотреть сообщение
Я так понимаю пример из учебника Праты?
я его когда то читал, наверно из него. точно не помню ) в памяти остался

Цитата Сообщение от h_wolf Посмотреть сообщение
разве вопрос применения разных функций в разное время не решается перегрузкой функции?
да же не знаю что ответить. мне кажется это разные вещи. перегрузка это одно а передача указателя функции совсем другое. не знаю
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 17:17  [ТС]     Расскаэите о указателях на функции #13
_, но ведь результат и цель одна и та же, или я не так понимаю?
Raali
572 / 276 / 12
Регистрация: 06.07.2013
Сообщений: 917
Завершенные тесты: 1
18.09.2013, 17:22     Расскаэите о указателях на функции #14
Цитата Сообщение от h_wolf Посмотреть сообщение
но ведь результат и цель одна и та же, или я не так понимаю?
в каком смысле?
User409368
191 / 168 / 6
Регистрация: 09.09.2013
Сообщений: 524
18.09.2013, 17:26     Расскаэите о указателях на функции #15
Цитата Сообщение от h_wolf Посмотреть сообщение
но ведь результат и цель одна и та же, или я не так понимаю?
нет, это все таки разные вещи. указатель это указатель, а перегрузка функций это уже другое.

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

вот еще небольшой пример с указателями. (на всякий случай)

C++
1
2
3
4
5
6
7
8
9
10
11
double Z(double a, double b);
 
double F(double a, double b, double (*pf)(double, double) );
 
int main()
{
    double (*pf)(double, double); // pf - это указатель на функцию
 
    pf = Z; // указателю присвоили адрес на функцию Z
 
    // здесь можно этому указателю присвоить адрес другой функции. но только на функцию, которая возвращает значение double и принимает два аргумента, каждый из которых double
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 17:38  [ТС]     Расскаэите о указателях на функции #16
Raali,
Цитата Сообщение от Raali Посмотреть сообщение
Сообщение от h_wolf
но ведь результат и цель одна и та же, или я не так понимаю?
в каком смысле?
в том что бы вызывать в зависимости от ситуации разные функции, нет?

_, не ясно почему нельзя вызвать функцию явно, зачем усложнять указателями?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
18.09.2013, 17:49     Расскаэите о указателях на функции #17
Цитата Сообщение от h_wolf Посмотреть сообщение
зачем усложнять указателями?
Наоборот всё становится легче
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
18.09.2013, 17:51     Расскаэите о указателях на функции #18
Цитата Сообщение от h_wolf Посмотреть сообщение
в том что бы вызывать в зависимости от ситуации разные функции, нет?
и в этом тоже
например есть функции сортировки, она берет указатель на массив и указатель на функцию сравнения (больше меньше)
в массиве могут лежать не простые данные(int char) а например твоя структура
тогда пишешь свою функцию сравнения и подсовываешь функции сортировки
итого одна и та же функция может сортировать разные данные

второе применение, есть функция которая лежит в DLL подгружая DLL ты можешь взять адрес нужной тебе функции и использовать её по указателю.
Raali
572 / 276 / 12
Регистрация: 06.07.2013
Сообщений: 917
Завершенные тесты: 1
18.09.2013, 17:51     Расскаэите о указателях на функции #19
Цитата Сообщение от h_wolf Посмотреть сообщение
не ясно почему нельзя вызвать функцию явно, зачем усложнять указателями?
xD

вот например нам надо чтобы по кнопке ESC мы выходили из программы, к сожалению это не виндоус и мы не можем отследить нажатие клавиши сами, за то у нас есть одна функция в библиотеке по работе с клавиатурой вида - SetKeyboardListener(kbfunc f); - Она сама (мы не знаем, и не сможем узнать когда) вызовет пользовательскую(нашу) функцию обработки клавиш, тогда когда она посчитает нужным(в момент нажатия клавиши например)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void listener(int param)
{
if(param == ESC)
{
exit(1);
}
}
 
int main(int, char**)
{
SetKeyboardListener(listener);
 
while(1) ;
 
return 1;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.09.2013, 18:05     Расскаэите о указателях на функции
Еще ссылки по теме:

Ошибка в указателях C++
Совсем запутался в указателях C++
C++ Об указателях по философски-математически

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

Или воспользуйтесь поиском по форуму:
h_wolf
 Аватар для h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 211
18.09.2013, 18:05  [ТС]     Расскаэите о указателях на функции #20
Спасибо всем, за подробные ответы, видимо так туго идет понимание из-за отсутствия опыта.
Yandex
Объявления
18.09.2013, 18:05     Расскаэите о указателях на функции
Ответ Создать тему
Опции темы

Текущее время: 06:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru