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

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

Войти
Регистрация
Восстановить пароль
 
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
#1

Как работает указатель на функцию? - C++

21.02.2013, 23:29. Просмотров 682. Ответов 12
Метки нет (Все метки)

Вот пример :
C++
1
2
3
4
void error(int i);
void (*p)(int);
p=&error;
(*p)(1);
Что будет происходить при исполнении этой инструкции
C++
1
(*p)(1);
? После разыменования указателя подставится адрес функции, который наверно заменится компилятором на имя функции
C++
1
error
и будет обычный вызов функции вида
C++
1
error(1)
или вызов с адресом если не заменится. А дальше будет
C++
1
int i = 2;
расположенное между телом и сигнатурой функции и начнется вызов первой команды тела функции. То есть любое имя функции - это указатель на первую команду её тела? Можете в подробностях рассказать что происходить от начала вызова функции и до конца?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2013, 23:29
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как работает указатель на функцию? (C++):

Как сделать функцию, возвращающую указатель на функцию (которая в свою очередь возвращает указатель на массив) - C++
Изучаю c++ по одной книжке.Она говорить не умеет.. Так вот понадобилось написать функцию,которая как параметр получает указатель на...

Расскажите, как здесь работает указатель на указатель? - C++
#include "stdafx.h" #include <iostream> #include <locale.h> using namespace std; void main() { setlocale(LC_ALL, "rus"); ...

Как передать параметр типа "указатель на указатель" в функцию? - C++
#include "stdafx.h" #include <conio.h> #include <iostream> using namespace std; #include <iomanip> using std::setiosflags; ...

В функцию-метод передать указатель на другую функцию-метод и вызвать через переданный указатель - C++
Друзья! Всем привет. Вот код: class otets { public: void f (void (otets::*p)()); private: void echo_f (){}; ...

Как передать указатель на функцию в функцию - C++
И как с ней работать?

Функция, получающая указатель на обычную функцию, получает указатель на метод класса - C++
Здравтсвуйте. Имеется вопрос по указателям на методы класса. Допустим, есть функция( f ), которая принимает указатель на функцию и...

12
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.02.2013, 23:38 #2
Все функции расположены где-то в памяти. Компилятор в курсе, где именно расположены те функции, которые вы прямо вызываете по имени в программе, поэтому их вызовы сразу заменяются на вызовы по адресу ещё во время компиляции. С помощью указателей на функции вы можете подсунуть нужный адрес не при компиляции, а во время исполнения программы. Принципиальная разница на этом заканчивается.

Не любое имя функции — это указатель на первую команду, а скорее получение указателя на функцию выглядит как имя. Не наоборот. Да и сам указатель — это не обязательно адрес первой команды. Это просто нечто, что позволяет вызвать функцию. Компилятор не обязан делать его адресом первой команды.
2
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 00:53  [ТС] #3
~OhMyGodSoLong~, тогда какая разница между p=&error; и p=error;? В первом случае берется адрес функции error, то есть там где она расположена в памяти, а во втором случае берется адрес, который содержит error, то есть в ней содержится адрес её тела или чего?
0
palva
2650 / 1877 / 274
Регистрация: 08.06.2007
Сообщений: 7,212
Записей в блоге: 4
22.02.2013, 02:01 #4
Никакой разницы.
C++
1
2
3
4
5
6
    p=&error;
    (*p)(1);
    p(1);
    p=error;
    (*p)(1);
    p(1);
0
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 02:48  [ТС] #5
palva, это да, но почему?
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.02.2013, 02:52 #6
Потому что таков синтаксис взятия указателя на функцию.
0
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 03:21  [ТС] #7
шикарные ответы
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.02.2013, 03:39 #8
Ну а что ещё вам сказать? На вопросы в стиле "почему 1 + 2 означает сложение чисел 1 и 2".

Ещё раз: указатель на функцию — абстрактное понятие языка Си. Хватит туда приплетать железную реализацию. Если вас интересует именно она, то хватит туда приплетать Си, идите читайте про calling conventions.
0
NIch
399 / 310 / 27
Регистрация: 17.03.2010
Сообщений: 1,120
22.02.2013, 06:46 #9
Цитата Сообщение от mzarb Посмотреть сообщение
тогда какая разница между p=&error; и p=error;?
Тут рулит компилятор, он, понимает, что error это функция и сам присваивает адрес.
1
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 13:17  [ТС] #10
NIch, ясно, я просто думал, что в этом варианте p=error; error содержит адрес, иначе как бы получилось присвоение указателю, но а если компилятор просто заменяет имя функции на адрес, то это все меняет. Пока писал сообщение, понял что это очевидно, так как знал же и тут раньше говорили что компилятор заменяет имя функций на их адреса, просто в контекст присвоения указателя почему то не осенило.
Всем спасибо, понял свою ошибку.

Добавлено через 7 минут
palva, а в этом коде p(1); , p автоматически разыменовывается компилятором или что-то другое происходит?
0
palva
2650 / 1877 / 274
Регистрация: 08.06.2007
Сообщений: 7,212
Записей в блоге: 4
22.02.2013, 13:58 #11
Да кто его знает, что происходит. В учебниках пишут, что можно так и так. Компиляторы это поддерживают. А логику я в этом месте отключаю и пишу как короче. В языке Delphi с адресами функций такая же ситуация.

По логике вещей функция это константный тип данных. Значение функции это ее определение или реализация. Мы не можем ничего присвоить функции, потому что тогда придется запускать компилятор, чтобы откомпилировать новое значение. Но мы можем присвоить адрес указателю на функцию. То есть надо писать p=&fun и (*p)(). Но это моя логика. Допускаю, что может быть и другая. Посмотрите, как это реализовано в JavaScript. Там всё стройно и логично, хотя все глубИны их подхода я тоже не осознал.
1
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 14:21  [ТС] #12
palva, да, вот что было в последнем учебнике "Разыменование указателя при вызове не обязательно. Также не обязательно пользоваться & для получения адреса функции.". Есть вещи, которые одними учебниками по c++ не понять, но имхо этот момент можно было и поподробней освещать или ещё раз напоминать что все имена функции при компиляции заменяются адресами, просто чтобы связать эти два момента в памяти.
Кстати спасибо за вашу логику по поводу функции, я тоже задавался этим вопросом, но до поиска ответа не дошло).
0
Vourhey
Почетный модератор
6486 / 2260 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
22.02.2013, 14:26 #13
Цитата Сообщение от mzarb Посмотреть сообщение
что все имена функции
Дело не в имени, а в (), которые стоящие после какого-либо слова говорят, что в этом месте кода ожидается вызов функции. И компилятор уже знает, как работать с символами перед (). Поэтому не важно с * оно, или без.
1
22.02.2013, 14:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.02.2013, 14:26
Привет! Вот еще темы с ответами:

Передача умного указателя в функцию принимающую указатель на указатель - C++
Итак имеется функция со следующим параметром: HRESULT __stdcall Function(SomeClass **param); В случае, когда создаём обычный...

Как получить указатель на функцию - C++
Здравствуйте! Подскажите, как получить указатель на функцию? Амперсанд не помогает. class Menu{ private: //...

Как сделать указатель на функцию ? - C++
Я только учусь программировать и у меня возник такой вопрос. В общем имеется на форме 5 эдитов ввода и один эдит вывода. При наступлении в...

Указатель на функцию (как передать?) - C++
void abc(int a, int b) { } void func(void *f(int, int)) { f; }


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

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

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