Лекции (1129116), страница 12

Файл №1129116 Лекции (Лекции) 12 страницаЛекции (1129116) страница 122019-05-11СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 12)

// то и переменная передастся как бы по ссылке

С++, с этой точки зрения, не менее мощный язык, но более опасный. В таких случаях, он предлагает использовать явным образом ссылки. Заменителем операции ToString в С++ служит оператор преобразования к типу данных char* или CString. Но для преобразования в CString, программист должен сам задать оператор преобразования типа в CString, и тогда компилятор сможет автоматически подставлять это преобразование. К сожалению, за все надо платить, и иногда, неявные преобразования выходят боком.

Язык Delphi, с точки зрения средств развития, кажется не менее мощным, чем С++ и Java. Как и в Java, создателям Delphi, необходимо было интегрировать тип данных String в язык. В языке Delphi нельзя написать класс, который эквивалентен по функциональности классу String. Кроме того, нельзя переопределять операций работы со сроками, и поэтому теряется гибкость. С этой точки зрения, концепция типов, встроенных в язык несколько порочна, потому что для любой самой изысканной реализации подобного рода встроенных типов данных, всегда можно найти вариант реализации, который будет работать для вашего приложения значительно лучше. В этом смысле, подход С++ значительно лучше.

Лекция 10

Мы начинаем рассматривать cредства развития в современных ЯП, традиционных (то есть процедурных). Кроме определения новых типов мы будем рассматривать:

  • управление доступом и абстрактные типы данных;

  • раздельная трансляция;

  • статическая параметризация (механизм шаблонов в C++ и разрывных модулей в Ada)

  • исключения (тема, которая стоит особняком, но интересная и важная с практической и теоретической точек зрения)

Это наша программа на часть, касающуюся традиционных ЯП.

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

Основными атрибутам типа данных являются:

  • множество значений

  • набор операций

Для таких типов, как массивы или записи, мы, прежде всего имели атрибут «набор операций». Например, тип:

Type T= record

Re, Im: real;

End;

связывается с операцией доступа по полю: X.Re=…

То есть подобное определение нового типа вводит лишь множество значений и небольшой набор операций, который встроен в соответствующий базисный тип данных.

Заметим, что мы хотели данным типом описать комплексное число, которому, вообще говоря, соответствует не только определенное множество значений, но и определенный набор операций (+, -, * и .т. д.). Если мы захотим описать это на ЯП Pascal, то встает два вопроса: а) как логически связать тип данных с соответствующим набором операций? б) насколько естественно впишется новый тип в структуру языка, действительно ли это будет расширением или же некий полиотип? В стандартном Pascal ответ на эти оба вопроса будет отрицательный, так как в нем полностью отсутствуют средства, позволяющие связывать множество значений и набор операций, следовательно о втором вопросе говорить даже не приходится.

Естественным образом возникает понятие логического модуля, в котором описывается новый тип. Заметим, что речь идет не о физическом модуле (мы будем разбирать их, когда коснемся раздельной компиляции).

Давайте по очереди рассмотрим, как реализованы эти логические модули в различных ЯП. Про стандартный Pascal мы ничего сказать не можем, точно также мы ничего не можем сказать о языке С, в нем тоже отсутствуют механизмы логического группирования.

Поговорим о модульной структуре языков и о том, как она применяется для формирования новых типов. Начнем с самых простых вариантов, созданных профессором Виртом: Модула-2 и Oberon.

В Модула-2 существует три вида модулей:

  • главный (некий аналог функции main), он может быть только один.

MODULE имя;

Набор определений;

BEGIN

Набор операторов;

END имя;

  • библиотечный (он будет интересовать нас больше всего, т.к. одно из его предназаначений - введение новых типов данных)

  • локальный модуль (обязательно вложен либо в набор определений главного модуля, либо в процедуру)

Библиботечный модуль разделяется на две части:

  • модуль определений

  • модуль реализаций

Эти два модуля имеют одинаковое имя, но различную структуру. Модуль определений служит для того, чтобы показать интерфейс модуля (каждый модуль имеет интерфейс для связи с внешним миром) – это набор имен и их свойств (атрибуты, если это тип данных; тип, если это переменная; значение, если константа и т.д.), которые видны извне этого модуля, т.е. только этими именами можно пользоваться. Напишем модуль определений, который реализует модуль Stacks (он представляет некий механизм работы со стеками):

DEFINITION MODULE Stacks;

Type Stack =

RECORD

Body: ARRAY [1..50] OF CHAR;

Top: 1..51;

END;

PROCEDURE PUSH (VAR S: Stack; X: CHAR);

PROCEDURE POP (VAR S: Stack): CHAR;

VAR errcode: INTEGER;

PROCEDURE INIT (VAR S: Stack);

END Stacks.

В этом модуле мы указываем только прототипы. На случай, когда у нас возникает ошибка (например, переполнение стека) мы вводим переменную errcode, которая фактически является частью типа, а с другой стороны – ему не принадлежит. Такие переменные называются членами класса, она принадлежит одновременно всем переменным класса. В C++ и Java такие переменные называются статическими. В этой переменной «сидит» последний код ошибки.

Процедура INIT инициализирует стек. Тем самым мы ввели новый тип и набор операций над ним.

IMPLEMENTATION MODULE Stacks;

{ Определения процедур и функций из Defenition Module

Здесь также могут быть и другие дополнительные определения}

[ BEGIN

Операторы; Errcode=0;

END Stacks. ]

Часть в квадратных скобках может отсутствовать. В качестве инициализации мы сопоставляем переменной Errcode Значение 0. Эта инициализирующая часть выполняется лишь один раз в момент загрузки модуля. Обычно она очень короткая или может вообще отсутствовать.

Зачем нужен модуль реализации? Зачем выделять его отдельно? Дело в том, что все, что находится внутри модуля реализации недоступно извне. Программист, использующий конкретный библиотечный модуль имеет доступ только к определениям, описанным в интерфейсной части. Это есть некое управление доступом. Позже мы заметим, что такое разделение имеет отношение еще и к механизму раздельной компиляции в ЯП Модула-2. Что нужно компилятору, чтобы корректно откомпилировать клиентский модуль (модуль, использующий Stacks)? Ему нужен только модуль определений, так как в нем есть все необходимые данные. Модуль реализации нужен лишь для того, чтобы собрать готовую работающую программу. Заметим, что Н.Вирт убил здесь сразу нескольких зайцев.

В Turbo Pascal, например, такого разбиения на два модуля нет, там две части – объявления и реализация объединены в одной физической части:

Unit имя;

Interface

{…}

implementation

{…}

end.

Можно ли упростить эту схему? Рассмотрим язык Oberon. Вирт для создания этого языка выкинул из Modula-2 все не необходимые вещи, то есть еще минимизировал этот и без того простой язык и добавил одну концепцию, а именно, концепцию расширения функций. Что выкинул Вирт? Деление на две физические части, понятие локального модуля и понятие главного модуля. В Обероне отсутствует понятие главного модуля вообще. В нем есть только одно понятие – модуля.

MODULE имя;

Набор определений;

BEGIN

Инициализация

END имя.

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

У возникшей проблемы есть некоторое решение. Дело в том, что современные ЯП представляют из себя не столько компилятор, сколько интегрированную среду, включающую в себя редактор, компилятор, управление проектами, помощью и т.д. И с этой точки зрения в Обероне принято следующее – у нас есть только один модуль, например:

MODULE Stacks;

TYPE Stack * =

RECORD

Top: INTEGER;

Body: ARRAY 50 OF CHAR;

END;

PROCEDURE PUSH * (VAR S: Stack; X: CHAR);

END Stacks;

Звездочка после имени говорит о том, что имя является экспортируемым.

Что хорошо и что плохо?

Хорошо то, что мы освобождаемся еще от одного языкового понятия. И еще (этого нельзя сделать в Модула-2), заметим, что у Top и Body отсутствуют звездочки, это говорит о том, что тип данных Stack доступен только через свое имя и экспортируемый набор операций. То есть мы упрятали поля Top и Body от несанкционированного доступа. Заметим, что в Модула-2, если мы что-то сделаем с элементом Top, то стек испортится. Здесь же мы имеем очень хорошую и естественную защиту от случайной порчи. К тому же, можно давать доступ к отдельным полям записи.

А плохо то, что если иметь маломальски нормальный модуль, то разобраться по тексту, что там происходит, что экспортируется, а что нет – весьма тяжело. От этой проблемы нас как раз и избавляет интегрированная среда Oberon’а, которая включает в себя средство генерирования модуля определения. По нашему модулю она выдаст следующее:

DEFENITION Stacks;

TYPE Stack = RECORD END;

PROCEDURE PUSH;

END Stacks;

И далее можно пользоваться только вот этим сгенерированным модулем определений. Это решение тоже влечет некоторые недостатки с точки зрения раздельной компиляции. Но об этом будем говорить позже.

Перейдем к языку Ada. Мы начали с простых схем – языков Pascal, Modula-2, Oberon. Ada представляет некоторое усложнение. В нем существует понятие логического модуля, которое называется Package:

Package Stacks is

Record

Body: array (1..50) of character;

Top: 1..51;

End record;

Procedure Push(S: inout Stack; X: character);

Procedure Pop(S: inout Stack; X: out character);

End Stacks

Процедуру Pop, вообще говоря, следует описать как функцию, но тут есть один ньюанс: в Ada функции могут иметь только IN параметры, а в нашем случае параметр типа Stack следует передавать, как INOUT.

Заметим, что, не считая синтаксической разницы, мы получили в чистом виде модуль определения языка Modula-2. И, следовательно, должна быть конструкция, которая идейно соответствует модулю реализаций, где будут конкретизироваться процедуры и функции, а также будут вводиться какие-то данные (типы, процедуры и т.п.) необходимые для внутренней реализации. Такая конструкция есть и называется она «Телом пакета»:

Package body Stacks is

end Stacks;

Несмотря на похожесть с Modula-2 в Ada имеются и различия (с точки зрения организации доступа, плюс некоторые усложнения). Дело в том, что в Ada существуют так называемые «локальные пакеты». Уже было сказано о локальных модулях в Modula-2 – это крайне ограниченная конструкция, он имеет следующий вид:

MODULE имя;

EXPORT список имен;

Определения

BEGIN

Инициализация

END имя;

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

В Ada ситуация немного другая, мы можем создавать вложенные пакеты:

package M is

package M_IN is

end M_IN;

end M;

Причем вложенный пакет имеет свой нормальный интерфейс и свое тело, причем тело будет реализовано по структуре там же, где и описание:

package body M is

package body M_IN is

end M_IN;

end M;

Какой стиль программирования поддерживает такие пакеты? В курсе Технологии Программирования рассказывается о том, что существуют различные способы построения программ, один из них – снизу вверх:

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

Сверху вниз:

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

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

Характеристики

Тип файла
Документ
Размер
1,12 Mb
Материал
Тип материала
Высшее учебное заведение

Список файлов лекций

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