лекции (2010) (by Ульянов Алексей_ Лихогруд Николай_ Сергеев Николай) (1160852), страница 9
Текст из файла (страница 9)
«ref»реализует семантику inout, а «out» реализует семантику out. При использовании out компилятор вставляетквазистатический контроль на наличие в методе присваивания значения, зато не требуетинициализированность фактического параметра перед вызовом метода.void f(ref int x){x = -3;}….int a = 0;f( ref a); // а будет передано по ссылке, если бы объект «а» был структурой, то он так жепередался бы по ссылкеРазрешать или не разрешать функции с переменным количеством параметров?СиВ Си можно было создавать функции с переменным количеством параметров при помощи библиотеки«stdargs»: va_list, va_start, va_end, va_next и т.дСи#void f(param object [] args){…. args [0] = …; }void g(object [] args){….
args [0] = …; }….f(a , b);f();//f(1);f(new X[]{new X(). new X()});// Ошибка!!f(new X(), new X()); // Правильно!g(new X[]{new X(). new X()});// Правильно!!javavoid func(Object a[]){for(int i = 0;i < a.length; i++)System.out.println(a[i]);}Для java 1.5 – func(1,2,3, new Object(), "word");Для java 1.4 – func(new Object[] {1, 2, "some string"});Передача параметров по имениАлгол-60Передаём сам объект «как он есть» . Фактически передаётся его идентификатор как строчка. Далее в телепроцедуры идентификатор формального параметра заменяется на идентификатор фактическогоОбоснование невозможности написание процедруры swap на Algol-60:procedure Swap(a,b); //a, b передаются по имениBeginT tmp;tmp := a; a:= b; b := tmp;End;….swap(i, A[i]);T tmp;tmp := i;i := A[i];A[i] := tmp;// A [ A[i] ] := i; неправильно!!!swap(A[i], i);T tmp;tmp := A[i];A[i] := i;i:= tmp;// i := A[i] – всё правильноРешение проблемы: С каждым параметром передавалась процедура thunk, которая выполнялась при каждомобращении к фактическому параметру.Параметры по умолчаниюВ С++ можно задавать параметры по умолчанию: void f(int a = 4){ …;}В C# эту возможность убрали.
Вместо этого предлагается использовать перегрузку:f(){ f(1, 2); }f(int i ){ f(i , 2) ;}f(int i, int j ) { … ; }Лекция. Ульянов А.В.Подпрограммы. Типы данных.Ада 83, Java – нет.П.1. Передача подпрограмм, как параметров.Присваивание [:=]Вычисление [()]Ада 83: generic не только для ТД, но и для процедур, функций.//generic – параметризация.с/с++: typedef void (*f)(int);Отсюда, процедурный тип – указатель.Проблема в том, что в Ада 83 и Java отказались от указателей, т.е.
и от П/П ТД.//В Java целиком, в Ада частично.Ада 95:type Func_Pointer is access function (L,R: float) return Boolean;function Compare (X,Y: float) return Boolean … end Compare;F: Func_PointerF:=Compare’accessМодула-2, Оберон:TYPE FUNC_INT = PROCEDURE (L,R: REAL): BOOLEAN;PROCEDURE COMPARE (X,Y: REAL): BOOLEAN;VAR F: FUNC_INT;F:=COMPARE;П.2. Функции обратного вызова.Для реализации ООП(динамическое связывание), например, в xlib xt Motif;События Реакция.Чистые ООЯП: Любой ОД принадлежит классу.//Автоупаковка, автораспаковка => Простой ТД объект.Java:Существуют класс (интерфейс) Interface, метод Integrate, Virtual подынтегральная функция.
Наследует изаменяет подынтегральную функцию.C#: Делегаты(расширение П/П ТД)С++: class X{void f(int);int i;}X::*int p; //Указатель на членСмещение относительно начала.Typedef void (*f)(int);Class X{static void p(int);}f Fptr;Fptr = x::p;Если virtual: this, таблица виртуальных функций, смещений,иначе: this, адрес.class X{public delegate void delf(int);delf g;}=; +=; -=; ()//присваивание, добавление, удаление, выполнение.this хранится вместе с указателем на функцию. Делегатом может быть и статический и нестатический членкласса.1. Параметр функции – делегат.2.
Подписка – рассылка.EventProducer, EventConsumer.Почта:public delegate void OnNewMail (object o);OnNewMail onNewMail;EventProducer ep = new EventProducer();EventConsumer ec = new EventConsumer();ec.onNewMail += new OnNewMail(…); //подпискаOnNewMail(MailMessage);//рассылка.Незащищено. =>public delegate void OnNewMail(object o);public event OnNewMail onNewMail; Толькo += или -=.Глава 6. Логические модули.ТД = (множество операций = набор подпрограмм) + (множество значений = набор структур данных)Модуль = контейнерКласс:1) ТД2) КонтейнерМодуль – набор взаимосвязанных ресурсов, которые служат для использования других модулях.Модуль-ресурсы = ОД, ТД, П/П.Интерфейс = определение ресурсов + реализация.Межмодульные связи.Пространство имен в ООЯП заменена на модули.М-2:1) Главный модуль //Один2) Библиотечный модуль3) Локальный модуль //параллельное программирование.Клиент Библиотечные модули СервисКлиент Сервис.Глобальное пространство имен => видимость для всехНепосредственная видимость: имя использует ASIS.Потенциальная видимость: имя с уточнением.DEFINITION MODULE имя;Определение ресурсов.END имя;IMPLEMENTATION MODULE имя;Реализация всех процедур/функций из DEF + дополнительные ресурсы.END имя;TP, DELPHI:init имя;interface…implementationEnd имя;Все имена экспортируются в глобальное пространство имен.ПОТЕНЦИАЛЬНО.IMPORT M; //Первые в модуле => клиент.IMPORT InOut; //Видимы потенциально.InOut.WriteString(“counter”);InOut.WriteInt(out);InOut.Writeln;FROM InOut Import Writeln, WriteInt.Видны непосредственно!TP, Delphi: uses список имен; //видимы непосредственно.Оберон: оставлен только библиотечный модуль.MODULE M;…ENDM;Принцип РОРИ: Зазделение Определение Реализация Использование.* - экспорт имени.//имя *MODULE STTYPE STACK* = …PROCEDUR PUSH* (VAR S: STACK); … PROCEDURE P…END.
=> псевдомодуль.DEFINITION ST;TYPE STACK = …PROCEDURE PUSH = …D st.=> IMPORT список_имен_модулей.//В Обероне только так.=> ST.STACK //интерфейс.Или FROM ST IMPORT R; => R//реализация.Реальное программирование: работа с древообразным модульным проектом:1) Сверху вниз2) Снизу вверхАда: библиотечный модуль пакет(спецификация, тело)Спецификация:package M isОпределение типов, переменных, констант, заголовков процедурend M;Тело:package body M isРеализация всех процедур и функцийend M;package STANDART; //пакет стандартных имен.Пользовательские пакеты встраиваются в STANDART.Любой пакет можно вложить в другой.STANDARTpackage M1 ispackage M1.2 is…end M1.2; end M1;package M2 ispackage M2.1 ispackage M2.2 is…end M2.2; end M2.1; end M2;Тела вкладываются также, как и спецификации!Более близкое описание скрывает менее близкое описание одинаковых имен.Неявный импорт: вместе с одним именем неявно импортируется другое.С++: T operator+(T x1, T x2);Ада: function “+” (x1, x2: T) return T;Импорт: use M;//все имена становятся явно видимыми.Java: import имя_пакета.имя_класса; или имя_пакета.*;C#: using …Переименование: a renames bM-2:DEFINITION MODULE STACKS;TYPE STACK*=RECORDB:ARRAY[0..N] of T;TOP: [0..N];END;PROCEDURE PUSH*(VAR S: STACK; X: T);PROCEDURE POP*(VAR S:STACK; VAR X: T);…isEMPTY*isFULL*INIT*PEEK*…VAR DONE*: BOOLEAN; //END STACKS;Глава 7.
Инкапсуляция и абстрактный тип данных.ТД = МнОП + МнЗн;РОРИ: алгоритмы инкапсуляции.АТД = МнОП;Инкапсуляция:Единица инкапсуляции – тип.Атом инкапсуляции – отдельные поля, члены или весь тип.М-2: скрытые ТДDEFINITION MODULE STACKS;FROM MYTYPES IMPORT T;TYPE STACK; (*скрытый ТД*) //компилятор не знает, что это.PROCEDURE PUSHINITDESTROYEND STACKS.DEF транслируется в SYM(таблица символов) и OBJ(реализация). STACK ~ INTEGER или POINTER TYPE STACK = POINTER TO STACKRECSTACKREC = RECORD … END := (shallow, copy), = (равно), # (не равно)Ада 83:приватный ТД (~скрытый ТД)ограниченно приватный ТД package stacks is type stack is private;… - описание всех заголовков.private… - описание всех приватных структур данных.:=, =, /= ограниченно приватный:type T is limited privaty;… - оперции.private type T is … ;Лекция.
Сергеев Николай.Межмодульные связиОпределения:РОРИ – метод, когда реализация скрыта от пользователя. Пользователю доступен лишь интерфейс , ареализация инкапсулирована.Тип данных = множество значений + множество операцийАбстрактный тип данных = множество операцийКонтейнер - средство создания новых типов данных.
В некоторых языках контейнером выступают модули(Модула – 2, Ада, С#(namespace), Java(package)), в других - классы, структуры(С++, С). Delphi – гибрид,содержащий как модули, так и классы.Атомы инкапсуляции – минимально возможные данные, которые можно скрыть от пользователя. Для всехкласс – ориентированных языков атомы инкапсуляции – это поля класса, а таких языках как Ада, Модула – 2 –минимальным атомом является весь класс, то есть хороший программист на таких языках всегда используетабстрактные типы данных.Модуль - независимая единица трансляции. Подключить модуль чаще всего означает заимствоватьнаписанный кем – то код, сохраненный в модуль.
Множество языков имеют кучу встроенных библиотечныхмодулей, реализация которых опирается на РОРИ. Структура модулей как правило древовидная.Видимость подразумевает возможность обращения с объектом, то есть , к примеру, знаем его имя итип. непосредственно видимы в глобальном пространстве имен только модули Имена полей измодуля видимы только потенциально.3 подхода организации проектирования модулейБез сомнения, главнейшее условие успешного создания крупных программ заключается в применениинадежных методов проектирования. Широкое распространение при написании программ получилиследующие три метода: нисходящий (сверху вниз), восходящий (снизу вверх) и специальный (на данныйконкретный случай).