лекция 10 (Языки программирования (лекции) (2008)), страница 2
Описание файла
Файл "лекция 10" внутри архива находится в папке "Языки программирования (лекции) (2008)". Документ из архива "Языки программирования (лекции) (2008)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Онлайн просмотр документа "лекция 10"
Текст 2 страницы из документа "лекция 10"
P(X: out integer; Y: out integer)
X := l;
... // происходит авария
Y := l;
A, B:INTEGER;
P(A, B);
Если процедура работает нормально, то всё ОК.
А если в середине процедуры происходит авария и процедура P не завершается нормальным образом и параметры передаются по ссылке, то параметр А поменяет свои значения. Если параметры передаются по значению, то А не изменится, т.к. присваивание происходит при нормальном выходе из процедуры, если выход не нормальный то мы не знаем присвоилось что-нибудь х и y.
Если для процедуры побочный эффект - норма, то стоит ли создавать функции с побочным эффектом?
Побочный эффект для функции вещь очень неприятная(70-80гг 20в):
В языке должны быть:
- procedure( с побочным эффектом)
- function F(in ...) (без побочного эффекта) входной класс in и только входные параметры
- procedure F (in out inout) return T; - процедура, возвращающая значение.
Побочный эффект - функция модифицирует свои параметры и функция, которая модифицирует глобальные переменные (что практически невозможно проверить- ошибка) Аде-83 остались только процедуры и функции с параметрами in.
(рор()-процедура для Ада, т.к. она меняет значение стека)
5-й способ передачи параметров - передача по имени. Это и есть полное отождествление формального и фактического параметра(похоже на макроподстановку).
Если адрес фактического параметра не меняется, то различий по способу передачи по имени и по ссылке нет., в противном случае разница существенна.
int x[20]; - некоторый массив
int i;
P(int a, int i)
P(x[i], i)
по ссылке- зависит от i
i = 2;
a = 0; // x[2] = 0;
i = 3;
a = 1; // x[3] = 1;
по имени- действительно x[i]
Algol-60
Впервые применен способ передачи параметров по имени.
Параметры можно было передавать по значению.
Если параметр менял свое значение, его можно было передавать по имени.
Реализация
thunk - маленькие подпрограммки. Для каждого параметра, переданного по имени, связывалась такая подпрограммка, вычисляющая адрес этого параметра.
Обращение к этому thunk'у было каждый раз, когда мы обращались к параметру внутри функции!
И именно это стало причиной редкой неэффективности Алгола 60.
Во многих функциональных языках программирования передача параметров по имени является наиболее естественной и адекватной.
Процедурные типы данных или передача функций как параметров
В языке Модула-2 был введён специальный процедурный тип:
TYPE P = procedure (INTEGER; VAR REAL):REAL
Procedure-указатель, что это процедура
(INTEGER; VAR REAL)- параметры( var- переменная)
REAL- возвращаемое значение
Значением Р- все функции, которые удовлетворяют этому прототипу.
PROCEDURE F(X:INTEGER; VAR Y:REAL):REAL;
a:P;
a := F;- правильно!
Можно написать:
D,Z:REAL;
D := a(D,Z);
а ведет себя, как F
В Обероне и turbo Рascal такая же семантика.
В C и C++ явно говорится об указателе на функцию.
int f(void) – прототип функция
int (*f)(void) - указатель на функцию
typedef int (*f)(void) – f- синоним соответствующего типа
В реализации функционального типа процедура - указатель. Вещь это крайне не надёжная. Следовательно, операции с ними надо сильно ограничивать, для языков, которые претендуют на надежность:
-
Ada
Ada-83 функциональных типов нет, иначе- введение указателя, которого разработчики очень опасались. Передача процедур решается с помощью родовых модулей)
Родовые сегменты (функции, процедуры, модуля) - аналог шаблонов в Си++. Инициализация происходит статически на этапе компиляции.
Ada-95 вернулся процедурный тип данных и указатели для обычных переменных.
1