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

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

Войти
Регистрация
Восстановить пароль
Результаты опроса: Ну кто так считает:
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Если каждую итерацию разом
Согласен с утверждением 3 42.86%
Не согласен с утверждением 4 57.14%
Голосовавшие: 7. Вы ещё не голосовали в этом опросе

 
 
Рейтинг: Рейтинг темы: голосов - 50, средняя оценка - 4.78
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

Процедурный тип - C++

12.02.2010, 06:04. Просмотров 6353. Ответов 44
Метки нет (Все метки)

Не заню, как в c++, в других языках есть понятие "процедурный тип". Процедурным типом называется тип указателя на подпрограмму. Для object pascal есть рекомендация, как описывать такие типы:
при описании процедурного типа, после его имени и знака равенства пишут оператор procedure или function в зависимости от типа подпрограммы, далее в скобках описывают формальные параметры, как в заголовке подпрограммы, причём, имена параметров указываются, но значения не имеют, а имя самой подпрограммы опускается, в типе указателя на функцию после закрывающей скобки указывается тип возвращаемого значения. А для c++ кто нибудь может дать подобную рекомендацию, чтоб прочитать и под любой прототип функции быстро, но качественно слепить процедурный тип? Пример:
Delphi
1
2
3
4
5
6
7
8
9
function f1(x:integer):integer;
begin
        if x>0 then f1:=f1*(x-1) else f1:=1;
end;
function f2(x:integer):integer;
begin
        f2:=x*x;
end;
type a=function (x:integer):integer;
Delphi
1
2
3
4
5
6
var d:a;
e:integer;
begin
       d:=f1;
       e:=d(4);
end;
. Здесь a - процедурный тип. В данном случае, тип указателя на целую функцию с одним целым параметром. Как это делать на c++? Запостите сюда правило + пример.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.02.2010, 06:04     Процедурный тип
Посмотрите здесь:

C++ Перечисляемый тип данных.Символьный тип.
тип cout-a ostrieam? соответствено тип cin-a istream? C++
Enum и типы данных. Как задать тип значений явно, и какой тип будет при переполнении? C++
C++ Процедурный тип на функцию содержащую указатель на массив
Багаж пассажира характеризуется количеством вещей (целый тип) и общим весом вещей (вещественный тип). C++
Восьмибитный тип переменной (что за тип, но не BYTE и не CHAR? C++
C++ clrscr(); не определен данный тип и const MAX_ELEMENTS = 4; отсутсвует тип int когда я его туда вписываю у меня больше ошибок вылазит
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 08:23     Процедурный тип #2
Есть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream.h>
int myfunc(int a){
cout<<a<<'\n';
return 0;
}
 
int main(){
int (*p)(int) = NULL ; //указатель на функцию возвращающую int и имеющую параметр int.
 
p = myfunc;         //берём адрес функции
p(20);                 //вызываем функцию через указатель.
 
return 0;
}
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 08:54  [ТС]     Процедурный тип #3
Мне надо описать именно тип. чтоб потом писать не
C++
1
int (*p)(int);
а
C++
1
TintF p;
. Как сделать именно так?
C++
1
2
typedef TintF (*)(int);
TintF p;
правильно? Или как?
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 08:59     Процедурный тип #4
Вот правильно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream.h>
 
typedef int(*p)(int) ;
 
int myfunc(int a){
cout<<a<<'\n';
return 0;
}
 
int main(){
p pF= NULL ;
 
pF = myfunc;        
pF(20);             
 
return 0;
}
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:02  [ТС]     Процедурный тип #5
Спасибо. А как сформулировать правлило? Так что ли: "пишем typedef, тип возвращаемого значения, в скобках знак "*" и имя типа, потом в вторых скобках список типов параметров, опуская их имена"?
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:06     Процедурный тип #6
Можно и так:
typedef int(*p)(int a);
Главное что в прототипе самой функции есть имена типов параметров.
В указатель можно написать и просто список типов.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:10  [ТС]     Процедурный тип #7
Спасибо. Правило такое: "пишем typedef, тип возвращаемого значения, в скобках знак "*" и имя типа, потом в вторых скобках список параметров, при этом можно опустить их имена"?
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:10     Процедурный тип #8
typedef int(*p)(int a);
Переводится это так указатель на функцию возвращающую int и имеющую один параметр int
кстати посмотри в код я исправил ошибку. Почему то её компилятор не заметил:
pF(20); вызов функции.
а было так p(20); //компилятор даже не заметил.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:12  [ТС]     Процедурный тип #9
Я сразу видел
C++
1
pF(20);
. А если б и с ошибкой, сразу бы понял, как это исправить.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:15     Процедурный тип #10
Может тебе показать как объявить массив указателей на функции.

Добавлено через 56 секунд
От него толку больше бывает: мини-полиморфизм
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:17  [ТС]     Процедурный тип #11
C++
1
TIntF p[200];
. Вопрос был только по описанию типа указателя, а как его юзить и комбинировать я и сам знаю.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:18     Процедурный тип #12
Не правильно.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:19  [ТС]     Процедурный тип #13
Кстати, я чаще всего юзю именно массивы указателей на подпрограммы, а не отдельные указатели. Но пока пользовался указателями на подпрограммы только на object pascal.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:24     Процедурный тип #14
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
#include <iostream.h>
 
typedef int(*p[3])(int);     //массив указателей на функции
 
int myfunc1(int a){
cout<<"myfunc1"<<'\n';
cout<<a<<'\n';
return 0;
}
 
int myfunc2(int a){
cout<<"myfunc2"<<'\n';
cout<<a<<'\n';
return 0;
}
 
int myfunc3(int a){
cout<<"myfunc3"<<'\n';
cout<<a<<'\n';
return 0;
}
 
 
int main(){
p masf = {&myfunc1,&myfunc2,&myfunc3}; //записываем адреса фукнций в массив
 
//Компакт полиморфизм: я его называю мини полиморфизм
int i;
for(i=0;i<3;i++)masf[i](20);       //вызываем очередную функцию через массив указателей.
//-------------------------------------------------------------------------------------------    
 
 
 
return 0;
}
Добавлено через 1 минуту
Как красивый эффект, стиль называется меньше кода больше дела,
или смена поведения программы в реальном времени.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:27  [ТС]     Процедурный тип #15
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Не правильно.
Тогда
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef int (*TintF)(int);
typedef int (**TintFArray)(int a);
TIntFArray p=NULL;
p=new TintF[10];
p[0]=f1;
p[1]=f2;
p[2]=f3;
p[3]=f4;
p[4]=f5;
p[5]=f6;
p[6]=f7;
p[7]=f8;
p[8]=f9;
p[9]=f10;
. Можно ещё запихать указатель на указатель на функцию в закрытый член класса и перегрузить оператор [] и член Size.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:28     Процедурный тип #16
Поясняю как происходит вызов функции:
masf[0](20) ; //вызывается 1 функция
masf[1](20); //вторая
masf[3](20); //третья

Запомни прототип указателя, должен совпадать с прототипом функции: адрес которой он собирается хранить.
Прототип это возвращаемое знач и параметры.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:34  [ТС]     Процедурный тип #17
Цитата Сообщение от Genius Ignat Посмотреть сообщение
C++
1
typedef int(*p[3])(int); //массив указателей на функции
Толку от такого типа нет совсем:
C++
1
2
3
4
typedef int(*p3[3])(int);
typedef int (*p40[20])(int);
typedef int (*p40[40])(int);
typedef int (*p2[2])(int);
и т.д. объявляешь тип для каждого массива и потом гадаешь, как всё это упорядочить, если вдруг число элементов начнёт меняться.

Добавлено через 58 секунд
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Запомни прототип указателя, должен совпадать с прототипом функции: адрес которой он собирается хранить.
Это я знаю.
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:37     Процедурный тип #18
taras atavin:
Я сомневаюсь, что количество функций растёт во время выполнения программы,
или ты не логично хочешь напихивать массив адресам одно и той же функции.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
12.02.2010, 09:50  [ТС]     Процедурный тип #19
Цитата Сообщение от Genius Ignat Посмотреть сообщение
p masf = {&myfunc1,&myfunc2,&myfunc3};
А это вообще не понятно, зачем. Процедурный тип нужен для того, чтобы можно было менять функцию во время исполнения программы. Представь себе калькулятор с функциональными кнопками, флажками и т.д. при использовании которых должны меняться функции основных кнопок. Обработчик кнопки вызывает
C++
1
p[2][1]();
,
C++
1
p[3][4])();
, где индексы определяются положением кнопок. Как поменять функцию? Правильный ответ:
C++
1
p[3][4]=f1;
в обработчике одного флага и
C++
1
p[3][4]=f2;
- другого. А ты что предлагаешь?
C++
1
2
3
4
5
6
switch (Mode)
{
 case 1:return p1[3][4]();
 case 2:return p2[3][4]();
 case 3:return p3[3][4]();
}
. Где сдесь полиморфизм? Зачем вообще понадобились указатели? Тогда уж проще по именам.

Добавлено через 1 минуту
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Я сомневаюсь, что количество функций растёт во время выполнения программы,
Не во время выполнения, а просто несколько массивов с разным числом функций и мо мере разработки начинаешь соображать, что 20 надо поменять на 18, 40 на 50 и т.д.

Добавлено через 1 минуту
Цитата Сообщение от Genius Ignat Посмотреть сообщение
или ты не логично хочешь напихивать массив адресам одно и той же функции.
Такую глупость я не смог сморозить. Надо в "наглядные пособия" запостить.

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
C++
1
2
3
4
typedef int(*p3[3])(int);
typedef int (*p40[20])(int);
typedef int (*p40[40])(int);
typedef int (*p2[2])(int)
;
имеется ввиду:
C++
1
2
3
4
typedef int(*p3[3])(int);
typedef int (*p20[20])(int);
typedef int (*p40[40])(int);
typedef int (*p2[2])(int)
;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.02.2010, 09:50     Процедурный тип
Еще ссылки по теме:

C++ 8.Дан список населенных пунктов области с описанием: название, кол-во жителей, тип. Тип выбирается из списка: город, районный цент, село, поселок г
Узнать тип значения, зная тип указателя C++
Как сконвертировать свой тип в тип double? C++
Не могу преобразовать тип char в тип double C++
Какой символьный тип использует тип std::string? C++

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

Или воспользуйтесь поиском по форуму:
Genius Ignat
1233 / 771 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
12.02.2010, 09:50     Процедурный тип #20
//Компакт полиморфизм: я его называю мини полиморфизм
int i;
for(i=0;i<3;i++)masf[i](20); //вызываем очередную функцию через массив указателей.

И попробуй вызвать каждую функцию в цикле по каждому имени.
Условие: Три вызова сразу в теле делать нельзя нельзя.
Yandex
Объявления
12.02.2010, 09:50     Процедурный тип
Ответ Создать тему
Опции темы

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