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

Не обязательно разыменовывать указатель на функцию при вызове? - C++

Восстановить пароль Регистрация
 
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.02.2014, 03:44     Не обязательно разыменовывать указатель на функцию при вызове? #1
Здравствуйте.
Вот такой вопрос.

C++
1
2
3
4
5
6
7
8
void estimate(int lines, double (*pf) (int)); //прототип
// ...
void estimate(int lines, double (*pf) (int))
{
   using namespace std;
   cout << lines << " lines will take ";
   cout << (*pf)(lines) << " hour(s)\n";
}
Одинаковый результат при (*pf)(lines) и pf(lines). Почему?

И как, вообще, удобней по-вашему писать указатели? Например:
- int* pt;
- int * pt;
- int *pt.

Пока не начал учить ук-ли на ф-ии, писал как в первом варианте. Теперь начинаю сомневаться...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.02.2014, 03:44     Не обязательно разыменовывать указатель на функцию при вызове?
Посмотрите здесь:

Как передать параметр типа "указатель на указатель" в функцию? C++
Указатель на указатель на функцию C++
Зачем передавать в функцию X указатель на callback функцию, если последняя ВНЕШНЯЯ и вызовется БЕЗО ВСЯКОГО УКАЗАТЕЛЯ? C++
C++ Указатель на функцию в вызове другой функции
C++ Обязательно ли объявлять переменную для хранения адреса переменной как указатель?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
some_name
Вежливость-главное оружие
 Аватар для some_name
219 / 219 / 55
Регистрация: 19.02.2013
Сообщений: 1,419
23.02.2014, 03:58     Не обязательно разыменовывать указатель на функцию при вызове? #2

(*pf)(lines)
вызывает функцию , на которую указывает , с аргументами lines. Скобки вокруг *pf обязательны. Существует и другой, более простой, способ вызова функции с помощью указателя:

pf(lines);
Однако первый способ используется чаще (рекомендуем использовать именно его), потому что при втором способе вызова указатель *pf очень похож на имя функции, что может сбить с толку читающего программу. В то же время у первого способа записи есть свои преимущества, например, хорошо видно, что функция вызывается с помощью указателя на функцию, а не имени функции. Следует отметить, что первоначально в С был определен именно первый способ вызова.

Цитата Сообщение от andrejap Посмотреть сообщение
- int* pt;
юзай этот. он логичнее
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.02.2014, 04:11  [ТС]     Не обязательно разыменовывать указатель на функцию при вызове? #3
Цитата Сообщение от some_name Посмотреть сообщение
юзай этот. он логичнее
Мерси. В том то и дело, что мне кажется логичнее запускать с разыменовкой, а объявлять так как я и делаю. Ведь это же тип. Но с фундаментальной точки зрения, почему не обязательно разыменовывать указатель на ф-ию?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.02.2014, 05:55     Не обязательно разыменовывать указатель на функцию при вызове? #4
Цитата Сообщение от andrejap Посмотреть сообщение
Но с фундаментальной точки зрения, почему не обязательно разыменовывать указатель на ф-ию?
Прата.
Миниатюры
Не обязательно разыменовывать указатель на функцию при вызове?  
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.02.2014, 16:00  [ТС]     Не обязательно разыменовывать указатель на функцию при вызове? #5
alsav22, это я читал.

Добавлено через 2 часа 44 минуты
alsav22, еще смущает другой момент. Можете объяснить почему массив из трех указателей на функции необходимо объявлять так, например:

const int* (*ptrf[3])(My_type1*, My_type2*) = {function1, function2, function3}; ?

Почему не const int* ((*ptrf)(My_type1*, My_type2*))[3] = {function1, function2, function3}; ?

Вопрос, наверное, глуп и связан с приоритетами, но все-же хотелось бы прочитать ответ для полного понимания.
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.02.2014, 16:07     Не обязательно разыменовывать указатель на функцию при вызове? #6
Цитата Сообщение от andrejap Посмотреть сообщение
И как, вообще, удобней по-вашему писать указатели? Например:
- int* pt;
- int * pt;
- int *pt.
C++
1
int* pt;
писать так потому что звездочка относится к типу, но при этом помнить
C++
1
int* pt1, pt2; //pt2 не указатель
исходя из этого лучше: одна строка - одна переменная
C++
1
2
3
4
int* pt1;
int pt2;
int* pt3;
int* pt4;
Добавлено через 2 минуты
Цитата Сообщение от andrejap Посмотреть сообщение
const int* (*ptrf[3])(My_type1*, My_type2*) = {function1, function2, function3};
Почему не const int* ((*ptrf)(My_type1*, My_type2*))[3] = {function1, function2, function3}; ?
не рекомендовал бы вообще так писать, хочешь указатель на функцию - делай typedef
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
23.02.2014, 16:08     Не обязательно разыменовывать указатель на функцию при вызове? #7
использование варианта (*pf)(lines) может все обломать в каком-нибудь шаблонном коде,
который принимает функторы. pf(lines); - универсальный способ. в плюсах тип разыменовывания
указателей - ссылка. ссылок на функции нет. так что можно считать это особым случаем.
да и в других местах указатели на функции - особые случае. вот то же уродское объявление
указателеи и т.п.
тут лучше делать сперва тайпдеф и потом уже переменнные объявлять. так код понятнее:
C++
1
2
typedef const int* (*MyFunPtr)(MyType1*, MyType2*);
MyFunPtr myFuncs[3]; - вот тут понятно что имеем дело с массивом указателей на функции
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.02.2014, 16:11     Не обязательно разыменовывать указатель на функцию при вызове? #8
Цитата Сообщение от andrejap Посмотреть сообщение
alsav22, это я читал.
Если читали, то в чём тогда вопрос?
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
23.02.2014, 16:27     Не обязательно разыменовывать указатель на функцию при вызове? #9
Цитата Сообщение от andrejap Посмотреть сообщение
const int* ((*ptrf)(My_type1*, My_type2*))[3]
Потому что в этой записи [3] относится к возвращаемому значению.
Получается этой записью мы хотим вернуть массив указателей.
Но в С++ запрещено возвращать массивы как объекты (потому что в С++ они не объекты).
Зато можно возвращать ссылки на массивы:
C++
1
2
3
4
const int ( &func( const int (&arr)[5] ) )[5]
{
    return arr;
}
И это можно использовать, например, чтобы написать функцию, которая определяет размер масссива без sizeof:
C++
1
2
3
4
5
template <typename ArrT, size_t ArrN>
size_t sizeof_array(ArrT const (&arr)[ArrN])
{
    return ArrN;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.02.2014, 16:38     Не обязательно разыменовывать указатель на функцию при вызове?
Еще ссылки по теме:

C++ Класс - Ошибки при вызове методов: В вызове функции отсутствует список аргументов
C++ Когда оператор должен быть обязательно членом класса, и когда он обязательно не принадлежит классу?
Передача массива в функцию используя указатель на функцию C++

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

Или воспользуйтесь поиском по форуму:
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
23.02.2014, 16:38  [ТС]     Не обязательно разыменовывать указатель на функцию при вызове? #10
Спасибо всем, начинает проясняться!
Yandex
Объявления
23.02.2014, 16:38     Не обязательно разыменовывать указатель на функцию при вызове?
Ответ Создать тему
Опции темы

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