Расширения файлов для программных кодов: cpp - это что? Обзор языков программирования и средств разработки на их основе Расширяемые языки программирования.

1.1 Microsoft Visual Studio C++

Microsoft Visual Studio - линейка продуктов компании Майкрософт, включающих интегрированную среду разработки программного обеспечения и ряд других инструментальных средств.

Visual Studio включает один или несколько компонентов из следующих:

Visual Basic .NET, а до его появления - Visual Basic;

Visual C++;

Visual C#.

Многие варианты поставки также включают:

Microsoft SQL Server либо MSDE;

Visual Source Safe - файл-серверная система управления версиями;

В прошлом, в состав Visual Studio также входили продукты:

Visual InterDev;

Visual J++;

Visual J#;

Visual FoxPro.

Наиболее значимые версии пакета:

Visual Studio 97 - первая выпущенная версия Visual Studio, в ней впервые были собраны вместе различные средства разработки ПО. Она была выпущена в двух версиях Professional и Enterprise. Она включала в себя Visual Basic 5.0, Visual C++ 5.0, Visual J++ 1.1, Visual FoxPro 5.0, впервые появилась среда разработки ASP - Visual InterDev. Visual Studio 97 - была первой попыткой Microsoft создать единую среду для разработки на разных языках программирования: Visual C++, Visual J++, Visual InterDev, и MSDN использовали одну среду, называемую Developer Studio. Visual Basic и Visual FoxPro использовали отдельные среды для разработки.

Visual Studio 6.0 - выпущена в июне 1998 - последняя версия Visual Studio работающая на платформе Win9x. По-прежнему популярна среди программистов, использующих Visual Basic. Данная версия являлась основной средой разработки приложений под Windows от Microsoft, до появления платформы.NET.

Visual Studio .NET (кодовое имя Rainier; внутренняя версия 7.0) - выпущена в феврале 2002 (влючает.NET Framework 1.0). Service Pack 1 для Visual Studio .NET (2002) выпущен в марте 2005.

Visual Studio .NET 2003 (кодовое имя Everett; внутренняя версия 7.1) - выпущена в апреле 2003 (влючает.NET Framework 1.1). Service Pack 1 для Visual Studio .NET 2003 выпущен 13 сентября 2006.

Visual Studio 2005 (кодовое имя Whidbey; внутренняя версия 8.0) - выпущена в конце октября 2005 (включает.NET Framework 2.0). В начале ноября 2005 также вышла серия продуктов в редакции Express: Visual C++ 2005 Express, Visual Basic 2005 Express, Visual C# 2005 Express и др. 19 апреля 2006 редакция Express стала бесплатной. Service Pack 1 для VS2005 и всех Express-редакций выпущен 14 декабря 2006 года. Дополнительный патч для SP1, решающий проблему совместимости с Windows Vista выпущен 3 июня 2007.

Visual Studio 2008 (кодовое имя Orcas) - выпущена 19 ноября 2007, одновременно с.NET Framework 3.5. Нацелена на создание приложений для ОС Windows Vista (но поддерживает и XP), Office 2007 и веб-приложений. Включает в себя LINQ, новые версии языков C# и Visual Basic. В студию не вошёл Visual J#. С 28 октября 2008 года впервые доступна версия на русском языке.

Продукт-преемник Visual Studio 2008 имеет кодовое имя Hawaii. 29 сентября 2008 года появился анонс , представляющий некоторые новшества, которые появятся в Visual Studio 2010 и.NET Framework 4.0.

Разработчик приложений, решивший воспользоваться услугами Visual Studio.Net 7.0, получает в свое распоряжение достаточно много новых технологий и инструментов, которые позволяют ему быстро и эффективно создавать обычные Windows-приложения, которые теперь принято называть настольными - desktop applications, а также web-приложения и web-услуги (Web Services). Компания Microsoft добавила в арсенал программиста новый язык С# (произносится «Си шарп»), который, как обещают специалисты, способен в несколько раз ускорить цикл разработки сложных проектов.

Главной новостью, которая должна привлечь ваше внимание, является то, что Visual C++, Visual Basic и С# используют одну и ту же среду разработки IDE (Integrated Development Environment), что дает возможность создавать комплексные проекты с использованием разных языков (mixed-language solutions). Многоязыковая среда разработки.Net (.Net Framework) представляет собой сумму трех составляющих:

общая для рассмотренного набора языков библиотека времени исполнения (Common Language Runtime);

унифицированная библиотека классов разработчика (Unified Programming Classes);

модель разработки web-приложений (Active Server Pages.Net).

Первая составляющая - библиотека времени исполнения (Common Language Runtime, сокращенно CLR), функционирует как на этапе выполнения, так и на этапе разработки. Во время выполнения кода она следит за динамикой многопотоковых приложений, обеспечивает взаимосвязь процессов, поддерживает их безопасность, автоматизирует процедуры выделения и освобождения памяти. На этапе разработки CLR автоматизирует типовые задачи, решаемые программистом, значительно упрощая использование новых технологий. Особо отмечаются преимущества, получаемые при создании компонентов стандарта COM (Component Object Model, сокращенно COM - Модель многокомпонентных объектов).

Вторая составляющая (Unified Programming Classes) предоставляет разработчику унифицированную, объектно-ориентированную, расширяемую библиотеку классов, которая совместно с другими ресурсами является частью программируемого интерфейса приложений API (Application Programming Interface). Она объединяет элементы MFC (Microsoft Foundation Classes), WFC (Windows Foundation Classes) и часть API, используемую Visual Basic.

Третья составляющая (ASP.Net) представляет собой надстройку на.д классами, которая дает возможность пользоваться объектно-ориентированной технологией при разработке типовых элементов HTML-интерфейса. Фактически выполняемые на стороне сервера, эти элементы проецируют функции пользовательского интерфейса в виде HTML-кода. Однако при разработке сервера имеется возможность использовать мощный аппарат, предоставляемый объектной моделью программирования. Результат - резкое упрощение процесса построения web-приложений. В дополнение к этому ASP.Net поддерживает достаточно новую концепцию или модель разработки программ. Вы, наверное, слышали о ней, как о технологии «тонкого» клиента. Основная суть этой модели - предоставление кода пользователю не в виде инсталлируемого продукта, а в виде временной услуги (service).

Код, который создан на основе среды разработки.Net Framework, носит название управляемого кода {managed code) в отличие от обычного, неуправляемого кода (unmanaged code). В режиме.Net компиляторы рассмотренных языков производят метаданные (metadata), которые сопровождают сам код. Это означает, что они генерируют дополнительную информацию, описывающую типы данных, объекты и ссылки. Библиотека времени исполнения (Common Language Runtime) использует метаданные для поиска и загрузки объектов, запуска функций, передачи параметров, размещения объектов в памяти.

Важной функцией, которую выполняет библиотека времени исполнения, является автоматическое освобождение памяти, занимаемой объектами, которые более не используются. Это нововведение призвано повысить надежность как отдельных компонентов, так и всего разрабатываемого приложения. Данные, время жизни которых управляется таким образом, называются управляемыми данными (managed data). Если ваш код является управляемым (managed code), то вы можете пользоваться управляемыми данными, но можете и не использовать их. Более того, вы можете и не знать, являются ли ваши данные управляемыми.

Общая библиотека времени исполнения (CLR) упрощает создание приложений и их составляющих, которые разработаны на разных языках и настроены (target) на использование CLR. Эти модули могут быть интегрированы в одном проекте и взаимодействовать между собой так, как будто они были созданы на одном языке. Например, вы можете декларировать класс, а затем создать производный от него класс уже на другом языке. Можно и просто пользоваться методами класса в рамках модуля, написанного на другом языке. Такая интеграция стала возможной потому, что компиляторы и инструменты разных языков пользуются общей системой типов, определенной в CLR, а также новыми правилами игры, принятыми при ее разработке.

1.2 C++ Builder

Borland C++ Builder — выпущенное недавно компанией Borland средство быстрой разработки приложений, позволяющее создавать приложения на языке C++, используя при этом среду разработки и библиотеку компонентов Delphi. В настоящей статье рассматривается среда разработки C++ Builder и основные приемы, применяемые при проектировании пользовательского интерфейса.

C++ Builder представляет собой SDI-приложение, главное окно которого содержит настраиваемую инструментальную панель (слева) и палитру компонентов (справа). Помимо этого, по умолчанию при запуске C++ Builder появляются окно инспектора объектов (слева) и форма нового приложения (справа). Под окном формы приложения находится окно редактора кода.


Рис.1. Среда разработки C++ Builder

Формы являются основой приложений C++ Builder. Создание пользовательского интерфейса приложения заключается в добавлении в окно формы элементов объектов C++ Builder, называемых компонентами. Компоненты C++ Builder располагаются на палитре компонентов, выполненной в виде многостраничного блокнота. Важная особенность C++ Builder состоит в том, что он позволяет создавать собственные компоненты и настраивать палитру компонентов, а также создавать различные версии палитры компонентов для разных проектов.

Компоненты разделяются на видимые (визуальные) и невидимые (невизуальные). Визуальные компоненты появляются во время выполнения точно так же, как и во время проектирования. Примерами являются кнопки и редактируемые поля. Невизуальные компоненты появляются во время проектирования как пиктограммы на форме. Они никогда не видны во время выполнения, но обладают определенной функциональностью (например, обеспечивают доступ к данным, вызывают стандартные диалоги Windows 95 и др.)


Рис. 2. Пример использования видимых и невидимых компонентов

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

Каждый компонент C++ Builder имеет три разновидности характеристик: свойства, события и методы.

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

Свойства являются атрибутами компонента, определяющими его внешний вид и поведение. Многие свойства компонента в колонке свойств имеют значение, устанавливаемое по умолчанию (например, высота кнопок). Свойства компонента отображаются а странице свойств (Properties). Инспектор объектов отображает опубликованные (published) свойства компонентов. Помимо published-свойств, компоненты могут и чаще всего имеют общие (public), опубликованные свойства, которые доступны только во время выполнения приложения. Инспектор объектов используется для установки свойств во время проектирования. Список свойств располагается на странице свойств инспектора объектов. Можно определить свойства во время проектирования или написать код для видоизменения свойств компонента во время выполнения приложения.

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

1.3 Delphi

Delphi - среда разработки, использует язык программирования Delphi (начиная с 7 версии язык в среде именуется Delphi, ранее - Object Pascal), разработанный фирмой Borland и изначально реализованный в её пакете Borland Delphi, от которого и получил в 2003 году своё нынешнее название. Object Pascal по сути является наследником языка Pascal с объектно-ориентированными расширениями.

Delphi - это среда быстрой разработки, в которой в качестве языка программирования используется язык Delphi. Язык Delphi - строго типизированный объектно-ориентированный язык, в основе которого лежит хорошо знакомый программистам Object Pascal.

Delphi — это комбинация нескольких важнейших технологий:

    высокопроизводительный компилятор в машинный код;

    – объектно-ориентированная модель компонент;

    – визуальное (а, следовательно, и скоростное) построение приложений из программных прототипов;

    – масштабируемые средства для построения баз данных.

    Borland Delphi 8 Studio позволяет создавать самые различные программы: от простейших однооконных приложений до программ управления распределенными базами. В состав пакета включены разнообразные утилиты, обеспечивающие работу с базами данных, XML-документами, создание справочной системы, решение других задач. Отличительной особенностью седьмой версии является поддержка технологии.NET.

    Основной упор модели в Delphi делается на то,чтобы максимально производительно использовать код.. Это позволяет очень быстро разрабатывать приложения, так как уже существуют заранее подготовленные объекты. А так же вы можете создавать свои собственные объекты, без каких-либо ограничений. Язык Delphi - строго типизированный объектно-ориентированный язык, в основе которого лежит хорошо знакомый программистам Object Pascal.

    В стандартную поставку Delphi входят основные объекты из 270 базовых классов. На этом языке очень удобно писать, как приложения к базам данных, так даже и игровые программы. Если принять во внимание и удобный интерфейс для создания графических оболочек, то можно с уверенностью заявить что язык Delphi – это очень доступный для понимания, но в то же время и очень мощный язык программирования.

    Первая версия полноценной среды разработки Delphi для.NET - Delphi 8. Она позволяла писать приложения только для.NET. В настоящее время, в Delphi 2006, можно писать приложения для.NET, используя стандартную библиотеку классов.NET, VCL для.NET. Среда также позволяет создавать.NET-приложения на C# и Win32-приложения на C++. Delphi 2006 содержит функции для написания обычных приложений с использованием библиотек VCL и CLX. Delphi 2006 поддерживает технологию MDA с помощью ECO (Enterprise Core Objects) версии 3.0.

    В марте 2006 года компания Borland приняла решение о прекращении дальнейшего совершенствования интегрированных сред разработки JBuilder, Delphi и C++ Builder по причине убыточности этого направления. В августе 2006 года Borland выпустил облегченные версию RAD Studio под именем Turbo: Turbo Delphi, Turbo Delphi for .NET, Turbo C#, Turbo C++. В марте 2008 года было объявлено о прекращении развития этой линейки продуктов.

    В марте 2007 года CodeGear порадовала пользователей обновленной линейкой продуктов Delphi 2007 for Win32 и выходом совершенно нового продукта Delphi 2007 for PHP. В июне 2007 года CodeGear представила свои планы на будущее, то есть опубликовала так называемый roadmap, с которым можно ознакомиться здесь

    25 августа 2008 года компания Embarcadero, новый хозяин CodeGear, опубликовала пресс-релиз на Delphi for Win32 2009. Версия принесла множество нововведений в язык, как-то:

    – полная поддержка Юникода по умолчанию во всех частях языка, VCL и RTL;

    – обобщённые типы, они же generics.

    – анонимные методы.

    Среди многих распространенных программных продуктов, сделанных на Delphi, можно найти:

    1.Продукция Borland: Borland Delphi, Borland C++ Builder, Borland JBuilder 1 и 2 версии.

    2.Администрирование/разработка баз данных: MySQL Tools (Administrator, Query Browser), IBExpert, TOAD

    3.Инженерное ПО: Altium Designer/Protel (проектирование электроники).

    4.Просмотрщики графики: FastStone Image Viewer, FuturixImager, Photofiltre.

    5.Видео и аудио проигрыватели: KMPlayer (видео- и аудиопроигрыватель), X-Player (аудиопроигрыватель).

    6.Доставка информации в Интернете: Skype (VoIP и IM), QIP, QIP Infium и R&Q, (ИМы), The Bat! и si.Mail (клиенты электронной почты), PopTray (средство для проверки почты), FeedDemon (просмотр RSS/Atom новостных групп), XanaNews (чтение новостных групп), Xnews (чтение новостных групп).

    7.Создание музыки: FL Studio (ранее FruityLoops).

    8.Разработка программного обеспечения: Dev-C++, Dev-PHP , Maguma Open Studio и Open Perl IDE (IDE), DUnit (юнит-тестирование), Jedi Code Format (форматирование программного кода), Game Maker (создание игр) Help & Manual (система авторинга справки), Inno Setup (движок для инсталляции).

    9.Веб-разработка: Macromedia HomeSite (HTML-редактор), TopStyle Pro (CSS-редактор), Macromedia Captivate (захват экрана), Quick Page 2008 (Среда разработки Web-сайтов).

    10.Веб-браузеры (оболочки для MSIE): Avant Browser, Netcaptor.

    11.Утилиты: Spybot - Search & Destroy, Ad-Aware (антишпионское ПО), jv16 PowerTools, FDK (многофункциональная утилита для оптимизации системы), Total Commander и Frigate (файловые менеджеры), DarkCrypt TC/GUI (программный комплекс для шифрования), ImageSpyer и StegoTC (программный стеганографический комплекс), Copernic Desktop Search, PowerArchiver и PeaZip (архиваторы), MCubix (интеллектуальный анализ данных), Download Master [менеджер закачек], ACProtect (программа для упаковки и защиты EXE-файлов).

    12.Текстовые редакторы: SynEdit, Bred2, KeyNote, cEdit Professional, Programmer’s Notepad, UniRed, gleditor.

    13.Редакторы двоичных файлов (HEX-редакторы): Hexapad

    14.Бухучёт и налогообложение: Intuit’s Lacerte Professional Tax Software, включая все подсистемы, такие как QuickBooks/EasyACCT Trial Balance Utility, Document Management System и Client Database Repair Utility.

    15.Программы для чтения и каталогизации электронного текста: DarkLib (каталогизатор и мультиформатный букридер), IxReader (букридер).

    2 Сравнительный анализ возможностей (преимущества) недостатки современных объектно-ориентированных языков и средств разработки на их основе

    2.1 Object Pascal

    Object Pascal - полностью объектно-ориентированный диалект языка Pascal, разработанный фирмой Apple Computer совместно с Никлаусом Виртом. В 1986 компания Borland добавила подобное расширение Паскаля в продукт Turbo Pascal for Macintosh; с выпуском Turbo Pascal 5.5 расширение стало доступно для DOS. Начиная с Delphi 7 Borland начала официально называть свой язык Delphi. Однако Object Pascal поддерживается и развивается другими разработчиками. Наиболее серьёзные реализации Object Pascal (помимо Delphi) - это TMT Pascal, Virtual Pascal и Free Pascal.

    Любая программа в Delphi состоит из файла проекта (файл с расширением dpr) и одного или нескольких модулей (файлы с расширениями pas). Каждый из таких файлов описывает программную единицу Object Pascal.

    В окне кода жирным шрифтом выделяются так называемые зарезервированные слова, а курсивом — комментарии (так же выделяются зарезервированные слова и комментарии в книге). Как видим, текст программы начинается зарезервированным словом program и заканчивается словом end с точкой за ним. Замечу, что сочетание end со следующей за ней точкой называется терминатором программной единицы: как только в тексте программы встретится такой терминатор, компилятор прекращает анализ программы и игнорирует оставшуюся часть текста.

    Зарезервированные слова играют важную роль в Object Pascal, придавая программе в целом свойство текста, написанного на почти естественном английском языке. Каждое зарезервированное слово (а их в Object Pascal несколько десятков) несет в себе условное сообщение для компилятора, который анализирует текст программы так же, как читаем его и мы: слева направо и сверху вниз.

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

    {$R *.RES}

    на самом деле не является комментарием. Этот специальным образом написанный фрагмент кода называется директивой компилятора (в нашем случае — указание компилятору на необходимость подключения к программе так называемого файла ресурсов). Директивы начинаются символом $, который стоит сразу за открывающей фигурной скобкой.

    Поскольку речь зашла о комментариях, замечу, что в Object Pascal в качестве ограничителей комментария могут также использоваться пары символов (*, *) и //. Скобки (*…*) используются подобно фигурным скобкам т. е. комментарием считается находящийся в них фрагмент текста, а символы // указывают компилятору, что комментарий располагается за ними и продолжается до конца текущей строки:

    {Это комментарий}

    (*Это тоже комментарий*)

    //Все символы до конца этой строки составляют комментарий

    Слово Program со следующим за ним именем программы и точкой с запятой образуют заголовок программы. За заголовком следует раздел описаний, в котором программист (или Delphi) описывает используемые в программе идентификаторы. Идентификаторы обозначают элементы программы, такие как типы, переменные, процедуры, функции (об элементах программы мы поговорим чуть позже). Здесь же с помощью предложения, которое начинается зарезервированным словом uses (использовать) программист сообщает компилятору о тех фрагментах программы (модулях), которые необходимо рассматривать как неотъемлемые составные части программы и которые располагаются в других файлах. Строки

    uses

    Forms, Unit1 in ‘Unitl.pas’ {fmExample};

    указывают, что помимо файла проекта в программе должны использоваться модули Forms И Unit1. модуль Forms является стандартным (т. е. уже известным Delphi), а модуль Unit1 — новым, ранее неизвестным, и Delphi в этом случае указывает также имя файла с текстом модуля (in ‘uniti.pas’) и имя связанного с модулем файла описания формы {fmExample}.

    Собственно тело программы начинается со слова begin (начать) и ограничивается терминатором end с точкой. Тело состоит из нескольких операторов языка Object Pascal. В каждом операторе реализуется некоторое действие — изменение значения переменной, анализ результата вычисления, обращение к подпрограмме и т. п. В теле нашей программы — три исполняемых оператора:

    Application.Initialize;

    Application.CreateForm(TfmExample, fmExample);

    Application.Run;

    Каждый из них реализует обращение к одному из методов объекта Application

    Объектом называется специальным образом оформленный фрагмент программы, заключающий в себе данные и подпрограммы для их обработки. Данные называются полями объекта, а подпрограммы — его методами. Объект в целом предназначен для решения какой-либо конкретной задачи и воспринимается в программе как неделимое целое (иными словами, нельзя из объекта «выдернуть» отдельное поле или метод). Объекты играют чрезвычайно важную роль в современных языках программирования. Они придуманы для того, чтобы увеличить производительность труда программиста и одновременно повысить качество разрабатываемых им программ. Два главных свойства объекта — функциональность и неделимость — делают его самостоятельной или даже самодостаточной частью программы и позволяют легко переносить объект из одной программы в другую. Разработчики Delphi придумали для нас с вами сотни объектов, которые можно рассматривать как кирпичики, из которых программист строит многоэтажное здание программы. Такой принцип построения программ называется объектно-ориентированным программированием (ООП). В объекте Application собраны данные и подпрограммы, необходимые для нормального функционирования Windows-программы в целом. Delphi автоматически создает объект-программу Application для каждого нового проекта. Строка

    Application.Initialize;

    означает обращение к методу Initialize объекта Application. Прочитав эту строку, компилятор создаст код, который заставит процессор перейти к выполнению некоторого фрагмента программы, написанного для нас разработчиками Delphi. После выполнения этого фрагмента (программисты говорят: после выхода из подпрограммы) управление процессором перейдет к следующей строке программы, в которой вызывается метод CreateForm и т. д.

    Модули — это программные единицы, предназначенные для размещений фрагментов программ. С помощью содержащегося в них программного кода реализуется вся поведенческая сторона программы. Любой модуль имеет следующую структуру: заголовок секция интерфейсных объявлений секция реализации терминатор Заголовок открывается зарезервированным словом Unit за которым следует имя модуля и точка с запятой. Секция интерфейсных объявлений открывается зарезервированным словом Interface, a секция реализации — словом implementation. Терминатором модуля, как и терминатором программы, является end с точкой. Следующий фрагмент программы является синтаксически правильным вариантом модуля:

    unit Unit1;

    interface

    // Секция интерфейсных объявлений

    implementation

    // Секция реализации

    end.

    В секции интерфейсных объявлений описываются программные элементы (типы, классы, процедуры и функции), которые будут ‘видны’ другим программным модулям, а в секции реализации раскрывается механизм работы этих элементов. Разделение модуля на две секции обеспечивает удобный механизм обмена алгоритмами между отдельными частями одной программы. Он также реализует средство обмена программными разработками между отдельными программистами. Получив откомпилированный «посторонний» модуль, программист получает доступ только к его интерфейсной части, в которой, как уже говорилось, содержатся объявления элементов. Детали реализации объявленных процедур, функций, классов скрыты в секции реализации и недоступны другим модулям.

    Классы служат основным инструментом реализации мощных возможностей Delphi. Класс является образцом, по которому создаются объекты, и наоборот, объект — это экземпляр реализации класса. Образцы для создания элементов программы в Object Pascal называются типами, таким образом, класс TfmExamplel -это тип. Перед его объявлением стоит зарезервированное слово type (тип), извещающее компилятор о начале раздела описания типов.

    Стандартный класс TForm реализует все нужное для создания и функционирования пустого Windows-окна. Класс TfmExamplel порожден от этого класса, о чем свидетельствует строка

    TfmExample = class (TForm)

    в которой за зарезервированным словом class в скобках указывается имя родительского класса. Термин «порожден» означает, что класс TfmExample унаследовал все возможности родительского класса TForm и добавил к ним собственные в виде дополнительных компонентов, которые вставлены в форму fmExample. Перечень вставленных нами компонентов и составляет значительную часть описания класса.

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

    Объект fmExampie формально относится к элементам программы, которые называются переменными. Вот почему перед объявлением объекта стоит зарезервированное слово var (от англ. variables — переменные).

    Элементы программы — это минимальные неделимые ее части, еще несущие в себе определенную значимость для компилятора. К элементам относятся:

    зарезервированные слова;

    идентификаторы;

    типы;

    константы;

    переменные;

    метки;

    подпрограммы;

    комментарии.

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

    Идентификаторы — это слова, которыми программист обозначает любой другой элемент программы, кроме зарезервированного слова, идентификатора или комментария. Идентификаторы в Object Pascal могут состоять из латинских букв, арабских цифр и знака подчеркивания. Никакие другие символы или специальные знаки не могут входить в идентификатор. Из этого простого правила следует, что идентификаторы не могут состоять из нескольких слов (нельзя использовать пробел) или включать в себя символы кириллицы (русского алфавита).

    Типы — это специальные конструкции языка, которые рассматриваются компилятором как образцы для создания других элементов программы, таких как переменные, константы и функции. Любой тип определяет две важные для компилятора вещи: объем памяти, выделяемый для размещения элемента (константы, переменной или результата, возвращаемого функцией), и набор допустимых действий, которые программист может совершать над элементами данного типа. Замечу, что любой определяемый программистом идентификатор должен быть описан в разделе описаний (перед началом исполняемых операторов). Это означает, что компилятор должен знать тот тип (образец), по которому создается определяемый идентификатором элемент.

    Константы определяют области памяти, которые не могут изменять своего значения в ходе работы программы. Как и любые другие элементы программы, константы могут иметь свои собственные имена. Объявлению имен констант должно предшествовать зарезервированное слово const (от англ. constants — константы). Например, можyj определить константы const

    Kbyte = 1024;

    Mbyte = Kbyte*Kbyte;

    Gbyte = 1024*Mbyte;

    чтобы вместо длинных чисел

    1048576 (1024*1024) и 1073741824

    (1024*1024*1024) писать, соответственно, Mbyte и Gbyte. Тип константы определяется способом ее записи и легко распознается компилятором в тексте программы, поэтому программист может не использовать именованные константы (т. е. не объявлять их в программе явно).

    Переменные связаны с изменяемыми областями памяти, т. е. с такими ее участками, содержимое которых будет меняться в ходе работы программы. В отличие от констант переменные всегда объявляются в программе. Для этого после идентификатора переменной ставится двоеточие и имя типа, по образу которого должна строиться переменная. Разделу объявления переменной (переменных) должно предшествовать слово var. Например:

    var

    inValue: Integer;

    byValue: Byte;

    Здесь идентификатор inValue объявляется как переменная типа integer, а идентификатор byValue — как переменная типа Byte. Стандартный (т. е. заранее определенный в Object Pascal) тип integer определяет четырехбайтный участок памяти, содержимое которого рассматривается как целое число в диапазоне от -2 147 483 648 до+2 147 483 647, а стандартный тип Byte — участок памяти длиной 1 байт, в котором размещается беззнаковое целое число в диапазоне от 0 до 255 4 . Все приводимые сведения относительно диапазона возможных значений и объема памяти стандартных типов относятся к Delphi 32. Для 16-разрядной версии 1 эти величины имеют другие значения, например, тип Integer в версии 1 занимает 2 банта и имеет диапазон значении от -32 768 до +32 767.

    Метки — это имена операторов программы. Метки используются очень редко и только для того, чтобы программист смог указать компилятору, какой оператор программы должен выполнятся следующим. Метки, как и переменные, всегда объявляются в программе. Разделу объявлений меток предшествует зарезервированное слово label (метка).

    Подпрограммы — это специальным образом оформленные фрагменты программы. Замечательной особенностью подпрограмм является их значительная независимость от остального текста программы. Говорят, что свойства подпрограммы локализуются в ее теле. Это означает, что, если программист что-либо изменит в подпрограмме, ему, как правило, не понадобится в связи с этим изменять что-либо вне подпрограммы. Таким образом, подпрограммы являются средством структурирования программ, т. е. расчленения программ на ряд во многом независимых фрагментов. Структурирование неизбежно для крупных программных проектов, поэтому подпрограммы используются в Delphi-программах очень часто.

    В Object Pascal есть два сорта подпрограмм: процедуры и функции. Функция отличается от процедуры только тем, что ее идентификатор можно наряду с константами и переменными использовать в выражениях, т. к. функция имеет выходной результат определенного типа. Если, например, определена функция

    Function MyFunction: Integer;

    и переменная var

    X: Integer;

    то возможен такой оператор присваивания:

    Х:= 2*MyFunction-l;

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

    Procedure MyProcedure;

    :

    X:= 2*MyProcedure-l; // Ошибка!

    2.2 С++

    C++ — расширение языка С — был разработан сотрудником научно-исследовательского центра AT&T Bell Laboratories (Нью-Джерси, США) Бьерном Строустропом в 1979 году. С++ содержит в себе все, что есть в С. Но, кроме того, он поддерживает объектно ориентированное программирование (Object Oriented Programming, OOP). Изначально С++ был создан для того, чтобы облегчить разработку больших программ. Объектно ориентированное программирование это новый подход к созданию программ.

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

    Ключевым понятием C++ является класс. Класс — это тип, определяемый пользователем. Классы обеспечивают скрытие данных, гарантированную инициализацию данных, неявное преобразование типов для типов, определенных пользователем, динамическое задание типа, контролируемое пользователем управление памятью и механизмы перегрузки операций. C++ предоставляет гораздо лучшие, чем в C, средства выражения модульности программы и проверки типов. В языке есть также усовершенствования, не связанные непосредственно с классами, включающие в себя символические константы, inline- подстановку функций, параметры функции по умолчанию, перегруженные имена функций, операции управления свободной памятью и ссылочный тип. В C++ сохранены возможности языка C по работе с основными объектами аппаратного обеспечения (биты, байты, слова, адреса и т.п.). Это позволяет весьма эффективно реализовывать типы, определяемые пользователем.

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

    Программа на C++ обычно состоит из большого числа исходных файлов, каждый из которых содержит описания типов, функций, переменных и констант. Чтобы имя можно было использовать в разных исходных файлах для ссылки на один и тот же объект, оно должно быть описано как внешнее. Например:

    extern double sqrt(double);

    extern instream cin;

    Самый обычный способ обеспечить согласованность исходных файлов — это поместить такие описания в отдельные файлы, называемые заголовочными (или хэдер) файлами, а затем включить, то есть скопировать, эти заголовочные файлы во все файлы, где нужны эти описания. Например, если описание sqrt хранится в заголовочном файле для стандартных математических функций math.h, и вы хотите извлечь квадратный корень из 4, можно написать:

    #include

    //…

    x = sqrt(4);

    Поскольку обычные заголовочные файлы включаются во многие исходные файлы, они не содержат описаний, которые не должны повторяться. Например, тела функций даются только для inline-подставляемых функций (см. этот пункт) и инициализаторы даются только для констант (см. этот пункт). За исключением этих случаев, заголовочный файл является хранилищем информации о типах. Он обеспечивает интерфейс между отдельно компилируемыми частями программы.

    В команде включения include имя файла, заключенное в угловые скобки, например, относится к файлу с этим именем в стандартном каталоге (часто это /usr/include/CC); на файлы, находящиеся в каких-либо других местах ссылаются с помощью имен, заключенных в двойные кавычки.

    Например:

    #include «math1.h»

    #include «/usr/bs/math2.h»

    включит math1.h из текущего пользовательского каталога, а math2.h из каталога /usr/bs.

    Здесь приводится очень маленький законченный пример программы, в котором строка определяется в одном файле, а ее печать производится в другом. Файл header.h определяет необходимые типы:

    // header.h

    extern char* prog_name;

    extern void f();

    В файле main.c находится главная программа:

    // main.c

    #include «header.h»

    char* prog_name = «хороший, но полный»;

    main()

    {

    f();

    }

    а файл f.c печатает строку:

    // f.c

    #include

    #include «header.h»

    void f()

    {

    cout << prog_name << «\n»;

    }

    Скомпилировать и запустить программу вы можете например так:

    $ CC main.c f.c -o silly

    $ silly

    хороший, но полный

    $

    Язык, поддерживающий технологию локализации данных, абстракции данных и объектно-ориентированного программироввания, чтобы быть языком общего назначения должен также:

    Быть реализованным на традиционных ЭВМ;

    Выполняться в среде традиционных операционных систем;

    Быть конкурентоспособным с традиционными языками программирования по эффективности при выполнении программ;

    Подходить для большей части возможных приложений.

    Это означает, что должны быть включены средства для эффективных численных приложений (плавающая арифметика без накладных расходов, иначе Fortran окажется привлекательней). Должны быть включены возможности доступа к памяти (что необходимо для написания драйверов). Должны быть возможности обращения к функциям (call-обращения), согласованные с интерфейсами конкретных операционных систем. И, дополнительно, должны быть возможности обращения к функциям, написанным на других языках и наоборот, к функциям, написанным на объектно-ориентированных языках из других языков.

    В таблице 1 показаны достоинства и недостатки объектно-ориентированных языков.

    Таблица 1 – Достоинства и недостатки объектно-ориентированных языков

    Плюсы

    Минусы

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

    Необходимо понимать базовые концепции, такие как классы, наследование и динамическое связывание

    Данные и операции вместе образуют определенную сущность и они не «размазываются» по всей программе, как это нередко бывает в случае процедурного программирования

    Многоразовое использование требует от программиста познакомиться с большими библиотеками классов

    Локализация кода и данных улучшает наглядность и удобство сопровождения программного обеспечения

    Проектирование классов - задача куда более сложная, чем их использование

    Инкапсуляция информации защищает наиболее критичные данные от несанкционированного доступа.

    Очень трудно изучать классы, не имея возможности их «пощупать».

    Дает возможность создавать расширяемые системы

    Неэффективность в смысле распределения памяти

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

    использование объектов в качестве основных моделей позволяет пользователю моделировать сложные системы реального мира;

    гибкость объектно-ориентированных текстов выливается в быстрое реагирование на изменения требования пользователя;

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

    простота ПО делает его более гибким и снижает затраты на эксплуатацию.

    Наряду с этими явными преимуществами, использование объектно-ориентированных языков и сред программирования способствует пошаговой разработке ПО. Быстрое прототипирование интерфейсов позволяет тестировать ответы пользователя независимо от основного тела прикладной задачи. Значение такого подхода наиболее проявляется в проектах, прикладные задачи которых заданы нечетко или трудны для понимания.

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

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

    Например, в измерительной системе, разработанной в Combuston Engineering (Columbus, Ohio), группа датчиков отображается классом Sensor, задающим общие свойства всех датчиков. Подклассы задаются для каждого типа датчика системы, например, для оптических или инфракрасных. Они наследуют общие процедуры, применимые ко всем датчикам, и содержат дополнительные процедуры, применимые только к оптическим или инфракрасным датчикам.

    Объектно-ориентированный подход уменьшает концептуальный разрыв между реальным миром м компьютерной моделью. Он позволяет аналитикам и проектировщикам ясно понимать структуру системы. Как отмечает один из пользователей: «Я могу представить свои мысли текстом программы в таком виде, как я думаю.» Поэтому сегодня объектно-ориентированные системы используются для моделирования сложных физических систем на производстве, в телекоммуникациях, а также в военном и оборонном комплексах.

    Второе преимущество объектно-ориентированных систем обусловлено способом взаимосвязи объектов через сообщения. В примере, приведенном выше, общие сообщения типа «начать измерение», можно посылать всем датчикам системы; каждый из них отвечает специфическим образом. Если один из физических датчиков устарел, он заменяется. Одновременно меняется и соответствующий класс системы: для нового типа датчика вводится новый класс, содержащий процедуры, характерные для нового датчика. Новый класс наследует остальные необходимые ему процедуры от суперкласса. При получении новым датчиком общего сообщения он отвечает на него соответствующим образом. Тело всей системы и общие сообщения остаются без изменений.

    Гибкость объектно-ориентированных систем является неоспоримым преимуществом для пользователей в быстро меняющихся средах, например, в технологии программирования. Например, Computer Science Corporation использовал объектно-ориентированный язык Smalltalk для разработки продукта Design Generator. Компания отмечает, что благодаря использованию объектно-ориентированной технологии, разработчики программ имеют возможность быстро реагировать на новые течения рынка в условиях возрастающей конкуренции.

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

    В прошлом библиотеками подпрограмм пользовались разработчики ПО для решения стандартных задач типа математических вычислений. Объектно-ориентированные системы дают более широкий спектр многократного использования текстов программ. Один из первых пользователей, Cadre Technologies, подсчитал, что объем текстов программ для новой прикладной задачи уменьшается в отношении 5:1 в случае использования объектно-ориентированных программ.

    Библиотеки объектов также можно приобретать от независимых поставщиков. В настоящее время наиболее активно покупают такие библиотеки классов для создания пользовательских интерфейсов с пиктограммами. Разработка и написание таких интерфейсов с нуля — задача нелегкая. Компании типа Apple и Whitewater Group поставляют инструментарии для быстрого построения таких интерфейсов на основе нескольких базовых классов типа Window, Menu, ScrollBar и Icon. Пользователи могут использовать как эти классы, так и их подклассы, добавляющие в интерфейс, например, специальные пиктограммы.

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

    Известно, что затраты на сопровождение составляют до 80% стоимости жизненного цикла системы программирования. Разработчики больших сложных систем, часто сталкивающиеся с необходимостью их модификации, склоняются к использованию ООС как одному из способов снижения затрат на сопровождение и повышения надежности их продуктов. Например, Wild Leitz (Торонто, Канада) использовал объектно-ориентированных язык Objective-C для разработки географической информационной системы. Компания посчитала исходные тексты на этом языке более легкими в сопровождении, поскольку они короче, являются изолированными «вещами в себе», что снижает влияние изменения одного модуля на оставшуюся часть системы.

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

    повторная используемость;

    расширяемость;

    устойчивость к неправильным данным;

    системность.

    Правильный объектно-ориентированный стиль программирования обеспечивает наличие этих свойств. Поясним это на примере свойства системности.

    Программа обладает свойством системности, если она применима в качестве обобщенного оператора при «крупноблочном программировании». Крупноблочное программирование — это систематическое использование ранее разработанных крупных программных единиц (таких, как классы, подсистемы, или модули) при разработке новых программных систем.

    Ограничения современных объектно-ориентированных систем (ООС) в большинстве своем связаны с их несовершенством. Преодоление этих ограничений — это вызов продавцам ПО и возможность появления на рынке новых поставщиков. В этой главе обсуждаются проблемы развития объектно- ориентированных систем и дается временная шкала преодоления их слабостей.

    Основное препятствие для объектно-ориентированных систем в настоящее время — это сопротивление технического и управленческого персонала. Такое сопротивление естественно с точки зрения несовершенства многих объектно-ориентированных продуктов на сегодняшнем рынке. Несовершенство проявляется на примере ряда проблем, свойственных большинству новых технологий:

    ограниченный доступ на ряде стандартных платформ;

    необходимость интеграции с существующими системами и базами данных;

    нехватка ПО для программирования широкомасштабных систем.

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

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

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

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

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

    Эта механика нуждается в надлежащей языковой поддержке, чтобы быть эффективной. Для абстракции данных достаточно только языковой поддержки; для объектно-ориентированного программирования требуются средства общесистемного программного окружения. Чтобы обладать свойствами языка общего назначения, язык должен позволять эффективно использовать традиционные аппаратные средства.


    Рис. 3. Упрощённая схема организации многомодульной системы работы с геометрическими объектами

    Многомодульная структура системы обладает следующими преимуществами.

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

    Возможность повторного использования кода. Модуль ГеометрическиеОбъекты можно включить в любое приложение, если там есть и ДемонстрационныеОкна – можно включить и Визуализацию.

    Возможность поэтапной реализации программ. Так, первый релиз может включать ГеометрическиеОбъекты, ДемонстрационныеОкна и Визуализацию, во втором добавятся Вычисления и т.д..

    Возможность применения конвейерного метода производства, «распараллеливания» процесса разработки ПО.

    Есть несколько причин, не позволяющих считать С++ динамическим языком программирования.

    Статичность интерфейса и реализации класса. Под интерфейсом класса понимается совокупность его атрибутов и методов (задаётся описанием класса, обычно помещаемым в заголовочный файл), под реализацией – конкретный код, выполняемый при вызове этих методов. Как первое, так и второе должно быть определено ещё до начала компиляции, нельзя run-time добавить в класс переменную или метод, перекрыть уже существующий.

    Но при разработке новых модулей постоянно возникает необходимость менять уже существующие классы! Так, при разработке Вычислений, могут понадобиться функции, вычисляющие длину линии, её кривизну в некоторой точке, площадь фигуры. При разработке Визуализации может возникнуть необходимость в таких переменных, как цвет, толщина линии, для плоских фигур часто должна быть построена триангуляция (разбиение на треугольники). Причём вышеперечисленные функции существенно зависят от типа объекта: они должны быть отдельно написаны для прямоугольников, окружностей и произвольных геометрических объектов.

    Статический контроль типов.

    При разборе выражения p->f() компилятор «должен быть уверен», что объект, на который ссылается указатель p, действительно содержит метод f(). Даже шаблоны (template) не всегда помогают создать код, обрабатывающий разнотипные объекты: на этапе компиляции и сборки необходимо знать, какие из них требуется инсталлировать, какой применяется в каждом конкретном случае. Попробуйте-ка выполнить задание из листинга 1, не меняя классов и не используя конструкции if-then-else + dynamic_cast.

    /*

    Листинг 1. Статический контроль типов ограничивает возможности использования полиморфизма

    */

    class baseclass {};

    class A:public baseclass

    {

    public:

    A();

    // класс A содержит метод void f()

    virtual void f();

    };

    class B:public baseclass

    {

    public:

    B();

    // класс B не содержит метод void f()

    };

    class C:public baseclass {…};

    /*

    Требуется написать

    (не меняя вышеописанных классов и не используя if-then-else + dynamic_cast):

    */

    bool CallF(baseclass *p)

    {

    /*

    если определено p->f(), вызвать эту функцию и вернуть true,

    иначе – вернуть false

    */

    }

    C++ предлагает три способа реализовать функцию CallF. Первый (наиболее употребимый) – добавить в baseclass метод bool f(), в тех подклассах, где он имеет смысл – выполнять необходимые действия и возвращать true, в остальных – возвращать false. Второй – создать класс baseclass_f:public baseclass, унаследовать от него все классы, содержащие f(), и использовать dynamic_cast < baseclass_f *> . Третий – пресловутое if-then-else + dynamic_cast в CallF. Первый вариант приводит к засорению базового класса, к тому же baseclass может быть не доступен (например, содержаться в «закрытом» модуле). Второй требует перепроектировать всю систему объектов. А если затем потребуется написать CallG, CallH? Конечно, С++ поддерживает множественное наследование, но иерархия классов при таком подходе сильно усложнится, да и не дело менять её «туда-сюда». Недостатки третьего метода обсуждались неоднократно: функцию CallF придётся переписывать всякий раз, когда появляется новый класс, поддерживающий f().

    Невозможность run-time менять отдельные объекты классов. Казалось бы, если объекты принадлежат одному классу, то и вести себя они должны одинаково. Если существующий класс чем-либо не устраивает – «наследуйся» и меняй там что хочешь. Однако возможность динамически менять отдельные объекты класса часто оказывается очень полезной. Конечно, наследование является гибким и удобным способом изменения функциональности классов. Но после того как объект создан, изменить его методы, добавить новые методы и переменные уже нельзя. Для этого необходимо удалить существующий объект, а затем создать новый. При этом надо позаботиться об обновлении всех указателей на данный объект, сохранении его свойств. Кроме того, если каждый раз создавать новые классы, их количество может перейти все разумные границы.

    Заключение

    Наиболее распространенным объектно-ориентированным языком программирования безусловно является C++. Свободно распространяемые коммерческие системы программирования C++ существуют практически на любой платформе. Широко известна свободно распространяемая система программирования G++, которая дает возможность всем желающим разобрать достаточно хорошо и подробно прокомментированный исходный текст одного из образцовых компиляторов языка C++. Основные идеи объектно-ориентированного подхода опираются на следующие положения: программа представляет собой модель некоторого реального процесса, части реального мира; модель реального мира или его части может быть описана как совокупность взаимодействующих между собой объектов; объект описывается набором параметров, значения которых определяют состояние объекта, и набором операций (действий), которые может выполнять объект; взаимодействие между объектами осуществляется посылкой специальных сообщений от одного объекта к другому. Сообщение, полученное объектом, может потребовать выполнения определенных действий, например, изменения состояния объекта; Объекты, описанные одним и тем же набором параметров и способные выполнять один и тот же набор действий представляют собой класс однотипных объектов.

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

    Таким образом, объектно-ориентированный подход предполагает, что при разработке программы должны быть определены классы используемых в программе объектов и построены их описания, затем созданы экземпляры необходимых объектов и определено взаимодействие между ними.

    Классы объектов часто удобно строить так, чтобы они образовывали иерархическую структуру.

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

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

    Список использованной литературы

  1. Архангельский А. Программирование в Delphi для Windows. Версии 2006, 2007, Turbo Delphi + CD. –М.: Бином. Лаборатория знаний, 2006.

    Архангельский А. Язык C++ в С++Builder. Справочное и методическое пособие. – М.: Бином. Лаборатория знаний, 2008.

    Бакнелл Дж. Фундаментальные алгоритмы и структуры данных в Delphi. Библиотека программиста.–СПБ.: Питер, DiaSof, 2006.

    Галисеев Г.В. Компоненты в Delphi 7. Профессиональная работа.–М.: : Вильямс, 2006.

  2. Гамма Э. Приемы объектно-ориентированного проектирования. Паттерны проектирования. С.Петербург: Питер, 2006.
    Решите задачу на основе текста Законов Хаммурапи Совершенствование учета основных средств сельскохозяйственного предприятия Каковы сроки проведения инвентаризации основных средств?

    2014-05-28

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

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

Но реальность программирования гораздо сложнее.

Программирование сегодня

Это странно, но большинство действительно “глобальных” идей в компьютерном программировании были разработаны еще в 1950-х и 60-х годах. С тех пор появилось много новых языков, но ни один из них не реализует действительно нового подхода к логике и вычислениям.

Разработка новых языков программирования в течение последних нескольких десятилетий была основана на опыте разработчиков. Это означает, что появился код, который стало проще писать (движущая сила Ruby) и проще читать (Python), и делать определенные типы логических структур и способы решения проблем более интуитивными.

Некоторые языки были разработаны для решения конкретных проблем в программировании (например PHP и SASS), чтобы управлять определенными типами систем (), или для работы в определенной среде или на определенной платформе (Java и JavaScript). Некоторые языки были разработаны специально для того, чтобы помочь новичкам научиться программировать (классическими примерами являются BASIC и Scratch).

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

Относительно недавнее развитие включает в себя такое понятие, как SOA (Service Oriented Architecture- сервисо-ориентированная архитектура ) и MVC (Model-View-Controller), а также фреймворки, такие как , позволяющие программистам легко работать в рамках этих парадигм.

Список языков программирования

Пополняющийся список популярных языков программирования, разметок и протоколов. Ссылки на описание каждого из них:

Кодировка ASCII

  • Кодировка символов является одним из основных компьютерных и Интернет аспектов. ASCII – это первая, широко использованная система кодировки символов. Она была вытеснена UTF-8, но ASCII по-прежнему является основой для подавляющего большинства символов в Интернете и на сегодняшний день. Понимание этого очень важно для программистов. Читайте подробнее здесь (англ):

ASP / ASP.NET

  • ASP – это аббревиатура для Active Server Pages. Это первый скриптовый серверный язык для веб-сервера Microsoft IIS. ASP был заменен на серверный фреймворк с открытым исходным кодом – ASP.NET. Подробнее (англ):

AutoLISP

  • AutoLISP – это простой, легкий, интерпретируемый язык программирования, созданный специально для автоматизированного проектирования программного обеспечения. Читайте об этом (англ):

Awk

  • Awk является чрезвычайно мощным языком программирования для обработки текстов, позволяющим извлекать данные из файла или другого источника, и выводить их в любом формате, который вам нужен. Он является уже старым инструментом, но все еще так же полезен, как и раньше. Узнайте подробнее (англ): .

BASH

  • Bash – это наиболее часто используемый интерфейс командной строки в мире Unix. Это интерфейс на основе текста по умолчанию и для Linux и для Mac OS X. Подробнее (англ):

Common Lisp

  • Lisp является довольно уникальным языком программирования, возможно, самым древним языком и до сих пор продолжает использоваться. Это особенно важно в области искусственного интеллекта. Подробнее (англ):

C

  • Если мы включим сюда две производные этого языка, то смело можно будет сказать, что ни один язык не проиносил большей пользы и большего влияния, чем С. Это особенно важно для развития операционных систем и другого программного обеспечения. Многие компиляторы и интерпретаторы для других языков написаны на языке C. Подробнее (англ):

C++

  • Первоначально он назывался “C с классами”, C++, во многих отношениях, просто более продвинутый преемник C (хотя в целом ситуация сложнее). C++ был разработан, чтобы добавить высокий уровень парадигмы программирования C, сохраняя при этом возможности аппаратной манипуляции низкого уровня. Многие из этих дополнений добавлялись в C на протяжении многих лет, и языки больше похожи на два диалекта одного и того же языка. Подробнее (англ):

C#

  • Использовался в качестве основного языка для.NET программирования, похож на C++, является расширением языка программирования C, но с важным дополнением в виде объектно-ориентированных возможностей. Подробнее (англ):

CSS / CSS3

  • CSS или Cascading Style Sheets, также не является языком программирования, а языком стиля страницы – это язык, предоставляющий стиль и правила компоновки документам и приложениям. Является основным используемым в Интернете языком стиля. Подробнее:

Emacs Lisp

  • Emacs уже давно был известен как популярный и мощный текстовый редактор. Но добавление в него Emacs Lisp, превращает его в интегрированную среду разработки для почти любого языка программирования. Подробнее (англ): .

F#

  • F# – язык программирования общего назначения. Разработан, чтобы быть чрезвычайно эффективным. Будучи изначально только языком Microsoft, теперь является языком с открытым исходным кодом и используется на всех платформах. Подробнее (англ): .

FORTAN

  • Fortran впервые появился в 1957 году и до сих пор используется для решения некоторых из наиболее сложных проблем современной науки и техники. Подробнее (англ):

FORTH

  • Работа над Forth началась в 1968 году, и язык обычно используется на оборудовании, не имеющем традиционную операционную систему. Он также широко используется для управления станками. Подробнее (англ):

Haskell

  • Haskell является одним из наиболее популярных функциональных языков программирования, в дополнение к тому, что стал прототипом для дюжины других языков. Он широко используется в деловых и научных кругах и является отличным языком, с которого стоит начать знакомство с функциональным программированием. Подробнее (англ):

HTML

  • HTML не является языком программирования. Это язык разметки – язык добавления смысловых и стилистических аннотаций содержимому. Является основным языком для веб-контента. Знание его необходимо и обязательно всем веб-дизайнерам и веб-разработчикам, а также всем (писателям, редакторам), кто производит Интернет контент. Подробнее (англ): и

IDL

  • IDL, или Interactive Data Language, это язык программирования, используемый в основном для анализа и визуализации данных. Он до сих пор широко используется в аэрокосмической промышленности и астрономии. Подробнее (англ):

INTERCAL

  • INTERCAL является пародийным компьютерным языком, разработанным в начале 1970-х годов. Его создали как шутку, чтобы показать как технически сложны языки и трудно читаемы. Это реальный язык, который можно скачать, и с помощью которого можно даже что-то сделать. Подразумевается, что вы должны быть хорошо с ним знакомы для этого – но, опять же, не слишком хорошо, ведь и это не понравится самому INTERCAL. Подробнее (англ):

Java

  • Java является языком высокого уровня и предназначен для использования на Java Virtual Machine. Имеет очень мало внешних зависимостей, и был предназначен для работы на любой физической машине. Много используется в сетевой архитектуре, а также во встраиваемых устройствах и других вычислительных приложениях. Подробнее (англ): .

Javascript

  • JavaScript (не имеет фактического отношения к Java) это скриптовый язык, изначально разработанный для использования в веб-браузерах. Поэтому он имеет встроенную возможность работы с Document Object Model (DOM), отображением находящегося в памяти контента веб-страниц. Является основным языком программирования для front-end веб-разработки. В основном управляется событиями, и, благодаря Node.JS, в последнее время получил признание как серверный язык. Подробнее (англ): и . И здесь:

Ksh

  • Korn Shell (ksh) представляет собой интерфейс командной строки, используемый на Unix. Он был ранней оболочкой (shell), совместимый со стандартной оболочкой Bourne, но со всеми классными интерактивными функциями оболочки C. Подробнее (англ):

Linux Programming

  • Программирование Linux включает в себя все: начиная от скриптов оболочки до разработки приложений и разработки ядер. Подробнее (англ):

Logo

  • Logo один из самых ранних языков по обучению программированию, и до сих пор, вероятно, самый известный. Он известен своей черепахой, которую дети заставляют передвигаться компьютерными командами. Весело обучает программированию. Подробнее (англ):

ML

  • ML первоначально разработан как язык мета-программирования: язык для создания других языков. Но со временем он стал языком общего назначения, широко использовался в образовании, математике, естественных науках и даже финансах. Подробнее (англ): .

MPI

  • Message Passing Interface (Интерфейс передачи сообщений) представляет собой стандартный протокол для отправки сообщений между процессами или программами. Был реализован в ряде языков программирования, включая C, C++, Java и Python. Благодаря MPI стали возможны параллельные вычисления. Подробнее (англ):

Сетевое программирование с интернет-сокетами

Objective-C

  • Еще одна версия C, созданная в 1980-е годы для того, чтобы обеспечить полностью объектно-ориентированную реализацию C. Сейчас основное применение этого языка приходится на Mac OSX и операционные системы iOS. До недавнего времени iOS приложения должны были быть написаны на Objective-C, но сейчас можно писать также на Swift. Подробнее (англ):

OCaml

  • OCaml является объектно-ориентированным функциональным компьютерным языком. По ML традиции, он много используется для написания других языков программирования и фреймворков. Подробнее (англ): .

Разработка операционной системы

  • Эверестом среди работ по программированию считается разработка операционной системы. Если вы хотите доказать себе, что можете написать все, что угодно, то нет ничего лучше, чем написать свое собственное ядро операционной системы и связанные с ней инструменты.Но будьте осторожны: это путешествие по силам только храбрым и истинным программистам! Подробнее (англ): .

Perl

  • Очень полезный инструмент практически любого программиста. В качестве интерпретируемого языка его не нужно компилировать, иногда упоминается как “швейцарский армейский нож” скриптовых языков. Подробнее (англ):

PROLOG

  • Пролог – язык логического программирования, разработан для обработки естественного языка. Подробнее (англ):

Pure Data

  • Pure Data является уникальным визуальным языком программирования. Был создан специально для того, чтобы позволить пользователям создавать видео, аудио и графические работы. Подробнее (англ): .

Python

  • Python является языком программирования высокого уровня. Интерпретируемый (некомпилируемый) язык, также известный как “скриптовый язык”. В основном используется в качестве инструмента для выполнения специализированных задач программирования, таких как задачи по автоматизации и анализу данных. Имеет сильный набор инструментов для математических и научных вычислений, часто используется исследователями. Подробнее (англ):

Ruby on Rails

  • Ruby on Rails – это фреймворк для веб-разработки для языка программирования Ruby. Он обеспечивает архитектуру MVC (Model View Controller), уровень абстракции базы данных, а также множество инструментов для ускорения процесса программирования веб-приложений. Очень популярен для быстрой разработки веб-приложений. Подробнее (англ):

SAS

  • SAS является специализированным языком, предназначенным для анализа статистических данных. Широко используется в правительственных, научных кругах и бизнесе. Для людей, обладающим большим количеством данных, SAS является очевидным выбором. Подробнее (англ): .

Scala

  • Scala является относительно новым языком – более или менее новой и лучшей Java. Это отличный язык для Java-программистов, которые хотят быть более эффективными, или для людей, кто только начинают изучать программирование и хотят изучать мощный язык, который не будет ограничивать их в будущем. Подробнее (англ): .

Scheme

  • Scheme – старый язык, но до сих пор используется для обучения программированию и более сложных предметов в информатике. Основан главным образом на Lisp, и частично на ALGOL. Подробнее (англ): .

Scratch

  • Язык программирования Scratch был создан специально для обучения программированию детей в возрасте от 8 до 16 лет. Scratch – легкий, и с ним изучать основы логики программирования детям можно в увлекательной игровой форме. Подробнее (англ):

Simula

  • Simula – исторически важный язык, так как это был первый язык, внедривший понятия, ставшие основой для объектно-ориентированного программирования. Подробнее (англ): .

SMIL

  • SMIL (Synchronized Multimedia Integration Language) инструмент для тех людей, которые хотят создавать и распространять презентации. Особенно полезен, если вы хотите создавать презентации, которые должны время от времени обновляться. Подробнее (англ):

SQL

  • SQL (Structured Query Language) – язык, используемый для связи с Relational Database Management Systems (RDBMSes). SQL позволяет программисту создавать структуры данных, вставлять и редактировать данные, а также их запрашивать. Подробнее (англ):

Stata

  • Stata это среда разработки и язык программирования для решения серьезных статистических проблем. И хотя он создан довольно давно, но все еще широко используется. Если вы связаны со статистической работой, Stata – отличный инструмент. Подробнее (англ):

Swift

  • Swift является новыйм языком программирования, разработанным компанией Apple, для iOS, OS X, watchOS, tvOS и Linux. Это язык будущего для разработчиков программ и приложений для устройств Apple. Подробнее (англ):

S-PLUS

  • S-PLUS является коммерческой версией мощного языка программирования S, разработанного для выполнения статистического анализа. Проект GNU имеет свою собственную версию S, называемую R. Все необходимые ресурсы о S с акцентом на S-PLUS:

UNIX Programming

  • Широта программирования на Unix велика. Она охватывает диапазон от административных скриптов к коду на основе текста до разработки X Window. Подробнее (англ):

XML

  • XML хорошо структурированный язык для разметки, предназначен, как для чтения человеком, так и машиной. Подробнее (англ):

Урок подготовил: Акулов Иван

Если вы нашли опечатку - выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать .

Кроме использования комментариев для получения параллельной программы, часто идут на расширение существующих языков программирования. Вводятся дополнительные операторы и новые элементы описания переменных, позво­ляющие пользователю явно задавать параллельную структуру программы и в некоторых случаях управлять исполнением параллельной программы. Так язык High Performance Fortran (HPF), помимо традиционных операторов Фортрана и системы спецкомментариев, содержит новый оператор FORALL, введенный для описания параллельных циклов программы. Наиболее интересной чертой HPF представляется многоуровневое отображение массив - массив-шаблон - вирту­альный процессорный массив - физические процессоры, позволяющее макси­мально гибко отображать пользовательские данные на реальный компьютер.

Другим примером служит язык mpC, разработанный в Институте системного программирования РАН как расширение ANSI С. Основное назначение mpC - создание эффективных параллельных программ для неоднородных вычисли­тельных систем. Пользователь может задать топологию сети, распределение данных и вычислений и необходимые пересылки данных. Посылка сообщений организована с использованием интерфейса MPI.

DVM-система предназначена для создания переносимых и эффективных вы­числительных приложений на языках C-DVM и Fortran-DVM для параллельных компьютеров с различной архитектурой. Аббревиатура DVM соответствует двум понятиям: Distributed Virtual Memory и Distributed Virtual Machine. Первое отражает наличие единого адресного пространства. Второе отражает использо­вание виртуальных машин для двухступенчатой схемы отображения данных и вычислений на реальную параллельную машину. Модель программирования предполагает задание DVM-указаний с помощью спецкомментариев, а значит, один вариант программы для последовательного и параллельного исполнения. Поддерживаются три группы директив: директивы распределения данных, ди­рективы распределения вычислений и спецификации удаленных данных. Ком­пилятор переводит программу на язык Фортран или Си, используя для органи­зации межпроцессорного взаимодействия одну из существующих технологий параллельного программирования (MPI, PVM, Router). В систему DVM также входят библиотека поддержки LIB-DVM, DVM-отладчик, предсказатель вы­полнения DVM-программ, анализатор производительности DVM-программ. Система разработана в Институте прикладной математики им. М.В.Келдыша РАН.



Специальные языки программирования

Если нужно точнее отразить либо специфику архитектуры параллельных сис­тем, либо свойства какого-то класса задач некоторой предметной области, то используют специальные языки параллельного программирования. Для про­граммирования транспьютерных систем был создан язык Occam, для програм­мирования потоковых машин был спроектирован язык однократного присваи­вания Sisal. Очень интересной и оригинальной разработкой является деклара­тивный язык НОРМА, созданный под руководством И.Б.Задыхайло в Институ­те прикладной математики им. М.В.Келдыша РАН для описания решения вы­числительных задач сеточными методами. Высокий уровень абстракции языка позволяет описывать задачи в нотации, близкой к исходной постановке про­блемы математиком, что условно авторы языка называют программированием без программиста. Язык с однократным присваиванием, не содержит традици­онных конструкций языков программирования, фиксирующих порядок вычис­ления и тем самым скрывающих естественный параллелизм алгоритма.

Библиотеки и интерфейсы, поддерживающие взаимодейст­вие параллельных процессов

С появлением массивно-параллельных компьютеров широкое распространение получили библиотеки и интерфейсы, поддерживающие взаимодействие па­раллельных процессов. Типичным представителем данного направления являет­ся интерфейс Message Passing Interface (MPI), реализация которого есть прак­тически на каждой параллельной платформе, начиная от векторно-конвейерных супер-ЭВМ до кластеров и сетей персональных компьютеров. Программист сам явно определяет какие параллельные процессы приложения в каком месте про­граммы и с какими процессами должны либо обмениваться данными, либо син­хронизировать свою работу. Обычно адресные пространства параллельных процессов различны. В частности, такой идеологии следуют MPI и PVM. В других технологиях, например Shmem, допускается использование как локаль­ных (private) переменных, так и общих (shared) переменных, доступных всем процессам приложения, и реализуется схема работы над общей памятью с по­мощью операций типа Put/Get.

Несколько особняком стоит система Linda, добавляющая в любой последова­тельный язык лишь четыре дополнительные функции in, out, read и eval, что и позволяет создавать параллельные программы. К сожалению, простота зало­женной идеи оборачивается большими проблемами в реализации, что делает данную красивую технологию скорее объектом академического интереса, чем практическим инструментом.

Параллельные предметные библиотеки

Часто на практике прикладные программисты вообще не используют никаких явных параллельных конструкций, обращаясь в критических по времени счета фрагментах к подпрограммам и функциям параллельных предметных библио­тек. Весь параллелизм и вся оптимизация спрятаны в вызовах, а пользователю остается лишь написать внешнюю часть своей программы и грамотно восполь­зоваться стандартными блоками. Примерами подобных библиотек являются Lapack, ScaLapack, Cray Scientific Library, HP Mathematical Library, PETSc и многие другие.

Некоторые параллельные предметные библиотеки

BLAS и LAPACK - библиотеки, реализующие базовые операции линейной алгебры, такие как перемножение матриц, умножение матрицы на вектор и т.д.

ScaLAPACK включает подмножество процедур LAPACK, перера­ботанных для использования на MPP-компьютерах, включая: реше­ние систем линейных уравнений, обращение матриц, ортогональ­ные преобразования, поиск собственных значений и др.

FFTW, DFFTPack - быстрое преобразование Фурье.

PETSc - набор процедур и структур данных для параллельного ре­шения научных задач с моделями, описываемыми в виде диффе­ренциальных уравнений с частными производными.

Специализированные пакеты и программные комплексы

И, наконец, последнее направление, о котором стоит сказать, это использование специализированныю пакетов и программныю комплексов. Как правило, в этом случае пользователю вообще не приходится программировать. Основная зада­ча - это правильно указать все необходимые входные данные и правильно воспользоваться функциональностью пакета. Так, многие химики для выполне­ния квантово-химических расчетов на параллельных компьютерах пользуются пакетом GAMESS, не задумываясь о том, каким образом реализована парал­лельная обработка данных в самом пакете.

Для решения вычислительных задач сейчас все активнее используются графические процессоры, но до сих пор открыт вопрос: как писать эффективные программы под соответствующие конфигурации?

15.06.2011 Андрей Адинец

Для решения вычислительных задач сейчас все активнее используются графические процессоры, но до сих пор открыт вопрос: как писать эффективные программы под соответствующие конфигурации? Стандартное решение - связка CUDA или OpenCL - позволяет сравнительно быстро реализовать алгоритм, однако создать оптимизированную под конкретную конфигурацию версию с их помощью сложно. Требуются инструменты для программирования графических процессоров более высокого уровня, которые могут быть созданы, например, при помощи расширяемых языков.

Еще три года назад графические процессорные устройства (Graphical Processing Unit, GPU) рассматривались лишь как видеокарты для ПК, то сейчас отношение к ним изменилось - появились специальные серверные модели GPU, ориентированные на решение вычислительных задач, увеличилась производительность на вычислениях с двойной точностью, возникли системы рекордной производительности, занимающие высшие строки в Top500 . А как писать эффективные программы под такие машины? Стандартный ответ - связка CUDA или OpenCL для программирования GPU и MPI на уровне кластера. Эти инструменты доступны, активно поддерживаются производителями оборудования, под них уже написано много программ, однако есть и недостатки.

CUDA и OpenCL - расширения языка Си, они не сложны для изучения, хотя и являются достаточно низкуровневыми инструментами. С их помощью можно сравнительно быстро реализовать алгоритм для GPU, однако создать оптимизированную под конкретное приложение и конфигурацию версию оказывается значительно сложнее. Все оптимизации потребуется выполнять вручную, что приведет к увеличению размера кода и ухудшению его читаемости. И хотя программы, созданные при помощи OpenCL, будут переносимыми между широким спектром архитектур, производительность при таком переносе не сохранится. Требуются инструменты для программирования GPU более высокого уровня.

Создавать такие инструменты можно разными путями: вводить новый язык программирования; добавлять директивы в уже существующий язык, как делается в модели PGI Accelerator или CAPS HMPP; воспользоваться расширяемыми языками. Расширяемые языки - языки программирования, синтаксис и семантика которых не фиксированы, а могут быть изменены в зависимости от потребностей программиста. По сравнению с традиционными, расширяемые языки обладают рядом преимуществ: в них проще добавлять новые возможности; они открыты; изучение новых моделей программирования на основе таких языков проще, поскольку требуется изучить лишь сравнительно небольшие по объему расширения; с помощью таких языков легче выполнять тонкую настройку и оптимизацию программ.

Расширяемые языки

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

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

Оказывается, что языков, удовлетворяющих этим требованиям, сравнительно немного: Lisp, Nemerle , Seed7, xoc и Stratego. При этом xoc, который предназначен для расширения языка Си, использует отдельный язык Zeta для написания расширений, а Stratego - это язык предметной области для создания преобразователей исходного кода. Nemerle - расширяемый язык, использующий среду. Net.

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

В языке Nemerle для этого используется конструкция, например создает дерево, состоящее из объявления переменной i с начальным значением 0. Квазицитирование похоже на создание строковых объектов при строковых константах. На рис. 1 приведен пример квазицитирования. Конструкция интерполяции позволяет подставлять значения переменных в фиксированный шаблон внутри квазицитирования. В Nemerle для этого используются конструкции $(...), если требуется подставить список, например. Также в расширяемых языках присутствуют конструкции разбора дерева программы. В языке Nemerle для этого используется оператор match(...) { ... }, аналог switch из языка Си, в качестве веток которого используются конструкции квазицитирования. При этом интерполяция трактуется как объявление новых переменных, которые в случае успешного сопоставления получают значения соответствующих поддеревьев. Например, для оператора сопоставления match(e) {| => ... }, если e содержит дерево, в переменную a попадет, а в переменную b .

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

На рис. 2 приведен пример макроса с синтаксическим расширением, позволяющий объявить многомерный цикл с переменными и количеством итераций по каждому измерению, а на рис. 3 дан пример преобразования программы, которое осуществляет этот макрос. Заметим, что макрос, осуществляющий такое расширение, занимает менее 30 строк исходного кода и при этом включает несколько проверок на ошибки. При традиционном подходе реализация такого расширения потребовала бы значительно большего количества кода и, кроме того, потребовала бы изучения внутреннего устройства компилятора.

Исторически первым появился механизм макросов в Лиспе, программа в котором представляется как обычный список и не требует специальных конструкций для работы с деревом программы, поэтому именно в этом языке расширяемое программирование получило наибольшее распространение. Макросы в Nemerle аналогичны таковым в Лиспе. В системе xoc механизм расширений реализован через расширения грамматики и атрибуты дерева разбора. Любое расширение обязательно задает два атрибута: тип синтаксической конструкции и выражение на базовом языке, в которое она преобразуется.

Для расширяемых языков характерна реализация через макросы многих стандартных конструкций. В языке Nemerle все циклы и условные операторы, кроме match, реализованы через макросы, а в Лиспе макросами являются стандартные конструкции циклов и объявления функций.

Как использовать языки?

Для расширяемого языка программирования можно написать конструкции, позволяющие наиболее удобным способом программировать графические процессоры, что и было сделано в рамках проекта NUDA (Nemerle Unified Device Architecture), целью которого является создание расширений языка Nemerle для программирования GPU. В качестве интерфейса взаимодействия с GPU и целевого языка для представления программы используется OpenCL.

Для начала надо реализовать исполнение на GPU подмножества кода на языке Nemerle. При этом должны поддерживаться привычные операторы языка, такие как циклы и ветвления, а также работа с простыми типами данных, структурами и массивами. Код для GPU выносится в отдельные функции, или в ядра NUDA. Каждое ядро отмечается макросом nukernel, который по коду ядра генерирует код на OpenCL и метод-заглушку для вызова ядра на стороне хоста. Перед генерацией кода производится раскрытие всех макросов, за исключением макросов циклов и ветвления. Если внутри ядра требуется вызвать функцию, эта функция должна быть помечена макросом nucode, который сгенерирует для этой функции код на языке OpenCL. Вызов ядра осуществляется при помощи макроса nucall; помимо параметров ядра, ему передается еще и конфигурация решетки потоков, с которой оно запускается.

Чаще всего в качестве ядра для GPU используется тело цикла, поэтому хотелось бы сразу переносить цикл на GPU. В Nemerle это можно реализовать - соответствующий макрос в NUDA называется nuwork. В качестве обязательных параметров он принимает размер блока потоков и на основании текущего контекста и анализа кода тела цикла определяет набор переменных, которые необходимо передать ядру в качестве параметров. Тело ядра формируется из тела цикла, вычисления индексов цикла через глобальный номер потока, а также условия, позволяющего корректно исполнять цикл даже в том случае, когда глобальный размер сетки не делится на размер группы потоков. На место цикла подставляется вызов макроса nucall, осуществляющий вызов сгенерированного ядра.

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

На рис. 4 слева приведена обычная программа сложения массивов, а справа - аналогичная программа, но выполняющая вычисления на GPU. Получить GPU-программы из обычной достаточно просто - требуется лишь применить макросы к циклам и операциям выделения памяти, при этом объем кода практически не меняется. Программа, написанная с использованием NUDA, занимает менее 20 строк кода. Аналогичная программа, но на чистом языке Си и OpenCL занимает более 100 строк.

Помимо макросов, облегчающих работу с GPU, система расширений NUDA включает также аннотации для преобразования циклов. Аннотации, по сути, являются специальными макросами. Например, аннотация inline применяется к циклу с фиксированным числом итераций и выполняет его полную развертку. Аннотация dmine выполняет глубокую развертку цикла. “Глубокая развертка” означает, что создание нескольких копий тела цикла и перемешивание выполняются не только для самого преобразуемого цикла, но и для вложенных циклов, если они независимы.

Эффект

Для чего программисту нужно учить новый язык и осваивать новые библиотеки расширяемых языков? Основной ответ - продуктивность. Имея алгоритм из параллельных циклов, работающих с массивами и записанный на языке Nemerle, достаточно добавить несколько аннотаций, чтобы получить программу для GPU. При этом программа будет исполняться на любом устройстве с поддержкой OpenCL, включая графические процессоры nVidia и AMD, а также процессоры x86. Чтобы добиться того же с помощью только технологий OpenCL или CUDA, потребуется затратить значительно больше ресурсов, которые уйдут не только на написание исходного кода, но и на отладку взаимодействия между хостом и GPU.

Другая причина - производительность созданного кода. На CUDA или OpenCL преобразования циклов потребуется выполнять вручную, причем отдельно для каждой архитектуры. Это долгий и чреватый ошибками процесс, а полученный в результате код трудночитаем и неудобен для сопровождения. С NUDA эту работу можно делать при помощи аннотаций. Например для нескольких ядер можно оптимизироватьации операции свертки изображений или умножения матриц при помощи аннотаций inline и dmine. Без увеличения размера исходного кода удается добиться повышения производительности в два–пять раз. При этом, если бы те же самые преобразования выполнялись вручную, это привело бы к увеличению кода в разы, а иногда и на порядок, не говоря уже о затратах времени на отладку и подбор оптимальных параметров развертки. Например, универсальная аннотированная программа из семи строк в NUDA умножения транспонированной матрицы на матрицу с двойной точностью выполняется на nVidia Tesla C2050 лишь на 40% медленнее самой быстрой в настоящий момент реализации (CUBLAS 3.2). Аналогичная программа, написанная вручную, заняла бы 70 строк кода. Естественно, для стандартных задач можно один раз вручную написать код, чтобы повысить производительность, но для специфических задач снижение трудозатрат и повышение продуктивности будет очень кстати. Наконец, повышение продуктивности относится и к созданию самих расширений: создавать их при помощи расширяемых языков проще, чем с помощью традиционных инструментов. Вся система NUDA, несмотря на свою функциональность, занимает всего лишь 12 тыс. строк кода, не считая тестов. Это сравнительно немного, например, компилятор языка Nemerle (сборка 9025) занимает около 130 тыс. строк.

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

Андрей Адинец ([email protected]) - м.н.с. НИВЦ МГУ (Москва).



Эта статья о расширении и его важности для компьютерных систем. Вот, казалось бы, что такого особенного может быть в расширении программного файла? Но тем не менее надеемся, читатели смогут получить важную и интересную для себя информацию. Умение разбираться с расширениями сослужит неплохую службу, о чем будет написано ниже.

Какое расширение имеет C plus plus?

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

Расширение и его важность в программировании

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

Что вообще такое расширение имени файла?

Но давайте поговорим о расширениях имён файлов с точки зрения компьютерных наук. С его предназначением уже определились - оно нужно для идентификации формата или типа файла. Отсоединяется расширение от имени файла с помощью точки. До 95-го у "Виндовс" имелось ограничение на количество символов в расширении: их не могло быть больше трех. В современных системах такого ограничения нет. Даже более, в современных файловых системах могут быть файлы, у которых несколько типов расширения. Все они следуют через точку. К таким как cpp это, правда, не относится.

Таким подарком разработчиков часто пользуются мошенники. Свои вредоносные файлы, которые они пропихивают на компьютеры пользователей, злоумышленники часто маскируют под другие программы, прячут основное расширение файла (у вирусов и различных троянов оно отличается от обычных программ). Даже может быть такое, что все настоящие файлы прячутся или удаляются, и вместо них подсовываются совсем другие. И окажется, что cpp - это вовсе не cpp, а компьютерный вирус. Хорошей защитой от такого типа мошенников служит команда показа всех типов расширений. Включить эту функцию можно в «Панели управления», достаточно найти только и необходимый пункт. И тогда можно быть спокойным за свои файлы C plus plus, и уверенным в том, что не запустишь вместо них вредную программу. Хотя тут необходимо всегда смотреть на расширение исполняемых файлов.

Точность информации, указываемой в расширении

Иногда расширение неточно указывает на тип файла и не решает всех возможных проблем, которые могут возникнуть в процессе пользования различными программами. Так, расширение.txt, знакомое многим, не даёт информацию компьютеру о том, в какой кодировке файл. Поэтому часто при открытии текстовых файлов можно увидеть листы непонятных символов. Особенно печально видеть такое состояние документа, если он использовался для написания программного кода. В таких случаях следует менять кодировки файлов до тех пор, пока компьютер не сможет предоставить адекватный текст. Можно на основе неправильных символов попробовать вычислить необходимую кодировку, но нужно знать, какая кодировка относительно которой к чему приводит. Для вордовских файлов тоже используется одно и то же расширение, которое не даёт понять, с каким файлом человек имеет дело: с обычным типом или отформатированным. Также расширение не указывает, какая версия используется, что хорошо проявляется при попытках открыть версии ранних документов в более поздних средах обработки, как в случае с Microsoft Office.

Иные способы и возможности указать формат

Есть и другие возможности указать для файловой системы. Но они не являются распространёнными, и про них вы, скорее всего, никогда не слышали:

  • Сохранение информации о формате файла в самой операционной системе. Неудобства возникают при желании перейти на другой компьютер и поработать с этим же файлом.
  • Применение так называемого метода «магических чисел». Это когда в самом файле зашифровывается определённая последовательность байтов, которая указывает всю необходимую информацию для работы файла. Имеет определённый потенциал, но нужна кооперация производителей программного обеспечения.
  • Для некоторых Unix-систем разработана функция, которая оставляет специальные обозначения на начале файла, предназначенные для интерпретатора.