Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
1

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

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

Author24 — интернет-сервис помощи студентам
Всем дорого времени суток.
Объясните нубу для чего необходимы указатели на функции и как и где их правильно применять... Что-то до меня не доходит из книг.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.09.2013, 15:02
Ответы с готовыми решениями:

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

Ошибка в указателях
Здравствуйте, не понимаю почему выводит мусор. Вроде бы все правильно сделал. Знаю что можно было...

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

Запутался в указателях
Поиск элемента, равного figure void remove_helper(std::shared_ptr<BTreeItem> *item,const...

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

Не по теме:

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



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

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


Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 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
859 / 448 / 112
Регистрация: 06.07.2013
Сообщений: 1,491
18.09.2013, 15:25 7
Цитата Сообщение от h_wolf Посмотреть сообщение
Указатель на функцию требуется что бы вызвать свою функцию посреди чужой функции?
ну вобщем да, когда тело передаваемой функции либо не известно самой функции, либо когда тело может меняться (например функция вызова заклинания на игрока - она сама по себе не знает что это за заклинание, но инициирует его на нужного игрока, а там уже какое заклинание пользователь выбрал такой и эффект будет - либо полечит , либо подамажит)
1
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 15:28  [ТС] 8
Croessmah, К сожаления для понимания этого примера у меня мало знаний я не знаю ни шаблонов, ни классов пока, так что Ваш пример мне не ясен...

Raali, спасибо, картинка начинает проясняться, дальше думаю сам дожую
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 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
193 / 170 / 32
Регистрация: 09.09.2013
Сообщений: 522
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
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 16:47  [ТС] 11
_, Я так понимаю пример из учебника Праты?

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

Цитата Сообщение от h_wolf Посмотреть сообщение
разве вопрос применения разных функций в разное время не решается перегрузкой функции?
да же не знаю что ответить. мне кажется это разные вещи. перегрузка это одно а передача указателя функции совсем другое. не знаю
0
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 17:17  [ТС] 13
_, но ведь результат и цель одна и та же, или я не так понимаю?
0
859 / 448 / 112
Регистрация: 06.07.2013
Сообщений: 1,491
18.09.2013, 17:22 14
Цитата Сообщение от h_wolf Посмотреть сообщение
но ведь результат и цель одна и та же, или я не так понимаю?
в каком смысле?
0
193 / 170 / 32
Регистрация: 09.09.2013
Сообщений: 522
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
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 17:38  [ТС] 16
Raali,
Цитата Сообщение от Raali Посмотреть сообщение
Сообщение от h_wolf
но ведь результат и цель одна и та же, или я не так понимаю?
в каком смысле?
в том что бы вызывать в зависимости от ситуации разные функции, нет?

_, не ясно почему нельзя вызвать функцию явно, зачем усложнять указателями?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
18.09.2013, 17:49 17
Цитата Сообщение от h_wolf Посмотреть сообщение
зачем усложнять указателями?
Наоборот всё становится легче
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
18.09.2013, 17:51 18
Цитата Сообщение от h_wolf Посмотреть сообщение
в том что бы вызывать в зависимости от ситуации разные функции, нет?
и в этом тоже
например есть функции сортировки, она берет указатель на массив и указатель на функцию сравнения (больше меньше)
в массиве могут лежать не простые данные(int char) а например твоя структура
тогда пишешь свою функцию сравнения и подсовываешь функции сортировки
итого одна и та же функция может сортировать разные данные

второе применение, есть функция которая лежит в DLL подгружая DLL ты можешь взять адрес нужной тебе функции и использовать её по указателю.
1
859 / 448 / 112
Регистрация: 06.07.2013
Сообщений: 1,491
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;
}
1
11 / 11 / 2
Регистрация: 24.01.2013
Сообщений: 212
18.09.2013, 18:05  [ТС] 20
Спасибо всем, за подробные ответы, видимо так туго идет понимание из-за отсутствия опыта.
0
18.09.2013, 18:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.09.2013, 18:05
Помогаю со студенческими работами здесь

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

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

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

Реализация стека на указателях
Стек на указателях: #include &lt;iostream&gt; using std::cin; using std::cout; using std::endl;...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru