Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
L02.doc
Скачиваний:
4
Добавлен:
15.11.2019
Размер:
83.46 Кб
Скачать

12

Лекция 2

1.3.2. Легкость создания программ

Данный критерий оценки языков программирования связан с рассмотренной ранее читабельностью и определяется сходными характеристиками. Это объясняется тем, что в процессе созда­ния программы автор часто перечитывает написанные ранее части программы. Аналогично читабельности, легкость создания программ должна рассматриваться в контексте конкретной области применения языка. Нет смысла сравнивать легкость использования двух языков для решения некоторой задачи, если один из них был разра­ботан именно для этого, а другой – нет.

В следующих подразделах описаны факторы, влияющие на легкость ис­пользования языка.

1.3.2.1. Простота и ортогональность

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

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

1.3.2.2. Поддержка абстракции

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

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

В качестве примера абстракции данных можно рассмотреть двоичное дерево, храня­щее в своих узлах целочисленные данные. На языке FORTRAN 77 такое дерево обычно реализуется в виде трех параллельных целочисленных массивов, в которых два целых числа используются в качестве индексов для идентификации положения данных в дере­ве. На языках C++ и Java эти деревья можно реализовать, описав узел дерева в форме простого класса, содержащего два указателя и целое число. Такое описание является бо­лее естественным, поэтому написать программу, использующую двоичное дерево, на языке, поддерживающем такую абстракцию, легче, чем на языке FORTRAN 77. Это оз­начает, что следует выбирать язык, абстракции которого наиболее близки к рассматриваемой пред­метной области.

1.3.2.3. Выразительность

Выразительность языка может оцениваться различными показателями. В языке APL она означает наличие мощных операторов, позво­ляющих производить большое количество вычислений с помощью маленькой про­граммы. В более широком смысле выразительность позволяет производить вычисления более удобными и менее громоздкими способами. Например, в языке C запись count++ удобнее и короче записи count = count + 1. Аналогично, булевские операторы and и then в языке Ada помогают описать сокращенное вычисление булевских выражений. В языке Pascal циклы со счетчиком проще создавать с помощью оператора for, чем с помощью оператора while. Очевидно, что все перечисленные возможности облегчают использование языка.

1.3.3. Надежность

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

1.3.3.1. Проверка типов

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

Примером того, как отказ от проверки типов может привести к ошибкам в программе, служит использо­вание параметров подпрограмм в ранней версии языка C. В этом языке совпадение типов фактического и формального параметров при вы­зове функции не проверялось. В частности, переменная типа int могла использоваться в качестве параметра функции, ожидавшей формального параметра типа float. Ни компилятор, ни система поддержки выполнения программ не выявляли такое несоответствие. Это приводило к проблемам, источник которых было трудно определить.

В языке Pascal диапазон изменения индексов массива является частью типа перемен­ной, представляющей собой массив. Следовательно, проверка диапазона изменения ин­дексов является частью проверки типов, хотя она должна производиться во время вы­полнения программы. Поскольку в языке Pascal контролируется большинство типов, то в нем выполняется также проверка диапазона изменения индексов. Такая проверка весьма важна для обеспечения надежности программы, поскольку индексы, выходящие за пре­делы допустимого диапазона, часто создают проблемы, проявляющиеся намного позже того момента, когда действительно произошло нарушение. Аналогичная проверка диапа­зона индексов проводится также в языках Ada, Java, C#.

1.3.3.2. Обработка исключений

Возможность обработки исключительных ситуаций позволяет перехватывать ошибки и другие необычные ситуации во время выполнения программы, принимать соответствующие меры, а затем продолжать работу. Это значительно повышает надежность программ. Языки Ada, C++, Java, C# позволяют обрабатывать исключительные ситуации, однако в ряде широко используемых языков, таких как C или FORTRAN, эти возможности практически отсутст­вуют.

1.3.3.3. Совмещение имен

Совмещение имен – это наличие нескольких разных имен у одной и той же ячейки памяти. Существует мнение, что совмещение имен – опасная возможность языка программирования. Большинство языков программирования допускают не­которые виды совмещения имен. Например, в языке C как указатели, так и члены объединения, могут ссылаться на одну и ту же переменную. Некоторые разновидности со­вмещения имен могут запрещаться структурой языка.

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

1.3.3.4. Легкость чтения и использования

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

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

1.3.4. Стоимость

Суммарная стоимость языка программирования определяется как связанными с ним материальными затратами, так и объемами ресурсов, требуемых для его использования (времени, памяти компьютера и т.д.). Рассмотрим в этом плане некоторые факторы.

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

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

Стоимость создания программ на данном языке.

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

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

Затраты ресурсов на компиляцию программ.

Основным препятствием для использования языка Ada была высокая ресурсоемкость работы его компиляторов первого поколения. С появлением более совершенных компиляторов языка Ada острота этой проблемы была снижена.

Стоимость выполнения программы, написанной на данном языке.

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

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

Затраты на систему реа­лизации языка.

Одна из причин быстрой популярности языка Java – бесплатное распро­странение систем компиляции/интерпретации. Язык, система реализации которого либо слишком дорога, либо работает только на дорогостоящем аппаратном обеспечении, имеет меньше шансов получить широкое распространение.

Стоимость низкой надежности.

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

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

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

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]