Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
#1

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

18.09.2013, 15:02. Просмотров 715. Ответов 20
Метки нет (Все метки)

Всем дорого времени суток.
Объясните нубу для чего необходимы указатели на функции и как и где их правильно применять... Что-то до меня не доходит из книг.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.09.2013, 15:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Расскаэите о указателях на функции (C++):

Об указателях - C++
В чем разница между этими двумя строчками? int* x; int *x;

немного об указателях - C++
есть код: #include <iostream> #include <windows.h> using namespace std; int main() { int inta=1234; int...

Ошибка в указателях - C++
Здравствуйте, не понимаю почему выводит мусор. Вроде бы все правильно сделал. Знаю что можно было сделать p = rand(); но меня это не...

Написать стек на указателях - C++
хочю знать как написать стёк на указателях мне нужно чтобы можно было добавлять новые елемнты сколько угодно а уберать не обязтельно ...

Совсем запутался в указателях - C++
Шестую строку не могу понять, по моему перед массивом var должен стоять &. const int MAX = 3; int _tmain(int argc, _TCHAR* argv) {...

Реализация стека на указателях - C++
Стек на указателях: #include <iostream> using std::cin; using std::cout; using std::endl; enum FirstNodeEnum{NoFirstNode,...

20
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,068
Завершенные тесты: 1
18.09.2013, 15:08 #2
для того, чтобы функцию передавать в качестве параметра другой функции, например, чтобы по таймеру выполнилась какая то твоя функция - ты передаешь ее в таймер, который написан совершенно другим человеком, и он не знает какая фукция должна выполниться после окончания таймера, а ты , в свою очередь без понятия - где и куда вставлять свою функцию в его коде, в таком случае делают функции, которые принимают в качестве параметра заведомо неизвестные функции
0
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 15:10  [ТС] #3
почему нельзя вызвать функцию сразу после завершения функции таймер следующей строкой кода?
0
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,068
Завершенные тесты: 1
18.09.2013, 15:11 #4
Цитата Сообщение от h_wolf Посмотреть сообщение
после завершения функции таймер
если таймер например не ты писал и просто не знаешь куда вставлять, либо это вообще библиотека, в которой код даже не поменять будет, как например Windows для окна использует оконную процедуру, полностью заданную пользователем, которая передается в класс окна в качестве указателя
0
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 15:15  [ТС] #5

Не по теме:

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



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

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


Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13554 / 7705 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 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 ) ;
}
алгоритм сортировки взят из темы Алгоритмы сортировок
0
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,068
Завершенные тесты: 1
18.09.2013, 15:25 #7
Цитата Сообщение от h_wolf Посмотреть сообщение
Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
ну вобщем да, когда тело передаваемой функции либо не известно самой функции, либо когда тело может меняться (например функция вызова заклинания на игрока - она сама по себе не знает что это за заклинание, но инициирует его на нужного игрока, а там уже какое заклинание пользователь выбрал такой и эффект будет - либо полечит , либо подамажит)
1
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 15:28  [ТС] #8
Croessmah, К сожаления для понимания этого примера у меня мало знаний я не знаю ни шаблонов, ни классов пока, так что Ваш пример мне не ясен...

Raali, спасибо, картинка начинает проясняться, дальше думаю сам дожую
0
Croessmah
Ушел
Эксперт CЭксперт С++
13554 / 7705 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 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 ) ; //Смотрим теперь что получилось
  //Таким образом с помощью одной функции сортировки. мы смогли отсортировать массив и по возрастанию и по убыванию, передавая указатель на функцию сравнения элементов
}
0
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); }
1
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 16:47  [ТС] #11
_, Я так понимаю пример из учебника Праты?

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

Цитата Сообщение от h_wolf Посмотреть сообщение
разве вопрос применения разных функций в разное время не решается перегрузкой функции?
да же не знаю что ответить. мне кажется это разные вещи. перегрузка это одно а передача указателя функции совсем другое. не знаю
0
h_wolf
9 / 9 / 1
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 17:17  [ТС] #13
_, но ведь результат и цель одна и та же, или я не так понимаю?
0
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,068
Завершенные тесты: 1
18.09.2013, 17:22 #14
Цитата Сообщение от h_wolf Посмотреть сообщение
но ведь результат и цель одна и та же, или я не так понимаю?
в каком смысле?
0
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
1
18.09.2013, 17:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.09.2013, 17:26
Привет! Вот еще темы с ответами:

Об указателях по философски-математически - C++
Допустим, имеем код: int *p; Есть мнение, что истолковать запись можно двояко: 1) р - тип, указывающий на инт; 2) р -...

Реализация очереди на указателях - C++
Очередь на указателях: #include &lt;iostream&gt; using std::cin; using std::cout; using std::endl; const int Number = 10; enum...

Стек на указателях не компилируется - C++
#include &lt;iostream&gt; using std:: cin; using std:: cout; using std:: endl; struct NodePtr { char Value; NodePtr* Next; ...

передать в функцию стек на указателях - C++
Всем привет. Есть стек, реализованный через указатели. Необходимо его отправить в две функции не по значению. Проблема в том,...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru