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

Указатели на функции (Прата) - не пойму, как это работает - C++

Восстановить пароль Регистрация
 
 
gru74ik
Модератор
 Аватар для gru74ik
3116 / 1342 / 167
Регистрация: 20.02.2013
Сообщений: 3,809
Записей в блоге: 17
16.07.2014, 17:42     Указатели на функции (Прата) - не пойму, как это работает #1
Стивен Прата "Язык программирования C++. Лекции и упражнения"
7 глава, стр. 355, листинг 7.18. fun_ptr.cpp

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
// fun_ptr.cpp -- pointers to functions
#include <iostream>
double betsy(int);
double pam(int);
 
// second argument is pointer to a type double function that
// takes a type int argument
void estimate(int lines, double (*pf)(int));
 
int main()
{
    using namespace std;
    int code;
 
    cout << "How many lines of code do you need? ";
    cin >> code;
    cout << "Here's Betsy's estimate:\n";
    estimate(code, betsy);
    cout << "Here's Pam's estimate:\n";
    estimate(code, pam);
    // cin.get();
    // cin.get();
    return 0;
}
 
double betsy(int lns)
{
    return 0.05 * lns;
}
 
double pam(int lns)
{
    return 0.03 * lns + 0.0004 * lns * lns;
}
 
void estimate(int lines, double (*pf)(int))
{
    using namespace std;
    cout << lines << " lines will take ";
    cout << (*pf)(lines) << " hour(s)\n";
}
Вопрос. Я как бы понял, что в прототипе функции можно написать только типы
аргументов, опустив имена; либо написать те самые имена, которые будут в
реализации функции; либо вовсе написать любые удобные имена, которые будут
служить своеобразной подсказкой - это не важно, компилятор всё равно эти имена
пропустит.
В прототипах функций betsy() и pam() указаны только типы аргументов, это я
понял. В прототипе функции estimate() указаны имена-подсказки lines и pf
соответственно. Несмотря на то, что нигде потом не будет объявлена переменная
int lines и указатель pf, компилятор понимает, что первым аргументом функции
estimate() должно быть целое число, либо целочисленная переменная (в нашем
случае - переменная int code), а вторым аргументом указатель на функцию (в нашем
случае это betsy и pam, соответственно). Понимает почему? Потому что при вызове
функции estimate() на месте int lines стоит int code, а на месте double (*pf)(int) стоит
betsy (или во втором вызове - pam).
Но я хоть убей не могу понять, каким волшебным образом компилятор понимает,
что переменная int lns - это та же самая int code. Откуда он берёт это знание?
С чего он вообще решил, что надо подставить вместо int lns переменную int code?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6426 / 3800 / 880
Регистрация: 30.01.2014
Сообщений: 6,594
19.07.2014, 22:55     Указатели на функции (Прата) - не пойму, как это работает #21
Цитата Сообщение от gru74ik Посмотреть сообщение
Функции разные, имена переменных разные, а адрес у обеих один и тот же!
Точнее чем сказано здесь, вряд ли можно ответить. Я думаю все со мной согласятся, что этот ответ лучший, и тебе нужно просто вникнуть в него.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Psilon
Master of Orion
 Аватар для Psilon
5738 / 4686 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
20.07.2014, 03:26     Указатели на функции (Прата) - не пойму, как это работает #22
Цитата Сообщение от gru74ik Посмотреть сообщение
Не понятно почему переменная в betsy() и переменная в pam() - это одна и та же переменная? Функции разные, имена переменных разные, а адрес у обеих один и тот же!
почему одна и та же? Можешь разными назвать, это ничего не поменяет:
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
// fun_ptr.cpp -- pointers to functions
#include <iostream>
double betsy(int);
double pam(int);
 
void estimate(int lines, double(*pf)(int));
 
int main()
{
    using namespace std;
    int code;
 
    cout << "How many lines of code do you need? ";
    cin >> code;
    cout << "Here's Betsy's estimate:\n";
    estimate(code, betsy);
    cout << "Here's Pam's estimate:\n";
    estimate(code, pam);
    return 0;
}
 
double betsy(int x)
{
    return 0.05 * x;
}
 
double pam(int y)
{
    return 0.03 * y + 0.0004 * y * y;
}
 
void estimate(int lines, double(*pf)(int))
{
    using namespace std;
    cout << lines << " lines will take ";
    cout << pf(lines) << " hour(s)\n";
}
можешь даже функции разного типа сделать, все равно работать будет:
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
// fun_ptr.cpp -- pointers to functions
#include <iostream>
double betsy(int);
double pam(double);
 
template <typename FuncPtr>
void estimate(int lines, FuncPtr);
 
int main()
{
    using namespace std;
    int code;
 
    cout << "How many lines of code do you need? ";
    cin >> code;
    cout << "Here's Betsy's estimate:\n";
    estimate(code, betsy);
    cout << "Here's Pam's estimate:\n";
    estimate(code, pam);
    return 0;
}
 
double betsy(int x)
{
    return 0.05 * x;
}
 
double pam(double y)
{
    return 0.03 * y + 0.0004 * y * y;
}
 
template <typename FuncPtr>
void estimate(int lines, FuncPtr pf)
{
    using namespace std;
    cout << lines << " lines will take ";
    cout << pf(lines) << " hour(s)\n";
}
gru74ik
Модератор
 Аватар для gru74ik
3116 / 1342 / 167
Регистрация: 20.02.2013
Сообщений: 3,809
Записей в блоге: 17
20.07.2014, 13:22  [ТС]     Указатели на функции (Прата) - не пойму, как это работает #23
Цитата Сообщение от Psilon Посмотреть сообщение
почему одна и та же?
То есть один и тот же адрес - просто дело случая? А переменные int lns в функции betsy() и int lns в функции pam(), как и положено, разные?
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
20.07.2014, 13:40     Указатели на функции (Прата) - не пойму, как это работает #24
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от gru74ik Посмотреть сообщение
А переменные int lns в функции betsy() и int lns в функции pam(), как и положено, разные?
Честно говоря, не понимаю, в чем вообще затруднение в понимании.
Существование фактических аргументов функции (вышеупомянутые переменные) разнесено по времени.
И нет совершенно никак объективных причин, почему бы не использовать ту же самую память (с одинаковыми адресами) в разные моменты времени.

Вызовите одну функцию из другой и увидите, что адреса будут разные. А всё потому, что они уже используются (должны существовать) одновременно.
gru74ik
Модератор
 Аватар для gru74ik
3116 / 1342 / 167
Регистрация: 20.02.2013
Сообщений: 3,809
Записей в блоге: 17
20.07.2014, 14:20  [ТС]     Указатели на функции (Прата) - не пойму, как это работает #25
Цитата Сообщение от Tulosba Посмотреть сообщение
Существование фактических аргументов функции (вышеупомянутые переменные) разнесено по времени.
И нет совершенно никак объективных причин, почему бы не использовать ту же самую память (с одинаковыми адресами) в разные моменты времени.
То, что требовалось! Покорнейше благодарю, всё встало на свои места.
castaway
Эксперт С++
4842 / 2981 / 367
Регистрация: 10.11.2010
Сообщений: 11,013
Записей в блоге: 10
Завершенные тесты: 1
20.07.2014, 15:27     Указатели на функции (Прата) - не пойму, как это работает #26
gru74ik, да, в нём тоже.

Добавлено через 19 минут
Psilon, всегда считал и сейчас считаю что разницы нет, т.к. вызвать функцию через указатель можно только одним способом в конечном итоге.
Psilon
Master of Orion
 Аватар для Psilon
5738 / 4686 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
20.07.2014, 16:44     Указатели на функции (Прата) - не пойму, как это работает #27
Tulosba, эмм, что? Вот вызовы по-очереди, адреса все равно разные. Изменяем этот метод:
C++
1
2
3
4
5
6
template <typename FuncPtr>
void estimate(int lines, FuncPtr pf)
{
    using namespace std;
    cout << "Func adress is\t" << pf << endl;
}
получаем:
C++
1
2
3
4
5
6
How many lines of code do you need? 10
Here's Betsy's estimate:
Func adress is  001310E1
Here's Pam's estimate:
Func adress is  001312F3
Для продолжения нажмите любую клавишу . . .
как бы разные адреса жеж. Или я неправильно вопрос понял
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
20.07.2014, 20:21     Указатели на функции (Прата) - не пойму, как это работает #28
Psilon, когда я писал ответ на вопрос ТС из сообщения #23 я опирался на код из сообщения #6. В частности на строки 37 и 48.
Т.е. речь об адресах фактических аргументов функций, которые (аргументы) будут на стеке.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.07.2014, 21:35     Указатели на функции (Прата) - не пойму, как это работает
Еще ссылки по теме:

Как это работает? Я хочу спросить как работает C++ и где можно про него почитать C++
Не пойму, куда и как вставить функции и указатели C++
C++ Не пойму как работает char

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

Или воспользуйтесь поиском по форуму:
Psilon
Master of Orion
 Аватар для Psilon
5738 / 4686 / 619
Регистрация: 10.07.2011
Сообщений: 14,160
Записей в блоге: 5
Завершенные тесты: 4
20.07.2014, 21:35     Указатели на функции (Прата) - не пойму, как это работает #29
Tulosba, а, ну это логично. В принципе, если один поток всегда у процесса, то тогда первый аргумент будет всегда иметь один и тот же адрес для всех функций
Yandex
Объявления
20.07.2014, 21:35     Указатели на функции (Прата) - не пойму, как это работает
Ответ Создать тему
Опции темы

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