лекция 11 (Языки программирования (лекции) (2008))

2019-09-19СтудИзба

Описание файла

Файл "лекция 11" внутри архива находится в папке "Языки программирования (лекции) (2008)". Документ из архива "Языки программирования (лекции) (2008)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "лекция 11"

Текст из документа "лекция 11"

Языки программирования.

Лекция 11.

Функциональный тд (продолжение)

В прошлый раз мы начали рассматривать конкретную реализацию концепции процедурных и функциональных тд в разных яп (Модула 2, Оберон и Ада).

1. Ада

А) В языке Ада 83 подпрограммного типа (т.е. функционального типа) не было вообще. Когда возникает потребность передать функцию, как параметр. Рассмотрим пример функции интегрирования Integral(F, ...). очевидно, что один из параметров – это интегрируемая функция. Это типичный случай, когда в качестве параметра мы передаем значений конкретной функции, которая где-то описана – т.е. это константа функционального типа.

Введение нового процедурного (подпрограммного типа) связано с тем фактически в таких языках, как Модула 2, Оберон и Си, и Паскаль то, что подразумевалось под подпрограммным типом - есть указатель на конкретную функцию. А как мы говорили указатель вещь весьма ненадежная. Поэтому говорить о том, что язык в котором есть указатели на функции – надежный не приходится, поэтому в Аде 83 не было, вместо этого используется концепция родовых сегментов (аналогичная шаблонам в Си++). Проблема передачи априори известной статической функции решается за счет статической параметризации.

Б) На языке Ада 95 появился подпрограммный тип данных:

type Integrand is access function (in real) return real; такая запись говорит о том, что Integrand это указатель на соответствующие функции, и когда описываем процедуру интегрирования, то одним из параметров может выступать Integrand.

procedure Integral (F:Integrand; ...) // описание заголовка процедуры

Integral (EXP ' access; ...); // вызов процедуры, т.е. как бы явным образом берем адрес от конкретной функции (в нашем случае экспоненты), слово access здесь присутствует в поддержании обей концепции читабельности (readability) языка Ада

Такие новшества в Аде 95 были вызваны изменениями требований к языку, в 1995 году Ада была не единственным, а одним из многих яп и для того чтобы эффективно работать на этом языке было необходимо связывать программы на этом языке с программами на других языках, которые в большинстве своем были написаны на Си. В большинстве своем появление подпрограммного типа связано именно с этим. В Си и Фортран необходимо передавать указатели на соответствующие функции и процедуры, такую концепцию можно использовать, хотя она и не совсем надежна, для динамической параметризации соответствующих модулей. Заметим что статическая параметризация, которая была в Аде 83 и осталась в Аде 95, она с точки зрения компиляции немного более эффективна.

2. Современные языки

А) Delphi не рассматриваем, так как это эклектичный язык, т.е. язык - наследник Паскаля, кроме того присутствуют вкрапления из Си, Модула 2, и еще объектно-ориентированная нашлепка.

Чисто объектно-ориентированный язык

Б) В языке Java указателей нет вообще. Как написать процедуру интегрирования? Нужно понимать, что понятие функции и процедуры пришло из императивных языков, Java поддерживает объектно-ориентированную парадигму. Программа на языке Java есть набор классов, кроме классов у нас есть еще экспорт и импорт пакетов. Всё интересное происходит внутри классов. class X {...};

Процедура интегрирования не имеет смысла – имеет смысл некий интегрирующий класс, можно написать, что Integrand это некоторый класс, который содержит внутри себя метод, который и будет интегрирующей функцией. и процедура Integral она что делает, класс Integrand рассматривается как класс и вместо аргумента вызывается метод – интегрирующая функция. И как нам проинтегрировать конкретную функцию – мы делаем свой экземпляр класса Integrand, унаследуем от него от метод. Например, функцию EXP переопределим как интегрирующий метод. Всё на свете должно быть сведено к классам и методам их доступа. И в принципе механизм наследования он в общем случае более общий чем механизм параметризации. Можно было с помощью параметров ввести понятие функции, однако если у нас есть динамическое связывание методов, то этого в принципе достаточно, чтобы промоделировать параметризацию произвольных объектов на основе наследования. Стиль программирования меняется, зато у нас полная надёжность - никаких фокусов с указателями в языке Java быть не может.

В) Интересная ситуация с языком Cи#, который с одной стороны претендует на роль чистого объектно-ориентированного языка (J# - расширение языка Java под .NET, и если сравнивать J# и Cи#, то Cи# гораздо ближе к Java, чем к Си++). Cи# гораздо шире по своим возможностям, не за счет новых концепций, а потому что расширена область применения языка. Так в Cи# есть указатели, но они могут применяться только в специальных блоках. В есть unsafe-блоки, в которых мы можем делать небезопасный код, очень похожий на Си++. Такие блоки должны быть подписаны, и пользователь может отключить их. Так, например:

Unsafe

{

char *m = malloc (10);

}

Понятие функционального типа данных оказалось достаточно удобным, появилась специальная концепция делегатов - обладает концепциями функционального типа. Обладает многими достоинствами функционального тд, в то же время не обладая его недостатками. Введено понятие делегата, внешне объявление делегата очень похоже на объявление функционального типа и в Обероне, и в Модуле 2, и в Аде 95. Ключевое слово delegate, за которым идёт спецификация подпрограммы.

delegate void Handler (Object o, Args e); // Handler - имя функционального типа.

В Cи#, как и в языке Java, нет просто функций. Есть понятие пространства имен, внутри этого пространства могут быть только объявления классов и перечислимых типов. Нет понятий глобальных функций или глобальных переменных. Если речь идет о функции, то сразу определяется к какому классу она принадлежит.

  • Если есть объявление Handler P; то P - делегат (функция с двумя указанными выше параметрами Object o, Args e). Вызывать её можно как обычно:

string S;

Args t;

P(S, t); // поскольку любой объект может быть преобразован к класс object, то это здесь и произойдет с помощью специальной процедуры boxing

  • К делегату применимы операции:

- круглые скобки (вызов функции)

- присваивание (P = F), внешне делегат выглядит как функция;

void F(Object o, Args x);

void G(Object o, Args x);

P = F; // такое присваивание инициализирует делегат, если попытаемся вызвать неинициализированный делегат, то произойдет системная ошибка

- "+=" и "-=": P+=G - делегат может иметь в себе несколько объектов функционального типа. P-=F; (добавление и исключение функций из списка). Вызов делегата в таком случае – это поочередной вызов зарегистрированных функций. Порядок вызова не фиксирован.

Чем делегат удобней, чем указатели на члены:

1. Делегат может держать несколько функций.

2. Делегат - конструкция безопасная. Никакого отношения к понятию указателя делегат не имеет.

3. обговаривалось, что в Си# все функции являются функциями-членами, однако при P=F, ничего не говорилось о том, что собой представляет функция F. Присваивание P=F не совсем верно. Надо сначала инициализировать:

P = new Handler(F); // (только для статических функций-членов класса)

P = new Handler (X.F); // Где: X - ссылка на целевой объект (target object); F - имя соответствующей функции;

А в делегатском списке каждый элемент – это ссылка на целевой объект и ссылки на соответствующую функцию. Таким образом делегаты похожи на указатели на члены из Си++, но все-таки делегаты шире. Потому что указатель на член – может быть только указателем на член данного класса, а здесь объектами одного и того же делегата могут быть любые функции, удовлетворяющие прототипу соответствующего хедера. А в случае указателей – указатель на статический объект будет нулевым, и компилятор это определит. Имя_объекта.имя_функции – это ссылка на объект запоминается как целевой объект, и соответственно ссылка на метод, компилятор проверит совпадает ли метод с сигнатурой делегата.

Все недостатки классического функционального типа, как указателя преодалены, и в то же время очень большая эффективность.

Частным случаем делегатов являются события, о которых мы будем говорить позже.

Переменный список аргументов.

Уже в языке С++ появился переменный список аргументов, например:

int printf(const char* fmt, ...); // Функция обязана иметь хотя бы один явный аргумент.

Для использования списка параметров дополнительно были введены специальные макросы: va_start, va_list, va_end, которые позволяют получить доступ поочередно к каждому параметру из списка, этот параметр считается совместим с int или с любым указательным типом, например void *. Берем и преобразуем к нужному типу, при этом никакого контроля нет, эта возможность признавалась одной из самых опасных в Си и Си++. Раз она опасна, то ее следует изничтожить.

В Паскале так же были переменные списки параметров, но только в стандартных процедурах. Например, writeln (x,y,z); // верно

writeln; // верно

Именно с точки зрения ввода-вывода переменный список параметров очень удобен.

Пример: на Си

printf("Count = %d\n", cnt);

на языке Оберон то же самое:

InOut.WriteString("Count = ");

InOut.WriteInt(cnt)

InOut.Writeln;

И это только для одного параметра, а если их будет больше? Кроме того проблема читабельности текста программы.

Концепция объектной ориентации может довольно элегантно решить эту проблему. Так в Си# ее решили достаточно просто. Напомним, что любой класс языка наследуется из класса Object, а любого не-класса (структура, или объект простого тд) существуют классы обертки.

Console.Write("Count = {0}\n", Cnt);// это метод имеет переменное число параметров

Процедура write имеет прототип:

void Write(String fmt, params object[] args); {0} - индекс элемента в списке параметров, индексы в общем случае могут быть вычисляемы

params – ключевое слово, когда компилятор видит это слово, первый параметр отождествляет с форматом, а из переменного списка параметров делает массив. У массива есть свойство длина – сразу можно вычислить. Как write догадывается, что нужно выводить целое число – по типу. В современных объектно-ориентированных языках есть динамическая идентификация типа, у нас есть надежное и контролируемое преобразование из ссылки object к любому конкретному типу Т. Могут быть ошибки, но эти ошибки будут отловлены именно в момент их возникновения, у нас не произойдет соответствующего преобразования типов.

Общий вид:

params T[] args - соответствует любой список параметров от пустого. Компилятор пытается переменный список объектов свести к однотипным объектам, тем которые указаны в объявлении, а ключевое слово params говорит о том, что отождествляется произвольный список, если его убрать то void Write(String fmt, Т[] args); - всего два параметра, второй – это массив (уже не компилятор, а сам программист его формирует). Такое решение может привести к дополнительным накладным расходам, но является надежным.

Глава 4: Определение новых типов данных

Определение: Тип данных - это множество значений (определяется самой структурой типа) плюс множество операций (определяет поведение объекта данного типа). Тип данных характеризуется прежде всего множеством операций.

Пример1: множество значений не есть однозначное множество

А)Типы int и unsigned int в языках Си и Си++ одинаковое множество значений, по крайней мере, с точки зрения реализации, но разное множество операций.

Б)В Си# byte: 0-255, sbyte: -128-127 - с точки зрения реализации множество значений одинакова, но разная интерпретация этого множества значений, а именно с точки зрения множества операций и семантики операций типы и отличаются.

Пример 2:

record

body: array [1..50] of T;

t: integer;

end.

Что это за тип – может быть что угодно, однако мы можем сказать, что это стек (где Т – верхушка, body – тело – хотя этого можно и не говорить), и применимы операции:

Push(X: T);

T Pop();

IsEmpty();

И сказать, что если применить push, а затем сразу pop то вернется Х. Теперь понятно какой тип данных мы ввели.

Средства для объявления новых тд появились уже давно, с современной точки зрения, в языках должны быть средства абстракции и средства защиты этой абстракции. В данном случае одно из средств защиты состоит из того, что нам необходим некий контейнер, который объединяет в себе как структуру данных соответствующую и связанные с ней объявления, так и множество операций. Рассмотрим каким образом реализуются эти контейнеры.

Все ЯП делятся на две основные группы:

1. Модульные языки (Модула-2, Оберон, Дельфи, Ада) - существует концепция Module, Unit, Package - логический модуль, который представляет собой коллекция ресурсов;

2. ЯП с классами - есть понятие класс, с одной стороны является обёрткой (сводит множество значений и множество операций), но ещё он является и типом (дуальность классов).

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5224
Авторов
на СтудИзбе
426
Средний доход
с одного платного файла
Обучение Подробнее