Программные структуры


Содержание

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

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

Опыт применения методов структурного программирования при разработке, например, ряда сложных операционных систем показывает, что правильность логической структуры системы в этом случае легко поддается доказательству, а сама система допускает достаточно полное тестирование. Уменьшение трудностей отладки и тестирования программ приводит к увеличению производительности труда программистов, поскольку на тестирование программы тратится от трети до половины времени ее разработки. Производительность труда программиста обычно измеряется числом отлаженных операторов, которые он может написать за день. Приближенные оценки показывают, что применение методов структурного программирования позволяет увеличить это число в 5—6 раз. Также нужно сказать, что структурное программирование предполагает определенную организацию самого процесса программирования и определенную технологию проектирования программ, что также положительно влияет на производительность труда программистов.

Основы структурного программирования. Теоретическим фундаментом структурного программирования является теорема о структурировании, из которой следует, что алгоритм (программа) решения любой практически вычислимой задачи может быть представлен с использованием трех элементарных базисных управляющих структур: структуры следования (последовательности); структуры ветвления, структуры цикла, изображенных на рис. 6.5—6.7 соответственно, где Р — условие, S — оператор.

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

Структура ветвления представляет фактор принятия решения, включает проверку некоторого логического условия Р и, в зависимости от результатов этой проверки, выполнение оператора S1 либо оператора S2. В языках программирования (например, Pascal) реализуется оператором if Р then SI else S2 (см. рис. 6.6).

Структура цикла (цикла с предусловием) представляет фактор повторяемости вычислений, обеспечивает многократное повторение выполнения оператора S, пока выполняется (истинно) логическое

Рис. 6.5. Структура следования

Рис. 6.6. Структура ветвления

условие Р. В языках программирования (например, Pascal) реализуется оператором while Р do S (см. рис. 6.7).

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

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

Каждая из структур может рассматриваться как один функциональный блок с одним входом и одним выходом. Блоки S, SI, S2, входящие в состав базисных управляющих структур, сами могут быть одной из них, поэтому возможны вложенные конструкции. Однако, какова бы ни была степень и глубина «вложенности», важно, что любая конструкция в конечном итоге имеет один вход и один выход. Следовательно, любую сложную структуру можно рассматривать как «черный ящик» с одним входом и одним выходом. Таким образом, можно ввести преобразование любой структуры в функциональный блок. Тогда всякий алгоритм, составленный из стандартных структур, поддается последовательному преобразованию к единственному функциональному блоку, и эта последовательность преобразований может быть использована как средство понимания алгоритма и доказательства его правильности. Обратная последовательность преобразований может быть использована в процессе проектирования алгоритма с постепенным раскрытием единственного функционального блока в сложную структуру основных элементов.

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

Методика разработки программ. Распространены две методики (стратегии) разработки программ, относящиеся к структурному программированию: программирование «сверху вниз»; программирование «снизу вверх».

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

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

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

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

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

Программные структуры

Как во всяком языке программирования в тексте на языке shell могут быть комментарии. Для этого используется символ «#». Все, что находится в строке (в командном файле) левее этого символа, воспринимается интерпретатором как комментарий. Например,

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

Команда test проверяет выполнение некоторого условия. С использованием этой (встроенной) команды формируются операторы выбора и цикла языка shell.

Два возможных формата команды: или

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

На самом деле shell будет распознавать эту команду по открывающей скобке «[«, как слову(!), соответствующему команде «test». Уже этого достаточно, чтобы предупредить о распространенной ошибке начинающих: Между скобками и содержащимся в них условием обязательно должны быть пробелы.

Пробелы должны быть и между значениями и символом сравнения или операции (как, кстати, и в команде «expr»). Не путать с противоположным требованием для присваивания значений переменным.

В shell используются условия различных «типов».

УСЛОВИЯ ПРОВЕРКИ ФАЙЛОВ:

-f file файл «file» является обычным файлом;
-d file файл «file» — каталог;
-с file файл «file» — специальный файл;
-r file имеется разрешение на чтение файла «file»;
-w file имеется разрешение на запись в файл «file»;
-s file файл «file» не пустой.

Примеры. Вводя с клавиатуры командные строки в первом случае получим подтверждение (код завершения «0»), а во втором — опровержение (код завершения «1»). «specific» — имя существующего файла.

УСЛОВИЯ ПРОВЕРКИ СТРОК:

str1 = str2 строки «str1» и «str2» совпадают;
str1 != str2 строки «str1» и «str2» не совпадают;
-n str1 строка «str1» существует (непустая);
-z str1 строка «str1» не существует (пустая).

ВАЖНОЕ ЗАМЕЧАНИЕ. Команда «test» дает значение «истина» (т.е. код завершения «0») и просто если в скобках стоит непустое слово.

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

УСЛОВИЯ СРАВНЕНИЯ ЦЕЛЫХ ЧИСЕЛ:

x -eq y «x» равно «y»,
x -ne y «x» неравно «y»,
x -gt y «x» больше «y»,
x -ge y «x» больше или равно «y»,
x -lt y «x» меньше «y»,
x -le y «x» меньше или равно «y».

То есть в данном случае команда «test» воспринимает строки символов как целые (!) числа. Поэтому во всех остальных случаях «нулевому» значению соответствует пустая строка. В данном же случае, если надо обнулить переменную, скажем, «x», то это достигается присваиванием «x=0».

Реализуются с помощью типовых логических операций:

! (not) инвертирует значение кода завершения.
-o (or) соответствует логическому «ИЛИ».
-a (and) соответствует логическому «И».

ПРЕДУПРЕЖДЕНИЕ. Не забывайте о пробелах.

Примеры.

СОВЕТ. Не злоупотреблять сложными условиями.

5.2. Условный оператор «if»

В общем случае оператор «if» имеет структуру

Здесь «elif» сокращенный вариант от «else if» может быть использован наряду с полным, т.е. допускается вложение произвольного числа операторов «if» (как и других операторов). Разумеется «список» в каждом случае должен быть осмысленный и допустимый в данном контексте.

не являются обязательными (в данном случае для указания на необязательность конструкций использованы квадратные скобки — не путать с квадратными скобками команды «test»!).

Самая усеченная структура этого оператора

если выполнено условие (как правило это ком получен код завершения «0», то выполняется «список», иначе он пропускается.

Обратите внимание, что структура обязательно завершается служебным словом «fi». Число «fi», естественно, всегда должно соответствовать числу «if».

Пусть написан расчет «if-1» Тогда вызов расчета даст а даст

Возможно использовать в условии то свойство shell, что команды могут выдавать различный код завершения. Это напоминает приемы программирования на Си. Пусть расчет «if-2» будет тогда вызов даст а даст

Еще пример на вложенность

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

5.3. Оператор вызова («case») Оператор выбора «case» имеет структуру:

Здесь «case» «in» и «esac» — служебные слова. «Строка» (это может быть и один символ) сравнивается с «шаблоном». Затем выполняется «список команд» выбранной строки. Непривычным будет служебное слово «esac», но оно необходимо для завершения структуры.

Непривычно выглядят в конце строк выбора «;;», но написать здесь «;» было бы ошибкой. Для каждой альтернативы может быть выполнено несколько команд. Если эти команды будут записаны в одну строку, то символ «;» будет использоваться как разделитель команд.

Обычно последняя строка выбора имеет шаблон «*», что в структуре «case» означает «любое значение». Эта строка выбирается, если не произошло совпадение значения переменной (здесь $z) ни с одним из ранее записанных шаблонов, ограниченных скобкой «)». Значения просматриваются в порядке записи. При вызове «case-2 Hello» на экран будет выведено: А при вызове «case-2 HELLO» на экран будет выведено:

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

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

Напишем команду «case-4», которая добавляет информацию к файлу, указанного первым параметром (если параметр один), со стандартного входа, либо (если 2 параметра) из файла, указанного в качестве первого параметра:

«$1» (при «$#=1») — это имя файла, в который происходит добавление со стандартного входа.

«$1» и «$2» (при $#=2) — это имена файлов , из которого («$1») и в который («$2») добавлять.

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

5.4. Оператор цикла с перечислением («for»)

Оператор цикла «for» имеет структуру:

где «for» — служебное слово определяющее тип цикла, «do» и «done» — служебные слова, выделяющие тело цикла. Не забывайте про «done»! Фрагмент «in список значений» может отсутствовать.

Пусть команда «lsort» представлена командным файлом

В этом примере имя «i» играет роль параметра цикла. Это имя можно рассматривать как shell-переменную, которой последовательно присваиваются перечисленные значения (i=f1, i=f2, i=f3), и выполняется в цикле команда «procsort».

Часто используется форма «for i in *», означающая «для всех файлов текущего каталога».

Пусть «proc-sort» в свою очередь представляется командным файлом

т.е. последовательно сортируются указанные файлы, результаты сортировки выводятся на печать («/dev/lp») и направляются в файлы f1_sorted f2_sorted и f3_sorted

Можно сделать более универсальной команду «lsort», если не фиксировать перечень файлов в команде, а передавать произвольное их число параметрами.

Тогда головная программа будет следующей:

Здесь отсутствие после «i» служебного слова «in» с перечислением имен говорит о том , что список поступает через параметры команды. Результат предыдущего примера можно получить, набрав

Усложним ранее рассматривавшуюся задачу (под именем «case-2») определения холдинга фирмы. Теперь можно при вызове указывать произвольное количество фирм. При отсутствии в структуре оператора «for» фрагмента «in список значений», значения берутся из параметров вызывающей команды. При вызове «holding Hello HELLO ONE» на экране будет: Еще пример.

Следующий расчет иллюстрирует полезный, хотя и с долей трюкачества, способ повторения одних и тех же действий несколько раз. Переменная «i» принимает здесь пять значений: 1, 2, 3, 4, 5, но внутри цикла эта переменная отсутствует и поэтому ее значение никакой роли не играет и ни чего не меняет. С таким же успехом переменная «i» могла принимать значения, скажем ф о к у с , а в результате точно также было бы пять раз повторено одно и то же вычисление содержимого цикла без изменений.

Расчет «print-n» иллюстрирует еще одну полезную возможность в использовании цикла «for». Здесь, после «for i . «, отсутствуют «in . » и перечень имен, т.е. перечнем имен для «i» становится перечень параметров, а следовательно количество печатаемых экземпляров можно менять. Смысл не изменится, если первую строку расчета записать как поскольку значение «$*» — есть список значений параметров.

Отметим различие в специальных переменных «$*» и «$@», представляющих перечень параметров. Первый представляет параметры, как строку, а второй, как совокупность слов.

Пусть командный файл «cmp» имеет вид: При вызове на экран будет выведено

5.5. Оператор цикла с истинным условием («while»)

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

Оператор цикла «while» имеет структуру:

где «while» — служебное слово определяющее тип цикла с истинным условием. Список команд в теле цикла (между «do» и «done») повторяется до тех пор, пока сохраняется истинность условия (т.е. код завершения последней команды в теле цикла равен «0») или цикл не будет прерван изнутри специальными командами («break», «continue» или «exit»). При первом входе в цикл условие должно выполняться.

Обратим внимание на то, что переменной «n» вначале присваивается значение 0, а не пустая строка, так как команда «expr» работает с shell-переменными как с целыми числами, а не как со строками. т.е. при каждом выполнении значение «n» увеличивается на 1.

Как и вообще в жизни, можно реализовать то же самое и сложнее. Расчет «рr-br» приведен для иллюстрации бесконечного цикла и использования команды «break», которая обеспечивает прекращение цикла.

Команда «break [n]» позволяет выходить из цикла. Если «n» отсутствует, то это эквивалентно «break 1». «n» указывает число вложенных циклов, из которых надо выйти, например, «break 3» — выход из трех вложенных циклов.

В отличие от команды «break» команда «continue [n]» лишь прекращает выполнение текущего цикла и возвращает на НАЧАЛО цикла. Она также может быть с параметром. Например, «continue 2» означает выход на начало второго (если считать из глубины) вложенного цикла.

Команда «exit [n]» позволяет выйти вообще из процедуры с кодом возврата «0» или «n» (если параметр «n» указан). Эта команда может использоваться не только в циклах. Даже в линейной последовательности команд она может быть полезна при отладке, чтобы прекратит выполнение (текущего) расчета в заданной точке.

5.6. Оператор цикла с ложным условием («until»)

Оператор цикла «until» имеет структуру:

где «until» — служебное слово определяющее тип цикла с ложным условием. Список команд в теле цикла (между «do» и «done») повторяется до тех пор, пока сохраняется ложность условия или цикл не будет прерван изнутри специальными командами («break», «continue» или «exit»). При первом входе в цикл условие не должно выполняться.

Отличие от оператора «while» состоит в том, что условие цикла проверяется на ложность (на ненулевой код завершения последней команды тела цикла) проверяется ПОСЛЕ каждого (в том числе и первого!) выполнения команд тела цикла.

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

Здесь программа с бесконечным циклом ждет ввода слов (повторяя на экране фразу «some more»), пока не будет введено «5». После этого выдается «enough» и команда «break» прекращает выполнение цикла.

Другой пример («Ожидание полдня») иллюстрирует возможность использовать в условии вычисления.

Здесь каждые 30 секунд выполняется командная строка условия. Команда «date» выдает текущую дату и время. Команда «grep» получает эту информацию через конвейер и пытается совместить заданный шаблон «12:00:» с временем, выдаваемым командой «date». При несовпадении «grep» выдает код возврата «1», что соответствует значению «ложь», и цикл «выполняет ожидание» в течение 30 секунд, после чего повторяется выполнение условия. В полдень (возможно с несколькими секундами) произойдет сравнение, условие станет истинным, «grep» выдаст на экран соответствующую строку и работа цикла закончится.

Пустой оператор имеет формат

Ничего не делает. Возвращает значение «0». Например, в конструкции «while :» или ставить в начале командного файла, чтобы гарантировать, что файл не будет принят за выполняемый файл для «csh».

Функция позволяет подготовить список команд shell для последующего выполнения.

Описание функции имеет вид:

после чего обращение к функции происходит по имени. При выполнении функции не создается нового процесса. Она выполняется в среде соответствующего процесса. Аргументы функции становятся ее позиционными параметрами; имя функции — ее нулевой параметр. Прервать выполнение функции можно оператором «return [n]», где (необязательное) «n» — код возврата.

Пример. Вызов на выполнение файла «fun» содержащего описание и вызов функции «fn», выдаст на экран:

5.9. Обработка прерываний («trap»)

Бывает необходимо защитить выполнение программы от прерывания.

Наиболее часто приходится встречаться со следующими прерываниями, соответствующими сигналам:

выход из интерпретатора,
1 отбой (отключение удаленного абонента),
2 прерывание от ,
9 уничтожение (не перехватывается),
15 окончание выполнения.

Для защиты от прерываний существует команда «trap», имеющая формат:

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

Например, если перед прекращением по прерываниям выполнения какого то командного файла необходимо удалить файлы в «/tmp», то это может быть выполнено командой «trap»:

которая предшествует прочим командам файла. Здесь, после удаления файлов будет осуществлен выход «exit» из командного файла.

Команда «trap» позволяет и просто игнорировать прерывания, если «список команд» пустой. Так например, если команда «cmd» выполняется очень долго, а пользователь решил отключиться от системы, то для продолжения выполнения этой команды можно написать, запустив команду в фоновом режиме:

Программные структуры

РАЗДЕЛ II. ТЕХНОЛОГИЯ РАЗРАБОТКИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

Тема 5. Внутреннее проектирование программного изделия

Понятие модуля программы

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

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

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

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

Функция представляет собой внешнее описание действий, выполняемых модулем, без указания того, как эти действия производятся. Логика модуля определяет его внутренний алгоритм, т.е. то, как модуль выполняет функцию. Контекст описывает конкретное использование модуля. Функцию модуля можно рассматривать как совокупность логики модуля и функций всех подчиненных (вызываемых) модулей. Существует много способов проектирования, при применении которых программа разбивается на множество модулей, их сопряжений и отношений [12]. В результате использования этих методов достигается минимальная сложность структуры ПИ. Таким образом, первой целью данного этапа разработки является такое разделение программы на независимые модули, при котором каждый из них, с одной стороны, по возможности выполняет только одну функцию, т.е. обладает максимальной функциональной связностью, а с другой стороны имеет минимальные внешние связи по данным.

Связность модулей программы

Связность (связанность) модуля определяется как мера независимости его частей. Чем выше связность модуля, тем лучше результат проектирования. Для обозначения связности используется также понятие «сила связности модуля».
Ниже приведены типы связности модулей.

Вид связности Сила связности
По совпадению 0 (слабая связность)
Логическая 1
Временная 3
Процедурная 5
Коммуникативная 7
Последовательная 9
Функциональная 10 (сильная связность)

Модуль с видом связности «по совпадению» — это модуль, между элементами которого нет осмысленных связей. Такой модуль не выполняет никаких разумных функций. Единственный способ описания подобного модуля — описание его логики. Одна из причин, по которым такие модули могут возникнуть, это выполнение принципа модульности структуры программы, т.е. когда мы обнаруживаем одинаковые последовательности операторов в нескольких модулях и решаем их сгруппировать в отдельный модуль. Если эти последовательности операторов в своих модулях имеют различный смысл, то новый модуль обладает связностью «по совпадению». Модуль этого типа тесно связан с вызывающим его модулем. Если в модуле объединены операторы только по признаку их функционального подобия (например, все они предназначены для управления операциями обмена с внешними носителями или для проверки правильности данных), а для его настройки применяется алгоритм переключения, такой модуль имеет логическую связность, поскольку его части ничем не связаны, а имеют лишь небольшое сходство между собой. Главная проблема с модулями этого типа — это использование одного и того же сопряжения для выполнения многих функций. Это приводит к сложным сопряжениям и появлению непредсказуемых ошибок при изменении сопряжения ради одной из функций. Модуль, содержащий части, функционально не связанные, но необходимые в один и тот же момент обработки, имеет временную связность, или связность по классу. Самые распространенные примеры — «начальный» и «заключительный» модули. Основной недостаток таких модулей состоит в том, что обычно они не явно связаны с другими модулями программы, что делает программу непонятной и приводит к ошибкам при ее модификации. Процедурно-связанный модуль — это такой модуль, который последовательно выполняет набор функций, реализующих задач. Функции объединяются посредством процедур. Такая структура модуля может возникнуть при расчленении длинной программы на части в соответствии с передачами управления, но без определения какого-либо функционального базиса при выборе разделительных точек. Коммуникативно-связанный модуль — это модуль, обладающий процедурной связанностью и дополнительно тем, что все его функции связаны через используемые данные. Общая структура данных является основной его организацией как единого модуля. Недостатком подобной конструкции модуля являются сложность реализации функций и большая вероятность внесения ошибок при модификации. Модуль, имеющий последовательную связность, может быть разбит на последовательные части, выполняющие независимые функции, но совместно реализующие единственную функцию. Модуль с функциональной связностью не может быть разбит на два других модуля. Это такой модуль, который обеспечивает выполнение одной специфической функции. Выполняемая функция может быть представлена набором элементарных составляющих функций, но каждая из них не является самостоятельной с учетом общей выполняемой работы. Модуль с функциональной связностью обладает высшей степенью (силой) внутренней связности. Модули высшего уровня иерархической структуры ПИ должны иметь функциональную или последовательную связность. Для модулей обслуживания предпочтительнее коммуникативная связность. Если модули имеют процедурную, временную, логическую связность или связность по совпадению, это свидетельствует о недостаточно продуманном их планировании. Модификация уже существующей программы, когда модули разбиваются на части, часто приводит к этим типам связности.

Сцепление модулей программы

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

Вид сцепления Степень сцепления модуля
По кодам 9 (сильное сцепление)
По внешним ссылкам 7
По управлению 5
По общей области 4
По образцу 3
По данным 1
Независимое 0 (слабое сцепление)

Модуль сцеплен по внешним ссылкам, если у него есть доступ к данным в другом модуле через внешнюю точку входа. Таким путем осуществляется неявное управление функционированием другого модуля. Сцепление такого типа возникает при использовании Паскаля или ПЛ/1, когда внутренние процедуры оперируют с глобальными переменными. Модули имеют сцепление по управлению, если какой-либо из них управляет решениями внутри другого с помощью передачи флагов, переключателей и т.д., предназначенных для выполнения функций управления, т.е. один из модулей знает о функциях другого. Модули,сцепленные по кодам, по внешним ссылкам, по управлению, обладают наиболее тесной (худшей) степенью внешней связности, что отрицательно сказывается на их надежности, адаптируемости, сложности тестирования и пр. Модули сцеплены по общей области, если они разделяют одну и ту же глобальную структуру данных. Модули ПЛ/1, ссылающиеся на структуру, объявленную как EXTERNAL, сцеплены друг с другом по общей области. Модули Фортрана, ссылающиеся на данные в блоке COMMON, группы модулей, ссылающиеся на абсолютные адреса памяти (включая регистры), также служат примерами сцепления по общей области. Со сцеплением по общей области связан ряд проблем: невозможность управления доступом каждого модуля к данным; большая вероятность появления ошибок при модификации структуры данных; усложнение восприятия, корректировки программы из-за наличия глобальных данных. Модули сцеплены по образцу, если параметры содержат структуры данных. Недостатком такого сцепления является то, что оба модуля должны знать о внутренней структуре данных. Если программист, сопровождающий программу, модифицирует структуру данных в одном из модулей, он вынужден изменить структуру данных также и в другом. Поэтому вероятность появления ошибок, возникающих при кодировании и сопровождении программ, здесь больше. Модули сцеплены по данным, если они имеют общие единицы, которые передаются от одного к другому как параметры, представляющие собой простые элементы данных, т.е. вызывающий модуль «знает» только имя вызываемого модуля, а также типы и значения некоторых его переменных. Вызываемый модуль ничего «не знает» о вызывающем его модуле. Изменения в структуре данных в одном из модулей не влияют на другой. Кроме того, модули с этим типом сцепления не имеют общих областей данных или неявных параметров. Независимое сцепление возможно в том случае, если модули не вызывают друг друга или не обрабатывают одну и ту же информацию. Степень сцепления и силу связности модулей можно использовать для оценки существующего проекта и как руководящий принцип при проектировании ПИ. Высокая сила связности и слабое сцепление способствуют независимости модулей, поскольку они сводят к минимуму их взаимосвязи и взаимозависимость. В связи с этим, могут быть рекомендованы такие три критерия (правила) проектирования модулей:

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

Кроме внутренней (по виду) связности и внешней (по виду сцепления) связности степень независимости модуля определяется также еще целым рядом дополнительных факторов, к которым следует отнести:

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

Размеры модуля оказывают непосредственное влияние на независимость, читаемость программы и на сложность организации ее тестирования. Поэтому размеры модуля должны быть невелики; как правило, модуль должен содержать от 10 до 100 выполняемых операторов языка высокого уровня. Предсказуемый модуль — это модуль, работа которого не зависит от предыстории его использования. С целью уменьшения ошибок и повышения надежности ПИ необходимо проектировать такие предсказуемые модули, которые не сохраняют никаких данных о предыдущих вызовах. Всюду, где это можно, желательно организовывать модули и принятие решений в них таким образом, чтобы модули, непосредственно управляемые решением, вызывались модулем, содержащим такое решение. Это ведет к устранению передачи специальных параметров, представляющих решения, которые должны быть приняты, а также позволяет принимать влияющие на управление программой решения на высоком уровне программной иерархии. Объем данных, на которые модуль может ссылаться, должен быть сведен к минимуму. Проектировщик должен пытаться изолировать информацию о какой-либо структуре данных или записи в базе данных в отдельном модуле (или небольшом количестве модулей). Проблему общих данных не следует решать путем передачи одного огромного списка параметров во все модули. Следуя этим правилам, проектировщик минимизирует доступный для каждого модуля объем данных, сокращая при этом число ошибок и облегчая их выявление и устранение. Внутренняя процедура, или подпрограмма — это закрытая подпрограмма, физически содержащаяся в вызывающем ее модуле. Внутренних процедур следует избегать, так как их трудно тестировать и к ним нельзя обращаться из других модулей. Если возникнет необходимость в использовании внутренней процедуры, проектировщику предпочтительнее оформить ее как модуль. Таким образом, на основании изложенных выше соображений можно сформулировать следующие правила формирования структуры и взаимодействия модулей в ПИ: — структура ПИ и правила оформления описания каждого модуля должны быть унифицированы; — каждый модуль должен характеризоваться функциональной законченностью, автономностью и независимостью в оформлении от модулей, которые его используют и которые он вызывает; — применяются стандартные правила организации связей с другими модулями по управлению и передачи данных; -структура ПИ должна быть представлена в виде совокупности небольших (до 100 операторов) программных модулей, связанных иерархическим образом, что дает возможность полностью и относительно просто уяснить функцию и правила работы отдельных частей ПИ в целом; — должен отсутствовать эффект последействия очередного исполнения программного модуля на последующие исполнения. Созданный на этапе внутреннего проектирования проект проверяется автором внешних спецификаций и проектировщиком будущего проекта (разработчиком модулей) с целью обеспечения работоспособности, понятности, соответствия используемому языку программирования, совместимости с принципами организации модулей, полноты декомпозиции и минимизации доступа к данным.

Оформление структуры программного изделия

Program name
Раздел описаний
begin
Раздел описаний
end.

Рис. 2.12. Структура программы на языке Паскаль

Описания модулей в Си находятся, как правило, в отдельных файлах *.cpp, а описания взаимно используемых в них данных передаются с помощью так называемых включаемых файлов *.h, перечень которых приводится в начале модуля, например:

если это библиотечный модуль и

если это модуль пользователеля.

Особенности архитектуры Windows-программ

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

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

В связи с этим, практически каждая W-программа состоит из следующего ряда обязательных частей: 1. Функции WinMain, являющейся точкой входа в программу. 2. Создания и описания атрибутов класса окна. 3. Создания экземпляра окна данного класса. 4. Цикла обработки сообщений. 5. Оконной функции, обрабатывающей сообщения.

Например:
Program ProgName;
Uses WinProcs, WinTypes;
<описание всех процедур и функций, в том числе и всех оконных функций, которые объявляются экспортируемыми с помощью слова Export>
<Точка входа в программу>
Procedure WinMain;
Var
Window: HWnd; <ссылка на окно>
Message: TMsg ; <запись — сообщение>
WindowClasse: TwndClass ; <описание класса>
Begin
<определение копии программы>

<создание и регистрация класса окна>

<создание и отображение главного окна>

<цикл получения и обработки сообщений>

<завершение программы>
end;
Begin
WinMain
End.
Процедура WinMain — это точка входа в рассматриваемую программу, которая получает управление от ядра Windows. Каждая W-программа должна иметь такую процедуру, инициализирующие действия которой обычно заключаются в создании и регистрации класса окна, последующем создании и отображении окна на экране и активизации цикла работы с сообщениями. WinProcs — этот модуль представляет собой интерфейс BWP с функциями Windows API. WinTypes — модуль содержит описание всех типов данных, используемых Windows API. — Функция WindowProc — это специальная «оконная функция», обрабатывающая сообщения, присылаемые окну. Эта функция называется непосредственно ядром Windows. Функции, вызываемые Windows, называются косвенно-вызываемыми. Следует иметь в виду, что простое модульное программирование в среде Windows представляет собой достаточно сложную задачу. Это связано с тем, что, во-первых, программа должна иметь архитектуру, управляемую событиями (непривычную для традиционного программирования), а, во-вторых, ядро Windows насчитывает более 600 функций и 200 различных сообщений (о назначение и правилах применения которых программисту желательно знать). Среди программистов бытует мнение о том, что Windows — это рай для пользователя и ад для программистов. Одним из способов упростить программирование в среде этого типа ОС является использование объектно-ориентированных библиотек. Одной из таких библиотек является, например, ObjectWindows, которая была включена в состав Turbo Pascal for Windows еще в 1991 г.

Программирование модулей

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

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

Для того чтобы можно было считать модуль полностью специфицированным, должно быть определено его поведение при любых входных условиях. Важно отличать внешние спецификации модуля от другой документации, например от описания его логики, потому что изменение логики может никак не повлиять на вызывающие модули, а изменение внешних спецификаций обычно приводит к изменениям в вызывающих модулях. Внешние спецификации лучше хранить в самой программе в виде комментариев в начале текста программы модуля. После разработки внешних спецификаций модулей приступают к проектированию модуля и собственно программированию (кодированию) внутренней логики каждого модуля. Этот процесс должен быть тщательно спланирован, и состоять из следующих шагов. 1. Выбор языка программирования. Выбор языка программирования часто предопределен имеющимися у заказчика вычислительными ресурсами, принятыми организационными стандартами или подготовкой программистов. Выбор языка программирования обычно осуществляется на более ранних стадиях разработки ПИ. Однако если язык не определен, то программист выполняет выбор на этом шаге. Существенное влияние на выбор языка оказывают его возможности обеспечивать надежный процесс получения программ, наличие и специфические особенности компилятора и т.д. Выбранный язык программирования оказывает влияние и на разработку ПИ. 2. Выбор алгоритма и структуры данных. К настоящему времени разработано значительное количество алгоритмов и соответствующих структур данных, которые позволяют удовлетворить потребности проектировщиков. Поэтому следует использовать опыт предыдущих разработок, отчеты, опубликованные материалы, выбрать из имеющихся эквивалентных алгоритмов и структур данных необходимые. Если же поиск не приводит к желаемому результату, то алгоритм и структуры данных необходимо разработать. 3. Формирование структуры модуля в соответствии с полученным алгоритмом и требованиями принятого языка программирования. Так, например, в Паскале все программные элементы модуля можно разбить на две части: — программные элементы, предназначенные для использования другими программами или модулями, такие элементы называют видимыми вне модуля; — программные элементы, необходимые только для работы самого модуля, их называют невидимыми или скрытыми.

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

unit (имя модуля); <заголовок модуля>
interface
< описание видимых программных элементов модуля >
< описание скрытых программных элементов модуля >
begin
< операторы инициализации элементов модуля >
end.
Использование в модулях процедур и функций имеет свои особенности. Заголовок подпрограммы содержит все сведения, необходимые для ее вызова: имя, перечень и тип параметров, тип результата для функций, эта информация должна быть доступна для других программ и модулей. С другой стороны, текст подпрограммы, реализующий ее алгоритм, другими программами и модулями не может быть использован. Поэтому заголовок процедур и функций помещают в интерфейсную часть модуля, а текст — в часть реализации. Интерфейсная часть модуля содержит только видимые (доступные для других программ и модулей) заголовки процедур и функций (без служебного слова forward). Полный текст процедуры или функции помещают в часть реализации, причем заголовок может не содержать список формальных параметров. В том случае, если имена переменных в интерфейсной части модуля и в программе, использующей этот модуль, совпадают, обращение будет происходить к переменной, описанной в программе. Для обращения к переменной, описанной в модуле, необходимо применить составное имя, состоящее из имени модуля и имени переменной, разделенных точкой, например unit_M.var_K. Использование составных имен применяется не только к именам переменных, а ко всем именам, описанным в интерфейсной части модуля. Если в модуле имеется раздел инициализации, то операторы из этого раздела будут выполнены перед началом выполнения программы, в которой используется этот модуль. Рекурсивное использование модулей запрещено. 4. Детализация текста программы. В результате нескольких итераций осуществляется последовательная детализация логики модуля, начиная с достаточно высокого уровня абстракции и заканчивая готовым текстом программы. В зависимости от выбранного подхода к декомпозиции задачи и ее ПО на этом шаге используються и соответствующие методы программирования. 5. Окончательное оформление текста программы. Текст модуля проверяется еще раз. При этом вставляются дополнительные комментарии, поясняющие текст программы. 6. Проверка правильности программы. Вручную проверяется правильность модуля — правильность его внутренней логики. Такая проверка осуществляется людьми до выполнения программы вычислительной машиной. Проверка правильности основывается на различных способах чтения текста программы. Проверка может осуществляться как в форме статического чтения программы, так и в форме динамического чтения. Эти формы дополняют друг друга и должны использоваться совместно. 7. Компиляция модуля. Этот шаг отмечает переход проектирования к тестированию модуля. Работа над созданием модуля завершена. Компилятор, строя машинную программу, проводит контроль синтаксиса и частично семантики исходной программы. При проектировании логики модуля необходимо предусмотреть ряд контрольных мероприятий, обеспечивающих функционирование модуля, т.е. выполнить защитное программирование. Защитное программирование основано на важной предпосылке [12]: «. худшее, что может сделать модуль, — это принять неправильные входные данные и затем вернуть неверный, но правдоподобный результат». Поэтому проектировщик обязан до начала работы модуля предусмотреть контроль входных данных на соответствие их свойств атрибутам и диапазонам изменения, на полноту и осмысленность. Защитное программирование требует разумного подхода к его проведению, тщательного анализа необходимости и объема выполняемых проверок. Таким образом, модуль — это особым образом оформленная библиотека подпрограмм, которая представляет собой отдельно хранимую и независимо компилируемую программную единицу. Однако в отличие от программы модуль не может быть запущен на выполнение самостоятельно, он может только участвовать в построении программ и других модулей. Использование модулей позволяют создавать личные библиотеки процедур и функций и строить программы практически любого размера.

Стиль программирования

Сборка программы

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

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

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

Рис. 2.14. Последовательность сборки программы

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

Модульная структура программы

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

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

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

Спецификация программного модуля содержит:

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

— функциональную спецификацию модуля (описание семантики функций, выполняемых этим модулем по каждому из его входов).

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

Модульная структура программы представлена на (схема 1)

Схема 1.Модульная структура программы

ПРОГРАММИРОВАНИЕ

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

Проектирование сверху вниз.

Модульное программирование – это процесс разделения программы на логические части. Использование модулей приводит к снижению сложности. Модульную программу легче написать и протестировать.

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

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

Определим некоторые базовые понятия объектно-ориентированного программирования.

Объекты – некоторые элементы, из которых строится программное приложение.

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

Событие – это то, что происходит в реальном времени и может вызвать те или иные ответные действия.

Метод — способ, которым объект может реагировать на те или иные события. Это процедура, которая определена как часть класса и содержится в нем.

Методы объектов иметь любой из типов:

Класс – это категория объектов или методов, обладающих одинаковыми свойствами и поведением. При этом объект представляет собой просто экземпляр какого-либо класса.

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

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

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

В процессе построения приложения необходимо выбирать из палитры компоненты, на основе которых будет строиться проект. Еще до компиляции видно результаты своей работы. В этом смысле проектирование в Delphi мало чем отличается от проектирования в интерпретирующей среде, однако после выполнения компиляции получаем код, который исполняется в 10-20 раз быстрее, чем то же, самое, сделанное при помощи интерпретатора. Cреда Delphi включает в себя полный набор визуальных инструментов для скоростной разработки приложений (RAD — rapid application development), поддерживающей разработку пользовательского интерфейса.

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

Для разработки программы конструктора тестов использовались следующие компоненты Delphi7:

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

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

Image- предназначен для отображение на форме графических изображений по умолчанию выводит на поверхность формы изображения представленных в bmp формате. Для вывода изображений в jpg формате необходимо в дерективе uses подключить модуль JPEG. После размещения на форме компонента Image, он принимает вид выделенной прямоугольной области

MainMenu- не визуальный компонент delphi(место размещения которого на форме не имеет значения для пользователя так как он увидит не сам компонент, а меню, с генерированное им), предназначенный для вывода главного меню на форме

Memo- являются окном редактирования многострочного текста который можно загружать из файла либо сохранять введенную информацию в файл текстового формата

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

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

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

Timer- невизуальный компонент, который может размещаться в любом месте формы. Он имеет два свойства, позволяющие им управлять: Interval — интервал времени в миллисекундах иEnabled — доступность. Свойство Interval задает период срабатывания таймера. Через заданный интервал времени после предыдущего срабатывания, или после программной установки свойства Interval, или после запуска приложения, если значение Interval установлено во время проектирования, таймер срабатывает, вызывая событие OnTimer. В обработчике этого события записываются необходимые операции.

ТЕСТИРОВАНИЕ И ОТКЛАДКА

Тестирование – это динамический контроль программы, т.е. проверка правильности программы при ее выполнении на компьютере.

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

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

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

Учитывая разнообразие источников ошибок, при составлении плана тестирования классифицируют ошибки на два типа: 1 – синтаксические; 2 – семантические (смысловые).

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

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

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

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

procedure TForm3.Timer1Timer(Sender: TObject);

if TimeToAnswer = 0 then

TmrLabel.Caption := Format(‘Время на ответ: %b сек.’, [TimeToAnswer]);

После выявления ошибки и её исправления, программа стала правильно отсчитывать время данное пользователю для ответа на вопрос. После исправления код выглядит так:

procedure TForm3.Timer1Timer(Sender: TObject);

if TimeToAnswer = 0 then

TmrLabel.Caption := Format(‘Время на ответ: %d сек.’, [TimeToAnswer]);

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

procedure TForm1.N2Click(Sender: TObject);

if not InputQuery(‘Авторизация’, ‘Введите пароль: (1234)’, Password) then

if Password <> ‘1234’ then

if not InputQuery (Form2) then

Ошибка заключалась в том, что для вывода пароля использовалась процедура InputQuery, а нужно было использовать Assigned. Код после использования выглядит так:

procedure TForm1.N2Click(Sender: TObject);

if not InputQuery(‘Авторизация’, ‘Введите пароль: (1234)’, Password) then

if Password <> ‘1234’ then

if not Assigned(Form2) then

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

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

ДОКУМЕНТИРОВАНИЕ

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

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

АИС «Конструктор теста» предназначена для создания тестов, для очного итогового контроля качества усвоения теоретического материала, приобретенных знаний и практических навыков обучаемых в учебных заведениях по дисциплинам относящимся к информационным технологиям.

Главная форма (рис. 1) представляет собой меню где выбираешь между конструктором и тестом.

Рис. 1. Первоначальная форма

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

Рис. 2. Конструктор

При нажатии на вкладку тест открывается форма, где можно пройти тестирование по выбранному вами тестом (рис. 3).

ЗАКЛЮЧЕНИЕ

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

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

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

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

В процессе выполнения курсовой работы были осуществлены следующие задачи:

— закрепились и углубились теоретические знания;

— приобретены практические навыки при разработке программного продукта;

В результате проделанной работы были достигнуты все задачи, поставленные перед началом курсовой работы.

СПИСОК ЛИТЕРАТУРЫ

1. Вигерс И.К. Разработка требований к программному обеспечению: «Русская редакция», 2010, 576 с.

2. Бобровский С. Delphi 5: Учебный курс. — СПб.: Издательство «Питер», 2010. — 640 с.

3. Вонг, Уоллес. Основы программирования. М. 2011, 336 с.

4. П.П. Беленький. Учебное пособие по информатике — Ростов на дону «Феникс» 2012. – 448c.

5. Дантеманн Дж., Мишел Д., Тэйлор Д. Программирование в среде Delphi.- К.: НИПФ-‘Diasoft-Ltd.’,2011. — 608с.

6. Рубенкинг. Программирование в Delphi для «чайников». — К.: Диалектика, 1996. — 304с.

7. Дарахвелидзе П.Г., Марков Е.П. Delphi — среда визуального программирования.- СПб: BHV-Санкт-Петербург, 2011. — 352с

8. Сурков К.А., Сурков Д.А., Вальвачев А.Н. Программирование в среде DELPHI 2.0. — Минск: ООО «Попурри», 2012. — 640с.

9. Савицкая, Г.В. Анализ программной деятельности: Учебник / Г.В. Савицкая. — Минск: ООО «Новое знание», 2010;

10. Дж.Хьюз, Дж.Мичтом. Структурный подход к программированию. М.: Мир, 2011. — С. 29-71.

11. Диплом-Экспресс. Руководство пользователя. Версия 1.8. НТЦ «АРМ-Регистр», 2010, 41 с.

12. Коржинский С.Н Самоучитель работы на компьютере.- 2-е изд., перераб. и доп.- М.: ТК Велби, Изд-во Проспект, 2011, 370 с.

13. Леонтьев В.П. Новейшая энциклопедия ПК, 2011, 960 с.


14. Мазуркевич А., Еловой Д. РНР: настольная книга программиста, 2011, 480с.

15. Максимов Н.В. Архитектура ЭВМ и вычислительные системы, 2013, 512с.

16. Орлов С.А. Технология разработки программного обеспечения. – М.: Питер, 2013, 474 с.

17. Симонович С.В. Общая информатика. — М.: «Инфорко-Пресс», 2010, 428с.

18. Ташков П. Защита ПК на 100%: сбои, ошибки и вирусы, 2010, 288 с.

19. Шалин П.А. Энциклопедия Windows XP. — СПб.: «Питер», 2012, 688 с.

20. Культин Н.Б. — Основы программирования в Delphi 7, – СПб.: БХВ-Петербург, 2013

21. Ревич Ю. — Нестандартные приемы программирования на Delph. – СПб.: БХВ-Петербург, 2012

22. Сухарев — Основы Delphi. Профессиональный подход. – СПб.: Наука и Техника, 2011

23. Фленов — Библия Delphi. – СПб.: БХВ-Петербург, 2011

24. Ремизов Н. Delphi – М.: Питер, 2013.

25. Шпак Ю.А. — Delphi 7 на примерах. – К.: Издательство Юниор, 2012

26. Дарахвелидзе П., Марков Е. — Программирование в Delphi 7 (+ дискета). – СПб.: БХВ-Петербург, 2013

27. Кэнту — Delphi 7 для профессионалов. – СПб. Питер, 2012.

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

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

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

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

Рисунок — 10. — Пример схем программного комплекса: а) структурной; б) функциональной

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

Рисунок — 11. – Пример схем программной системы: а) структурной; б) функциональной

Более полное представление о проектируемом ПО с точки зрения взаимодействия его компонентов между собой и с внеш­ней средой дает функциональная схема. Функциональная схема (схема данных, ГОСТ 19.701-90) — схема взаимодействия компонентов ПО с описанием информационных потоков, состава данных в потоках и указанием используемых файлов и устройств. Для изображения функцио­нальных схем используют специальные обозначения, установленные стан­дартом. Основные обозначения схем данных приведены в таблице Г.1. Функциональные схемы более информативны, чем структурные. На рисунках 11.1б и 11.2б приведены функциональные схемы программных комплексов и систем. Все компоненты структурных и функциональных схем должны быть описаны. Следует тщательно прора­батывать спецификации межпрограммных интерфейсов, так как от качества их описания зависит количество самых дорогостоящих ошибок, к которым относятся ошибки, обнаруживаемые при комплексном тестировании.

Структурный подход к программированию изначально предлагал осуществлять декомпозицию программ методом пошаговой детализации. Результат — структурная схема программы, т.е. много­уровневая иерархическая схема взаимодействия подпрограмм по управле­нию. Минимально такая схема отображает два уровня иерархии (показы­вает общую структуру программы). Тот же метод позволяет получить структурные схемы с большим количеством уровней. Разбиение на модули выполняется эв­ристически, исходя из рекомендуемых размеров модулей (20-60 строк) и сложности структуры (2-3 вложенных управляющих конструкции). Для анализа технологичности иерархии модулей используют методики Константайна или Джексона.

На структурной карте Константайна отношения между модулями представляют в виде графа, вершинам которого соответствуют модули и общие области данных, а дугам — межмодульные вызовы и обращения к общим областям данных. Различают четыре типа вершин: модуль – подпрограмма; подсистема – программа; библиотека — совокупность подпрограмм, размещенных в отдельном модуле; область данных — специальным образом оформленная совокупность данных, к которой возможно обращение извне. При этом отдельные части программной системы могут вызываться последовательно, параллельно или как сопро­граммы.

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

Методика Джексона основана на поиске соответствий структур исходных данных и результатов. Однако при ее применении возможны ситуации, когда на ка­ких-то уровнях соответствия отсутствуют. Например, записи исходного фай­ла сортированы не в том порядке, в котором соответствующие строки долж­ны появляться в отчете. Такие ситуации были названы «столкновениями».

Методика Варнье-Орра базируется на том же положении, что и методика Джексона, но основными при построении про­граммы считаются структуры выходных данных и, если структуры входных данных не соответствуют структурам выходных, то их допускается менять. Таким образом, ликвидируется основная причина столкновений. Однако на практике не всегда существует возможность пересмотра структур входных данных: эти структуры уже могут быть строго заданы, на­пример, если данные получены при выполнении других программ, поэтому эту методику применяют реже.

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

1. вид хранимой информации каждого элемента данных — определяет тип соответствующего поля па­мяти;

2. связи элементов данных и вложенных структур, а также совокупность операций над ними — определя­ют структуры памяти, используемые для представления данных;

3. время хранения данных структуры («время жизни») — учитывается при размещении данных в статической или динамической па­мяти, а также во внешней памяти.

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

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

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

Дата добавления: 2020-02-28 ; просмотров: 278 ; ЗАКАЗАТЬ РАБОТУ

Программные структуры

УСЛОВИЯ ПРОВЕРКИ ФАЙЛОВ:

-f filename файл filename является обычным файлом
-d filename файл filename – каталог
-c filename файл filename – специальный файл
-r filename имеется разрешение на чтение файла filename
-w filename имеется разрешение на запись в файл filename
-s filename файл filename не пустой

Пример: document – имя существующего файла.

[ -f document ] ; echo $?
[ -d document ] ; echo $?

Вводя с клавиатуры командные строки, в первом случае получаем подтверждение (код завершения 0), во втором – опровержение (код завершения 1).

УСЛОВИЯ ПРОВЕРКИ СТРОК:

str1 = str2 строки str1 и str2 совпадают
str1 != str2 строки str1 и str2 не совпадают
-n str1 строка str1 существует (непустая)
-z str1 строка str1 не существует (пустая)
x=»who is who»; export x ; [ «who is who» = «$x» ] ; echo $?
x=»»; export x ; [ -n «$x» ] ; echo $?
[ privet ] ; echo $?

Команда test дает значение “истина” (код завершения 0), если в скобках стоит просто непустое слово. Кроме того, существуют два стандартных значения условия, которые можно использовать без скобок:

true ; echo $?
false ; echo $?

УСЛОВИЯ СРАВНЕНИЯ ЦЕЛЫХ ЧИСЕЛ:

x -eq y x равно y
x -ne y x неравно y
x -gt y x больше y
x -ge y x больше или равно y
x -lt y x меньше y
x -le y x меньше или равно y
x=321 ; export x ; [ 321 -eq «$x» ] ; echo $?
! (not) инвертирует значение кода завершения
-o (or) соответствует логическому ИЛИ
-a (and) соответствует логическому И
[ ! privet ] ; echo $?
x=privet ; export x ; [ «$x» -a -f document ] ; echo $?

Рекомендуется не злоупотреблять сложными условиями.

Условный оператор if

В общем случае оператор if имеет структуру:

if условие then список [elif условие then список] [else список] fi Конструкции, заключенные в квадратные скобки, не являются обязательными. Самая усеченная структура этого оператора имеет вид: if условие then список fi

# if-script: Оценка достижений

echo –n » Какую оценку получил на экзамене по ОС Linux? «

thenecho Не может быть !

then echo Тебеповезло !

then echo Молодец !

thenecho Этого следовало ожидать

Оператор выбора case

Оператор выбора case имеет структуру:

case строка in шаблон) список команд ;; шаблон) список команд ;; . . . esac cтрока (это может быть и один символ) сравнивается с шаблоном, а затем выполняется список команд выбранной строки

# case-script: Оценка достижений

echo –n » Какую оценку получил на экзамене по ОС Linux? «

5) echo Не может быть ! ;;

4) echo Тебе повезло ! ;;

2) echo Этого следовало ожидать ;;

Обычно последняя строка выбора имеет шаблон (*), что означает “любое значение”.

Еще один пример:

# case-menu: Реализация меню

echo «Назовите файл и через пробел наберите цифру,

соответствующую требуемой обработке:

2 – выдать на экран

3 – определить число строк «

readxy # x – имя файла, y – что сделать

Тогда головная программ может иметь вид:

Отсутствие перечисления имен указывает на то, что список поступает через параметры команды:

Часто используется форма «foriin *», означающая «для всех файлов текущего каталога».

Оператор цикла с истинным условием while

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

while условие do список команд done

Список команд в теле цикла повторяется до тех пор, пока сохраняется истинность условия ( код завершения последней команды в теле цикла равен 0) или цикл не будет прерван изнутри специальными командами:

break [n] позволяет выйти из цикла; n – число вложенных циклов, их которых надо выйти;
continue [n] прекращает выполнение текущего цикла и возвращает на начало цикла; n – номер цикла (из глубины), на начало которого нужно выйти;
exit [n] позволяет выйти из процедуры вообще с кодом возврата 0 или n, если n указано.

При первом входе в цикл условие должно выполняться.

# print-20: печать 50-ти экземпляров файла test

cтруктура while cтруктура while c break
n=0 while [ $n -lt 50 ] # пока n /dev/lp done n=0 while true do if [ $n -lt 50 ] # если n /dev/lp done

Оператор цикла с ложным условием until

Оператор цикла until имеет структуру:

until условие do список команд done

Список команд в теле цикла повторяется до тех пор, пока сохраняется ложность условия или цикл не будет прерван изнутри специальными командами (break, continue, exit). При первом входе в цикл условие не должно выполняться.

Отличие оператора until от оператора while состоит в том, что условие цикла проверяется на ложность (на ненулевой код завершения последней команды тела цикла) проверяется после каждого (в том числе и первого) выполнения команд тела цикла. Пример:

untildate | grep 12:00

каждые 30 секунд выполняется командная строка условия: команда date выдает текущую дату и время, команда grep, получив эту информацию через конвейер, сравнивает ее с заданным шаблоном «12:00». При несовпадении grep выдает код возврата «1» («ложь»), и выполняет переход в ожидание на 30 секунд, после чего повторяется проверка условия. В полдень условие станет истинным, работа цикла закончится выведением на экран соответствующей строки.

Пустой оператор ничего не делает, возвращает значение «0» и имеет формат

Пустой оператор используется, например в конструкции «while : » или ставится в начале командного файла, чтобы гарантировать, что файл не будет принят за выполняемый файл для оболочки csh.

Функции в shell

Функция позволяет подготовить список команд shell для последующего выполнения. Описание функции имеет вид:

Обращение к функции происходит по имени. При выполнении функции не создается нового процесса, она выполняется в среде существующего. Аргументы функции становятся ее позиционными параметрами, имя функции – ее нулевой параметр. Прервать выполнение функции можно оператором return [n], где необязательное n – код возврата.

В качестве примера рассмотрим выполнение файла ffnn, содержащего описание и вызов функции fn:

echo $$ # номер процесса
fn() # описание функции
<
echo xx=$xx
echo $# # число позиционных параметров
echo $0 : $$ $1 $2
xx=yy ; echo xx=$xx
return 5
>
xx=xx ; echo xx=$xx
fn a b
echo $? # значение, возвращенное последней командой
echo xx=$xx

На экране получим:

Вопрос

Работа с пакетами

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

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

Работать с RPM можно как и из командной строки, используя команду rpm, так и при помощи Х-программы GnoRPM , предоставляющей удобный графический интерфейс. Программа GnoRPM является приложением для рабочего стола GNOME.

Команду rpm можно вызвать в одном из десяти режимов: инсталляция, запрос, проверка, проверка подписи, деинсталляция, создание, перестройка базы данных, исправление прав доступа, исправление владельцев и групп, вывод используемого RC-файла. Р,рассмотрим подробно только три режима — удаление пакета из системы (деинсталляцию), установку в систему (инсталляцию) и создание.

Для всех рассматриваемых режимов работы программы грm действительны следующие опции:

-v вывод дополнительной информации;

-vv вывод дополнительной и отладочной информации;

-keep-temps нe удалять временные файлы из /tmp;

-quiet нe выводить ничего, кроме сообщении об ошибках;

-rcfile файл использовать указанный файл вместо /etc/ rpmгс;

-root каталог использовать файловую систему, смонтированную в указанном

каталоге для всех операций;

-dbpath путь использовать базу данных RPM, расположенную по указанному пути;

-help, —version стандартные GNU-опции, подсказка и номер версии.

Принятый формат имени пакета в RPM имеет вид:

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

Вопрос

WindowsNTявляется 32разрядной ОС с приоритетной многозадачностью и многопользовательским интерфейсом.

Особенности ОС WindowsNT:

· совместимость

· переносимость

· масштабируемость

· безопасность

· распределенная обработка

· надежность и отказоустойчивость

· возможности локализации

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

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

Структурно архитектуру WindowsNT можно разделить на две части:

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

2. Вторая часть работает в режиме пользователя .Эту часть составляют защищенные подсистемы ОС.

Типы пользовательских процессов:

• фиксированные процессы поддержки системы

Основными модулямиWindowsNT являются:

• уровеньаппаратныхабстракций HAL (Hardware Abstraction Layer),

• исполнительная система (Executive),

• защищенные подсистемы (Protected subsystems),

• подсистемы среды (Environment subsystems).

Уровень аппаратных абстракций(hardwareabstractionlayer, HAL), изолирующий ядро, драйверы и исполнительную систему Windows от специфики оборудования на данной аппаратной платформе.

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

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

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

Ядро управляет двумя типами объектов:

объекты диспетчеризации (dispatcherobjects)характеризуются сигнальным состоянием (signaled или nonsignaled) и управляют диспетчеризацией и синхронизацией системных операций. Эти объекты включают в свой состав события, мутанты, мутэксы (структура данных, обеспечивающая взаимоисключающую блокировку), семафоры, потоки управления и таймеры (events, mutants, mutexes, semaphores, threads, timers).

управляющие объекты (controlobjects)используются для операций управления ядра, но не воздействуют на диспетчеризацию или синхронизацию. Управляющие объекты включают в себя асинхронные вызовы процедур, прерывания, уведомления и состояния источника питания, процессы и профили (asynchronousprocedurecalls, interrupts, powernotifies, powerstatuses, processes, profiles).

Ядро выполняется полностью в привилегированном режиме и неперемещаемо (nonpageable) в памяти.

Программное обеспечение ядра не является выгружаемым (preemptible), для него не может производиться переключение контекста (contextswitch).

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

Исполнительная система(executive) Windows, содержащая базовые сервисы ОС, которые обеспечивают управление памятью, процессами и потоками, защиту, ввод-вывод и взаимодействие между процессами.

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

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

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

Вопрос 16: Модель безопасности WindowsNT

Модель безопасности Windows NT представлена монитором безопасности (Security Reference Monitor), а также двумя другими компонентами: процессом входа в систему (Logon Process) и безопасными защищенными подсистемами.

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

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

Распорядитель локальной безопасности (Local Security Authority):основа подсистемы безопасности Windows NT; генерирует маркеры доступа; управляет политикой локальной безопасности; обеспечивает интерактивный сервис аутентификации пользователя; управляет политикой контроля; регистрирует контрольные сообщения, сгенерированные монитором безопасности.

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

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

Структура программного обеспечения пк. Программное обеспечение

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

Рисунок 1. Классификация ПО

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

прикладное ПО, обеспечивающее выполнение необходимых работ на ПК: редактирование текстовых документов, создание рисунков или картинок, обработка информационных массивов и т.д.

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

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

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

операционные системы (эта программа загружается в ОЗУ при включении компьютера)

программы – оболочки (обеспечивают более удобный и наглядный способ общения с компьютером, чем с помощью командной строки DOS, например, Norton Commander)

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

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

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

К утилитам относятся:

диспетчеры файлов или файловые менеджеры

средства динамического сжатия данных (позволяют увеличить количество информации на диске за счет ее динамического сжатия)

средства просмотра и воспроизведения

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

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

средства обеспечения компьютерной безопасности (резервное копирование, антивирусное ПО).

Утилиты— программы, предназначенные для решения узкого круга вспомогательных задач.

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

Утилиты используются для:

Мониторинга показателей датчиков и производительности оборудования — мониторинг температур процессора, видеоадаптера; чтение S.M.A.R.T. жёстких дисков;

Управления параметрами оборудования — ограничение максимальной скорости вращения CD-привода; изменение скорости вращения вентиляторов.

Контроля показателей — проверка ссылочной целостности; правильности записи данных.

Расширения возможностей — форматирование и/или переразметка диска с сохранением данных, удаление без возможности восстановления.

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

Очистка диска — удаление временных файлов, ненужных файлов, чистка «корзины».

Разметка диска — деление диска на логические диски, которые могут иметь различные файловые системы и восприниматься операционной системой как несколько различных дисков.

Резервное копирование — создание резервных копий целых дисков и отдельных файлов, а также восстановление из этих копий.

Сжатие дисков — сжатие информации на дисках для увеличения вместимости жёстких дисков.

Утилиты работы с реестром

Утилиты мониторинга оборудования

Рисунок 2. Место СПО в многоуровневой структуре компьютера

Необходимо отметить, что часть утилит входит в состав операционной системы, а другая часть функционирует автономно. Большая часть общего (системного) ПО входит в состав ОС (рис.2). Часть общего ПО входит в состав самого компьютера (часть программ ОС и контролирующих тестов записана в ПЗУ или ППЗУ, установленных на системной плате). Часть общего ПО относится к автономными программам и поставляется отдельно.

Прикладное ПО. Прикладные программы могут использоваться автономно или в составе программных комплексов или пакетов. Прикладное ПО – программы, непосредственно обеспечивающие выполнение необходимых работ на ПК: редактирование текстовых документов, создание рисунков или картинок, создание электронных таблиц и т.д.Пакеты прикладных программ – это система программ, которые по сфере применения делятся на проблемно – ориентированные, пакеты общего назначения и интегрированные пакеты. Современные интегрированные пакеты содержат до пяти функциональных компонентов: тестовый и табличный процессор, СУБД, графический редактор, телекоммуникационные средства. К прикладному ПО, например, относятся:

Комплект офисных приложений MS OFFICE

Финансовые аналитические системы

Интегрированные пакеты делопроизводства

CAD – системы (системы автоматизированного проектирования)

Редакторы HTML или Web – редакторы

Браузеры – средства просмотра Web — страниц

Инструментальное ПО. Инструментальное ПО или системы программирования — это системы для автоматизации разработки новых программ на языке программирования. В самом общем случае для создания программы на выбранном языке программирования (языке системного программирования) нужно иметь следующие компоненты:1. Текстовый редактор для создания файла с исходным текстом программы. 2. Компилятор или интерпретатор. Исходный текст с помощью программы-компилятора переводится в промежуточный объектный код. Исходный текст большой программы состоит из нескольких модулей (файлов с исходными текстами). Каждый модуль компилируется в отдельный файл с объектным кодом, которые затем надо объединить в одно целое.3. Редактор связей или сборщик, который выполняет связывание объектных модулей и формирует на выходе работоспособное приложение – исполнимый код. Исполнимый код – это законченная программа, которую можно запустить на любом компьютере, где установлена операционная система, для которой эта программа создавалась. Как правило, итоговый файл имеет расширение .ЕХЕ или .СОМ.4. В последнее время получили распространение визуальный методы программирования (с помощью языков описания сценариев), ориентированные на создание Windows-приложений. Этот процесс автоматизирован в средах быстрого проектирования. При этом используются готовые визуальные компоненты, которые настраиваются с помощью специальных редакторов. Наиболее популярные редакторы (системы программирования программ с использованием визуальных средств) визуального проектирования:

Borland Delphi — предназначен для решения практически любых задачи прикладного программирования

Borland C++ Builder – это отличное средство для разработки DOS и Windows приложений

Microsoft Visual Basic – это популярный инструмент для создания Windows-программ

Microsoft Visual C++ — это средство позволяет разрабатывать любые приложения, выполняющиеся в среде ОС типа Microsoft Windows

Дайте определение операционной системе.

Какое программное обеспечение относят к системному?

Назовите служебное программное обеспечение.

Какое программное обеспечение относят к прикладному?

Каково назначение программного обеспечения?

Каковы основные классы программ? Приведите примеры программ в каждом классе по назначению.

Проектирование программного обеспечения

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

  • Анализ предметной области и создание ТЗ (взаимодействия с заказчиком)
  • Проектирование структуры программы
  • Кодирование (набор программного кода согласно проектной документации)
  • Тестирование и отладка
  • Внедрение программы
  • Сопровождение программы
  • Утилизация

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

UML — является графическим языком для визуализации, описания параметров, конструирования и документирования различных систем (программ в частности). Диаграммы создаются с помощью специальных CASE средств, например Rational Rose (http://www-01.ibm.com/software/rational/) и Enterprise Architect (http://www.sparxsystems.com.au/). На основе технологии UML строится единая информационная модель. Приведенные выше CASE средства способны генерировать код на различных объектно-ориентированных языках, а так же обладают очень полезной функцией реверсивного инжиниринга. (Реверсивный инжиниринг позволяет создать графическую модель из имеющегося программного кода и комментариев к нему.)

Рассмотрим типы диаграмм для визуализации модели (это must have, хотя типов гораздо больше):

  • Диаграмма вариантов использования (use case diagram)
  • Диаграмма классов (class diagram)
  • Диаграмма состояний (statechart diagram)
  • Диаграмма последовательности (sequence diagram)
  • Диаграмма кооперации (collaboration diagram)
  • Диаграмма компонентов (component diagram)
  • Диаграмма развертывания (deployment diagram)

Диаграмма вариантов использования (use case diagram)

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

Диаграмма классов (class diagram)

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

Диаграмма состояний (statechart diagram)

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

Диаграмма последовательности (sequence diagram)

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

Диаграмма кооперации (collaboration diagram)

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

Диаграмма компонентов (component diagram)

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

Диаграмма развертывания (deployment diagram)

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

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

Я убежден, что программист в первую очередь это кодер – он НЕ должен общаться с заказчиком, НЕ должен задумываться об архитектуре системы, не должен изобретать интерфейс к программе, он только должен кодировать – реализовывать алгоритмы, функционал, внешний вид, юзабилити, но не более…. Проектировщик же должен начиная от абстрактных диаграмм (описывающих предметную область) до диаграмм представляющих структуру данных, классов и процессов их взаимодействия, детально шаг за шагом все расписать. То есть сложность работы и зарплата проектировщика должна быть на порядок выше чем у программиста == кодера. Простите за крамолу.

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

О Г Л А В Л Е Н И Е

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

Функции текстовых редакторов в системах программирования


Компилятор как составная часть системы программирования

Компоновщик. Назначение и функции компоновщика

Загрузчики и отладчики. Функции загрузчика

Библиотеки подпрограмм как составная часть систем программирования

Лексический анализ «на лету». Система подсказок и справок

Разработка программ в архитектуре «клиент-сервер»

Разработка программ в трехуровневой архитектуре. Серверы приложений

Borland C++ Builder

Microsoft Visual Basic

Microsoft Visual С+-+

Системы программирования в составе ОС типа UNIX

Системы программирования проекта GNU

Разработка программного обеспечения для сети Интернет

Язык HTML. Программирование статических Web-страниц

Программирование динамических Web-страниц

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

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

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

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

Рис.1. Общая структура и этапы развития систем программирования

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

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

В качестве основных тенденций в развитии современных систем программиро­вания следует указать внедрение в них средств разработки на основе так называемых «языков четвертого поколения» — 4GL (four generation languages), — а также поддержка систем «быстрой разработки программного обеспечения» — RAD (rapid application development).

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

Описание программы, построенное на основе языков 4GL, транслируется затем в исходный текст и файл описания ресурсов интерфейса, представляющие со­бой обычный текст на соответствующем входном языке высокого уровня. С этим текстом уже может работать профессиональный программист-разработчик — он может корректировать и дополнять его необходимыми функциями. Дальнейший ход создания программного обеспечения идет уже традиционным путем, как это показано на рис. 1.

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

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

Принципы функционирования систем программирования

2.1.Функции текстовых редакторов в системах программирования

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

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

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

2.2.Компилятор как составная часть системы программирования

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

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

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

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

2.3.Компоновщик. Назначение и функции компоновщика

Компоновщик (или редактор связей) предназначен для связывания между собой объектных файлов, порождаемых компилятором, а также файлов библиотек входящих в состав системы программирования1.

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

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

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

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

2.4. Загрузчики и отладчики. Функции загрузчика

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

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

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

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

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

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

последовательное пошаговое выполнение результирующей программы hа основе шагов по машинным командам или по операторам входного языка;

выполнение результирующей программы до достижения ею одной из задан­ных точек останова (адресов останова);

выполнение результирующей программы до наступления некоторых заданных условий, связанных с данными и адресами, обрабатываемыми этой програм­мой;

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

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

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

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

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

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

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

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

2.5.Библиотеки подпрограмм как составная часть систем программирования

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

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

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

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

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

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

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

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

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

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

Широкий набор динамических библиотек поддерживается всеми современными ОС. Как правило, они содержат системные функции ОС и общедоступные функции программного интерфейса (API).

3.Дополнительные возможности систем программирования

3.1.Лексический анализ «на лету». Система подсказок и справок

Лексический анализ «на лету» — это функция текстового редактора в с. системы программирования. Она заключается в поиске и выделении лексем важного языка в тексте программы непосредственно в процессе ее создания разработчиком.

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

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

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

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

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

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

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

подсказку по работе с самой системой программирования;

справку о функциях библиотек, входящих в состав системы программирова­ния.

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

3.2.Разработка программ в архитектуре «клиент—сервер»

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

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

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

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

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

Кроме того, со временем на рынке СУБД стали доминировать несколько наиболее известных компаний-производителей. Они предлагали стандартизованные интерфейсы для доступа к создаваемым ими СУБД. На них, в свою очередь, стали ориентироваться и разработчики прикладных программ.

Такая ситуация оказала влияние и на структуру систем программирования. Многие из них стали предлагать средства, ориентированные на создание приложений в архитектуре «клиент—сервер». Как правило, эти средства поставляются в соста­ве системы программирования и поддерживают возможность работы с широким диапазоном известных серверов данных через один или несколько доступных интерфейсов обмена данными. Разработчик прикладной программы выбирает одно из доступных средств плюс возможный тип сервера (или несколько возможных типов), и тогда его задача сводится только к созданию клиентской части приложения, построенной на основе выбранного интерфейса.

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

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

Более подробно об организации приложений на основе архитектуры «клиент-сервер» можно узнать в [9, 35, 63].

3.3. Разработка программ в трехуровневой архитектуре. Серверы приложений

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

Недостатком архитектуры приложений типа «клиент—сервер» стал тот факт, что в клиентской части приложения совмещались как довольно сложные функции, связанные с обработкой получаемых от сервера данных, так и более простые функции организации интерфейса пользователя. Для выполнения этих функций к вычислительной системе должны предъявляться различные требования, и в том случае когда выполняется сложная обработка данных, эти требования со сторо­ны «клиентской» части приложения могут быть непомерно велики. Кроме того, обработка данных («бизнес-логика» приложения), как правило, изменяется незначительно по мере прохождения жизненного цикла, развития приложения и выхода его новых версий. В то же время интерфейсная часть может серьезно ви­доизменяться и в предельном случае подстраиваться под требования конкретно­го заказчика.

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

Поэтому дальнейшим развитием архитектуры «клиент—сервер» стало разделе­ние клиентской части в свою очередь еще на две составляющих: сервер приложе­ний (английские термины «application server» или «middleware»), реализующий обработку данных («бизнес-лотку» приложения), и «тонкий клиент» («thin client»), обеспечивающий интерфейс и доступ к результатам обработки (далее «тонкий клиент» будем называть просто «клиентом»). Серверная часть осталась без изменений, но теперь она получила название «сервер баз данных» («database server»), чтобы не путаться с сервером приложений.

Разделение клиентской части на две составляющих потребовало организации взаимодействия между этими составляющими. Причем это взаимодействие должно, с одной стороны, быть достаточно тесным, так как клиент должен выполнять отображение получаемых от сервера данных за время с разумной задержкой (же­лательно минимальной); а с другой стороны, он должен допускать обмен данными по протоколам, поддерживаемым глобальными сетями. Поэтому появилось некоторое число стандартов, ориентированных на организацию такого рода взаимодействия. Стали появляться новые интерфейсы обмена данными. Среди них можно выделить семейство стандартов COM/DCOM, предложенных фирмой Microsoft для ОС семейства Microsoft Windows], а также семейство стандартов CORBA (Common Object Request Broker Architecture), поддерживаемое широким кругом производителей и разработчиков программного) обеспечения для большого спектра различных ОС

Системы программирования в настоящее время ориентируются на поддержку средств разработки приложений в трехуровневой (трехзвенной) архитектуре. Средства поддержки тех или иных стандартов сейчас появляются в составе многих систем программирования. Принципы их. использования и распространения аналогичны принципам, применяемым для средств поддержки архитектуры типа «клиент—сервер». Следует заметить, что существуют системы программирования, ориентированные на разработку либо клиентской части, либо сервера приложений; и в то же время многие системы программиро­вания стремятся предоставить разработчикам средства для создания обеих частей в трехуровневой архитектуре. Серверная часть (сервер баз данных) в трех­уровневой архитектуре по-прежнему чаще всего является продуктом другого разработчика.

4.Примеры современных систем программирования

4.1. Системы программирования компании Borland/lnprise

Система программирования Turbo Pascal была создана компанией Borland на основе расширения языка Pascal, получившего название Borland Pascal.

Сам язык Pascal был предложен Н. Виртом в конце 70-х годов как хорошо структурированный учебный язык. Расширения, привнесенные в язык компанией Borland, преследовали две основные цели:

упрощение обработки в языке структур, представляющих наиболее распро­страненные типы данных — строки и файлы (например, в язык был внесен новый тип данных string);

реализация в языке основных возможностей объектно-ориентированных языков программирования.

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

Компания Borland построила и реализовала эффективный однопроходный компилятор с языка Borland Pascal. За счет этого в данной системе программирования удалось добиться относительно высокой скорости компиляции исходных программ. Для ускорения работы компоновщика компанией Borland был предложен собственный уникальный формат объектных файлов — модулей исходной программы — TPU (Turbo Pascal Unit). По этой причине модули, созданные в системе программирования Turbo Pascal, не могли быть использованы в других системах программирования. Также из них невозможно было создавать библиотеки, ориентированные на другие языки и системы программирования. Об­ратная задача — использование стандартных объектных файлов и библиотек в системе программирования Turbo Pascal — была решаема, но имела серьезные ограничения. В состав системы программирования Turbo Pascal, кроме компилятора с. языка Borland Pascal, входил также компилятор с языка ассемблера (а с появлением возможности разработки результирующих программ для среды Microsoft Windows — компилятор ресурсов). Среда программирования позволяла компоновать как единые исполняемые файлы, так и оверлейные программы для ОС типа MS-DOS.

Первоначально система программирования Turbo Pascal строилась на основе библиотеки RTL (run time library) языка Borland Pascal. Эта библиотека не предоставляла пользователю широкого набора функций — в основном она только реализовывала базовые математические функции и функции языка. Однако можно сказать об одной характерной черте данной библиотеки — она включала в свой состав объектный код менеджера памяти для управления распределени­ем динамической памяти («кучей» — heap — в терминах языка Pascal), который автоматически подключался к каждой результирующей программе, созданной с помощью данной системы программирования. Этот модуль получился доволъно удачным и нашел свое дальнейшее применение в других системах программирования данной компании-разработчика.

Несмотря на недостатки, система программирования Turbo Pascal получила широкое распространение и завоевала свое место на рынке. Основной причиной явилось то, что система впервые была построена в виде интегрированной среды. Данный факт предопределил ее широкое распространение, и, прежде всего, в университетской среде, где требовались простые и понятные в использовании средства разработки.

Система программирования Turbo Pascal получила широкое распространение и дальнейшее развитие. Компания Borland выпустила несколько ее реализации (наиболее распространенные из них — версии 5.5 и 7.0). Последние реализации данной системы программирования могли создавать результирующие программы, ориентированные на работу как в ОС типа MS-DOS, так и в среде типа Microsoft Windows. В них были реализованы все основные преимущества, предоставляемые интегрированной средой программирования, такие как лексический анализ программ «на лету» и встроенная контекстная подсказка.

По мере распространения системы программирования Turbo Pascal шла разработка библиотек подпрограмм и функций для нее. Были созданы такие библиотеки, как Turbo Professional (TP), Turbo Vision, Object Window Library (OWL) для среды MS-DOS и ObjectWindows для среды Microsoft Windows. Широкому распространению данных библиотек попрежнему мешал тот факт, что в системе программирования Turbo Pascal используется уникальный, нестандартный формат объектных файлов. Отсутствие стандарта языка Borland Pascal во многом сдерживало развитие этой системы программирования и не способствовало ее применению как профессионального средства разработки.

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

Система программирования Borland Delphi явилась логическим продолжением и дальнейшим развитием идей, заложенных компанией-разработчиком еще в системе программирования Turbo Pascal.

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

новый язык программирования — Object Pascal, явившийся серьезной переработкой прежней версии языка Borland Pascal;

компонентная модель среды разработки, в первую очередь ориентированная на технологию разработки RAD (rapid application development).

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

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

Система программирования Borland Delphi предназначена для создания результирующих программ, выполняющихся в среде ОС Windows различных типов.

Основу системы программирования Borland Delphi и ее компонентной модели составляет библиотека VCL (visual component library). В этой библиотеке реали­зованы в виде компонентов все основные органы управления и интерфейса ОС. Также в ее состав входят классы, обеспечивающие разработку приложений для архитектуры «клиент—сервер» и трехуровневой архитектуры. Разработчик имеет возможность не только использовать любые компоненты, входящие в состав библиотеки VCL, но также и разрабатывать свои собственные компоненты, основанные на любом из классов данной библиотеки. Эти новые компоненты становятся частью системы программирования и затем могут быть использованы другими разработчиками.

Для поддержки разработки результирующих программ для архитектуры «клиент—сервер» в состав Borland Delphi входит средство BDE (Borland database engine). Оно обеспечивает результирующим программам возможность доступа к широкому диапазону серверов БД посредством классов библиотеки VCL. Посредством BDE результирующая программа может взаимодействовать с серверами БД типа Microsoft SQL Server, Interbase, Sybase, Oracle и т. п. Система программирования Borland Delphi поддерживает также создание результирующих программ, выполняющихся в архитектуре «клиент—сервер», на базе других технологий, например ADO (ActiveX Data Objects)

Система программирования Borland Delphi выдержала несколько реализации. Последние реализации данной системы программирования (прежде всего, вер­сии 4 и 5) включают широкий набор средств для поддержки разработки ре­зультирующих программ в трехуровневой архитектуре приложений. Система программирования Borland Delphi позволяет разрабатывать как серверную, так и клиентскую часть приложения в данной архитектуре. Возможно использование как технологий COM/DCOM , так и технологии CORBA (но только при разработке клиентской части приложения).

В качестве недостатков данной системы программирования можно указать использование нестандартного формата объектных файлов (сохранился еще от системы Turbo Pascal, но в последней версии Borland Delphi 5 можно использовать стандартный формат), а также нестандартного формата для хранения ресурсов. пользовательского интерфейса. Кроме того, сам язык Object Pascal не является признанным стандартом. Этот факт несколько затрудняет использование Borland Delphi в масштабных проектах в качестве основного средства разработки.

Тем не менее система программирования Borland Delphi получила широкое распространение среди разработчиков в Российской Федерации.

BORLAND C++ BUILDER

Система программирования Borland C++ Builder объединила в себе идеи интегрированной среды разработки, реализованные компанией в системах программирования Turbo Pascal и Borland Delphi с возможностями языка программирования C++. История этой системы программирования начинается с интегрированной среды разработки Borland Turbo С.

Среда Turbo С представляла собой реализацию идей, заложенных компанией-разработчиком в системе программирования Turbo Pascal для языка программи­рования С. Компания Borland стремилась перенести удачную реализацию идей интегрированной среды разработки на новую основу. Компилятор Turbo С не был однопроходным, и потому время компиляции исходной программы превы­шало время компиляции аналогичной программы в Turbo Pascal. Кроме того, в системе программирования использовался стандартный компоновщик исполняемых файлов MS-DOS.

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

С развитием системы программирования на базе Turbo Pascal развивались и системы программирования на основе Turbo С

Современная реализация Borland C++ Builder ориентирована на разработку результирующих программ, выполняющихся под управлением ОС Microsoft Windows всех типов. Сама система программирования Borland C++ Builder, как и Borland Delphi, также функционирует под управлением ОС типа Microsoft Windows. Он полностью поддерживает стандарт языка С, что делает возможным создание с помощью данной системы программирования модулей и библиотек, используемых в других средствах разработки (чего очень сложно достигнуть с помощью Borland Delphi).

По возможностям, внешнему виду и технологиям система программирования Borland C++ Builder схожа с системой программирования Borland Delphi. В ее основу положены те же основные идеи и технологии. Структура классов языка C++ в системе программирования Borland C++ Builder построена в той же библиотеке VCL (visual control library), в которой строится структура классов Object Pascal в системе программирования Borland Delphi. Правда, разработчик, создающий программы на C++, может не пользоваться классами VCL и взять за основу любую другую библиотеку, чего нельзя сказать о разработчике, использующем Object Pascal — набор доступных библиотек для последнего языка сильно огра­ничен.

Успешное распространение систем программирования Turbo Pascal и Borland Delphi способствовало и внедрению на рынок системы программирования Borland C++ Builder от той же компании-разработчика. Эта система программирования занимает прочную позицию на рынке средств разработки для языка C++, где существует довольно жесткая конкуренция.

СИСТЕМЫ ПРОГРАММИРОВАНИЯ ФИРМЫ MICROSOFT

MICROSOFT VISUAL BASIC

. Система программирования Microsoft Visual Basic первоначально была ориентирована на интерпретацию исходного кода. Однако требования и условия на рынке средств разработки толкнули компанию-производителя на создание компилятора, вошедшего в состав данной системы программирования. При этом основные функции библиотеки языка были вынесены в отдельную, динамически подключаемую библиотеку VBRun, которая должна присутствовать в ОС для выполнения результирующих программ, созданных с помощью данной системы программирования. Различные версии системы программирования Microsoft Visual Basic ориентированы на различные версии данной библиотеки. Интерпретатор языка был сохранен и внедрен компанией-разработчиком в состав модулей другого программного продукта — Microsoft Office.

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

Последняя версия данной системы программирования — Microsoft Visual Ba­sic 6.0 — является одним из эффективных средств для создания результирующих программ, ориентированных на выполнение под управлением ОС типа Microsoft Windows. Эта система программирования ориентирована на технологию разработки RAD. Microsoft Visual Basic 6.0 содержит интегрированные средства визуальной работы с базами данных, поддерживающие проектирование и доступ к базам данных SQL Server, Oracle и т. п. К этим средствам относятся Visual Data­base Tools, ADO/OLE DB, Data Environment Designer, Report Designer и ряд других.

В данной системе программирования поддерживается также создание серверных Web-приложений, работающих с любым средством просмотра на базе новых Web-классов. В новой версии обеспечивается и отладка приложений для сервера IIS (Internet information server) производства компании Microsoft. В Microsoft Visual Basic 6.0 возможно создание интерактивных Web-страниц.

Microsoft Visual Basic 6.0 обеспечивает простое создание приложений, ориенти­рованных на данные. Visual Basic 6.0 позволяет создавать результирующие про­граммы, выполняемые в архитектуре «клиент—сервер», которые могут работать с любыми базами данных. Система программирования Microsoft Visual Basic ориентирована, прежде всего, на создание клиентской части приложений.

Теперь Visual Basic 6.0 поддерживает универсальный интерфейс доступа к данным Microsoft при помощи технологии ADO. Visual Basic 6.0 обеспечивает просмотр таблиц, изменение данных, создание запросов SQL из среды разработки для любой совместимой с ODBC или OLE DB базы данных. Так же как и в редакторе Visual Basic, синтаксис SQL выделяется цветом и незамедлительно проверяется на наличие ошибок. Это делает код SQL легче читаемым и менее подверженным случайным ошибкам.

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

Среда разработки обладает множеством новых возможностей, таких как выде­ление синтаксиса и автоматическое завершение ключевых слов. Система программирования Visual Basic интегрируется с семейством программных продуктов Microsoft BackOffice, которое обеспечивает среду для выполнения и создания сложных приложений масштаба предприятия для работы в локальных сетях или в Интернете. Использование новых интегрированных визуальных средств работы с данными облегчает выполнение рутинных задач по обеспече­нию доступа к ним; эти средства доступны прямо из среды разработки Visual Basic.

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

MICROSOFT VISUAL С+-+

Система программирования Microsoft Visual C++ представляет собой реализацию среды разработки для распространенного языка системного программиро­вания C++, выполненную компанией Microsoft. Эта система программирования в настоящее время построена в виде интегрированной среды разработки, включающей в себя все необходимые средства для разработки результирующих программ, ориентированных на выполнение под управлением ОС типа Microsoft Windows различных версий.

Основу системы программирования Microsoft Visual C++ составляет библиотека классов MFC (Microsoft foundation classes). В этой библиотеке реализованы в виде классов C++ все основные органы управления и интерфейса ОС. Также в ее состав входят классы, обеспечивающие разработку приложений для архи­тектуры «клиент—сервер» и трехуровневой архитектуры (в современных версиях библиотеки). Система программирования Microsoft Visual C++ позволяет разра­батывать любые приложения, выполняющиеся в среде ОС типа Microsoft Windows, в том числе серверные или клиентские результирующие программы, осуществляющие взаимодействие между собой по одной из указанных выше архитектур.

Классы библиотеки MFC ориентированы на использование технологий СОМ/ DC ОМ, а также построенной на их основе технологии ActiveX для организации взаимодействия между клиентской и серверной частью разрабатываемых приложений. На основе классов библиотеки пользователь может создавать свои собственные классы в языке C++, организовывать свои структуры данных.

В отличие от систем программирования компании Borland, система програм­мирования Microsoft Visual C++ ориентирована на использование стандартных средств хранения и обработки ресурсов интерфейса пользователя в ОС Windows. Это не удивительно, поскольку все версии ОС типа Windows разрабатываются самой компанией Microsoft. Microsoft Visual C++ обеспечивает все необходимые средства для создания профессиональных Windows-приложений. От версии к версии продукт становится проще в использовании, расширяются возможности применения, повышается производительность.

Система программирования Microsoft Visual C++ выдержала несколько реализации. В процессе выхода новых версий системы программирования было вы­пущено и несколько версий библиотеки MFC, на которой основана данная сис­тема.

Сама по себе библиотека MFC является, по мнению автора, довольно удачной реализацией широкого набора классов языка C++, ориентированного на разра­ботку результирующих программ, выполняющихся под управлением ОС типа Microsoft Windows. Это во многом обусловлено тем, что создатель библиотеки — компания Microsoft — одновременно является и создателем ОС типа Microsoft Windows, на которые ориентирован объектный код библиотеки. Библиотека мо­жет быть подключена к результирующей программе с помощью обычного ком­поновщика либо использоваться как динамическая библиотека, подключаемая к программе во время ее выполнения. Библиотека MFC достаточно широко рас­пространена. Ее возможно использовать не только в составе систем программи­рования производства компании Microsoft, но и в системах программирования других производителей.

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

Visual C++ 6.0 полностью интегрируется с Visual Studio 6.0 и другими средствами разработки, входящими в состав данного пакета. Эта интеграция, в частности, обеспечивает мгновенный доступ к MSDN (Microsoft developer network) library, содержащей документацию, примеры кода, статьи и другую информацию для разработчиков. Система программирования Visual C++ 6.0 широко известна.

Концепция .NET (произносится как «dot net» — «дот нет») — это не система программирования, а новейшая технология, предложенная фирмой Microsoft с целью унификации процесса разработки программного обеспечения с помощью различных систем программирования

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

Концепция —закономерный этап в развитии информационных технологий, приложений и сервисов, позволяющий разработчикам воспользо­ваться преимуществами сочетания открытых стандартов и архитектуры новой ОС производства компании Microsoft — Microsoft Windows 2000.

Большинство операционных систем, существовавших до настоящего времени, были неспособны предоставить необходимую корпоративным приложениям среду исполнения. Для них приходилось создавать специальные серверы приложений. ОС Microsoft Windows 2000 непосредственно предоставляет многие функций сервера приложений на уровне системных сервисов. Поэтому в концепции. NET управление приложениями концентрируется на более специфических для корпоративной среды и Интернет-служб задачах — управлении множеством объектов, приложений и серверов. Их решает сервер масштабирования приложений.

Концепция .NET содержит много новых идей и предложений. С точки зрения систем программирования основные идеи архитектуры. NET заключаются в том, что в ОС типа Windows 2000 организуется специальная виртуальная машина, исполняющая (интерпре­тирующая) команды некоторого промежуточного низкоуровневого языка. Любая программа, исполняемая в. NET, представляет собой набор команд данного про­межуточного языка. При этом сами команды этого языка интерпретируются независимо от архитектуры вычислительной системы и версии ОС, где они исполняются.

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

В первую очередь на поддержку концепции. NET будут, безусловно, ориентированы системы программирования производства компании Microsoft. Это коснется рассмотренных выше систем программирования Microsoft Visual C++ и Microsoft Visual Basic. Кроме того, компания предлагает новую систему программирования, построенную на базе нового языка С# (произносится «Сн-шарп»), которая специально ориентирована на поддержку концепции. NET. При успеш­ном развитии концепции и ее внедрении на рынок ОС и средств разработки на нее будут ориентироваться и системы программирования других разработчи­ков.

Поддержка концепции. NET в системах программирования не отменяет в них поддержку традиционного пути создания программного обеспечения. Возможность создания результирующих программ, исполняющихся под управлением. NET, идет в дополнение к возможности создания «традиционных» результи­рующих программ, построенных из машинных команд, ориентированных на определенную архитектуру целевой вычислительной системы. Однако далеко не все модули существующих в настоящий момент библиотек могут быть использованы в рамках данной концепции. Это в равной степени касается и распростра­ненных библиотек MFC и VBRun, используемых в системах программирования от Microsoft.

Концепция .NET ориентирована исключительно на новые ОС типа Windows 2000 производства компании Microsoft (а также на все последующие версии данного типа ОС). Она не переносима на ОС других типов, а также на архитектуру, не совместимую с традиционной архитектурой персональных компьютеров, построенных на базе процессоров Intel 80х86.

6. Системы программирования под ОС Linux и UNIX

6.1. Системы программирования в составе ОС типа UNIX

Вся история ОС UNIX тесно связана с историей языка программирования С. Фактически эти два программных продукта не смогли бы существовать друг без Друга. Язык программирования С появился как базовый язык программирования в ОС типа UNIX. Более того, сама операционная система представляла (и представля­ет) собой набор файлов, написанных на исходном языке программирования С. То есть практически любая ОС типа UNIX поставляется в виде исходного текста на языке С (кроме незначительной части ядра ОС, ориентированной на особен­ности архитектуры вычислительной системы, где она выполняется). Всякий раз при изменении основных параметров ОС происходит компиляция и компоновка ядра ОС заново, а при перезапуске ОС вновь созданное ядро активируется. Этот принцип характерен для всех ОС типа UNIX.

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

В ОС типа UNIX сложились основные особенности и характеристики второго этапа в развитии систем программирования. Именно здесь системы программирования стали представлять собой комплекс из библиотек языка, компилятора и компоновщика, выполняемых под управлением специальных командных файлов. Функции загрузчика в данном случае большей частью выполняются самой ОС. В ОС типа UNIX сложился, стал применяться и был стандартизован командный язык компиляции Makefile. Кроме того, именно в ОС этого типа были разработаны методы автоматизации разработки компиляторов, основанные на использовании программ LEX и YACC. К тому же практически все ОС типа UNIX обладают мощными командными процессорами, выполняющими команды пользователя в ОС. Возможности этих командных процессоров, по сути, соответствуют возможно­стям интерпретаторов языков программирования.

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

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

Системы программирования, построенные на базе интегрированных сред разработки, стали появляться и под ОС типа UNIX. Характерная черта их заключалась в том, что практически все они строились именно в графической среде на основе стандартного графического интерфейса. Так произошло, потому что в ОС типа UNIX (в отличие от ОС, ориентированных на персональные компьютеры) практически сразу в качестве стандарта «де-факто» установился стандарт графического интерфейса пользователя на основе среды Х Window Это по­зволило унифицировать библиотеки систем программирования (все они строятся на базе библиотеки Xlib), компиляторы и компоновщики ресурсов пользовательского интер4)ейса. Широкие возможности командных процессоров в ОС типа UNIX облегчают построение интегрированной среды в системах программирования. Поэтому сейчас существует широкий выбор таких сред от многих производителей (при наличии хотя бы небольшого опыта работы в ОС разработчик имеет возможность сам построить интегрированную среду программирования под управлением ОС).

Системы программирования проекта GNU

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

GNU — это название полной UNIX-совместимой программной системы, которая разрабатывается и безвозмездно предоставляется всем желающим ее использовать в рамках проекта. Система GNU способна исполнять UNIX-программы, но не идентична ОС типа UNIX. Улучшения основаны на имеющемся опыте работы с другими операционными системами. В качестве языка системного програм­мирования в системе доступны как С, так и Lisp. Кроме этого, поддерживаются коммуникационные протоколы сети Интернет.

Безусловно, по самой своей сути проект предполагает наличие в своем составе систем программирования. В противном случае распространение исходных кодов программ в рамках проекта будет просто бессмысленным. Очевидно, базовой системой программирования в проекте GNU стала система программирования на языке С. Хотя GNU и не UNIX, но проект перенял многие положительные черты ОС этого типа, в том числе — создание и распространение ядра ОС на основе языка С. Другим фактором, обусловившим создание системы программирования языка С в рамках проекта GNU, стало то, что большинство профессионалов-энтузиастов, основавших проект, использовали именно этот язык про­граммирования.

Со временем система программирования GNU С преобразовалась в более развитую систему программирования GNU C++, поскольку именно язык C++ получил широкое распространение в среде профессионалов. Затем в рамках проекта стали доступны и системы программирования на основе многих других языков программирования, в частности известного языка Pascal.

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

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

Положительной чертой проекта можно считать так же тот факт, что многие системы программирования, созданные в рамках проекта, оказались совместимыми и с ОС типа UNIX, которые формально не входят в проект GNU. Та же система программирования GNU C++, созданная в рамках проекта GNU, с успехом используется под многими версиями ОС типа UNIX.

Разработка программного обеспечения для сети Интернет

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

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

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

Во многих случаях при использовании исполнения программ в глобальной сети применяется именно такая схема.

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

7.1.Язык HTML. Программирование статических Web-страниц

Язык HTML (hypertext markup language, язык разметки гипертекста) во многом определил развитие и широкое распространение сети Интернет по всему миру. Сам по себе язык достаточно прост, а для овладения им нужны только самые примитивные знания в области программирования.

Язык позволяет описывать структурированный текст (гипертекст), содержащий ссылки и взаимосвязи фрагментов; графические элементы (изображения), которые могут быть связаны как с текстовой информацией, так и между собой; а также простейшие элементы графического интерфейса пользователя (кнопки, списки, поля редактирования). На основе описания, построенного в текстовом виде на HTML, эти элементы могут располагаться на экране, им могут присваиваться различные атрибуты, определяющие используемые ресурсы интерфейса поль­зователя (такие, как цвет, шрифты, размер и т. п.). В результате получается гра­фический образ — Web-страница (от «web» — «паутина» — слова, входящего в состав аббревиатуры WWW — World Wide Web — Всемирная паутина). Она в принципе может содержать различные мультимедийные элементы, включая графику, видео и анимацию.

Широкому распространению HTML послужил принцип, на основе которого этот язык стал использоваться в глобальной сети. Суть его достаточно проста: Интернет-сервер создает текст на языке HTML и передает его в виде текстового файла на клиентскую сторону сети по специальному протоколу обмена данными HTTP (hypertext transfer protocol, протокол передачи гипертекста). Клиент, получая исходный текст на языке HTML, интерпретирует его и в соответствии с результатом интерпретации строит соответствующие интерфейсные формы и изображения на экране клиентского компьютера.

Грамматика HTML проста (она относится к регулярным грамматикам), а потому не составляет сложности построить соответствующий интерпретатор. Такими интерпретаторами явились программы-навигаторы в сети Интернет (браузеры, browser), которые, по сути, минимально должны были содержать две составляющих: клиентскую часть для обмена данными по протоколу HTTP и интерпретатор языка HTML., В настоящее время преобладают две — Internet Explorer и Netscape Navigator Первый из них доминирует на архитектуре персональных компьютеров на базе процессоров типа Intel 80х86 под управлением ОС типа Microsoft Windows.

Гораздо разнообразнее программное обеспечение серверной части. Это вызвано тем, что в протоколе HTTP нигде строго не специфицирован источник HTML-текста. Им может быть обычный текстовый файл, и тогда клиент будет видеть у себя статическую картинку всякий раз, когда устанавливает соединение с данным сервером. Но может быть и так, что сервер будет порождать новый HTML — текст всякий раз, когда клиент устанавливает с ним соединение, или даже менять текст по мере работы клиента с сервером. Тогда и изображение на стороне клиента» зависящее от интерпретируемого текста HTML, будет динамически изменяться по мере изменения текста. Последний вариант представляет гораздо больший интерес с точки зрения предоставляемых возможностей. Вопрос только в том, как организовать динамическое изменение HTML-текста. Вот в этом на­правлении и шло развитие основных средств Интернет — программирования.

Язык HTML прост и тем удобен. Однако отсюда проистекают и основные его недостатки. Во-первых, он не предоставляет средств динамического изменения содержимого интерфейсных форм и изображений, поэтому основной метод — динанамическое изменение самого текста HTML. Во-вторых, данный язык не предоставляет никаких методов поддержки современных архитектур типа «клиент-сервер» или трехуровневой архитектуры. Он не позволяет обмениваться данными ни с серверами БД, ни с серверами приложений как на стороне сервера, где готовятся тексты HTML, так и на стороне клиента, где эти тексты интерпретиру­ются. Наконец, этот язык имеет очень ограниченные средства для реакции на действия пользователя в интерфейсных формах, созданных с его помощью.

Для устранения этих недостатков были предложены различные средства. Некоторые из них рассмотрены ниже.

Программирование динамических Web-страниц

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

Вопрос только в том, как обеспечить динамическую генерацию HTML-кода на стороне сервера.

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

CGI (common gateway interface, общедоступный шлюзовой интерфейс) — это ин­терфейс для запуска внешних программ на сервере в ответ на действия клиента, установившего соединение с ним через глобальную сеть. Пользуясь этим интер­фейсом, приложения могут получать информацию от удаленного пользователя, анализировать ее, формировать HTML-код и отсылать его клиенту. CGI-прило-жения могут получать данные из заполненной формы, построенной с помощью HTML, либо из командной строки описания URL (universal resource locator, универсальный указатель ресурса). Строка URL вводится в программе-навигаторе, осуществляющей доступ к серверу со стороны клиента через глобальную сеть по протоколу HTTP. To, какие CGI-приложения по каким действиям пользователя должны выполняться на сервере, указывается непосредственно в коде HTML-страницы, которую сервер передает клиенту.

Кроме интерфейса CGI существуют и другие варианты интерфейсов, позволяю­щие динамически создавать HTML-код путем запуска на сервере приложений в ответ на действия клиента. Например, можно выделить интерфейс ISAPI (Internet server application programming interim интерфейс прикладных программ Интернет-сервера). Отличие ISAPI от CGI заключается в том, что для поддержки CGI создаются отдельные приложения, выполняющиеся в виде самостоятельных программ, а ISAPI поддерживается с помощью библиотек, динамически подключаемых к серверу. ISAPI-библиотеки исполняются непосредственно в адресном пространстве сервера, имеют большие возможности и обеспечивают более высокую производительность сервера, в то время как CGI-приложения исполняются в ОС сервера как отдельные процессы и вынуждены определенным образом организовывать обмен данными с самим сервером (что снижает производитель­ность). Но, с другой стороны, ошибка в библиотеке ISAPI может привести к выходу всего сервера из строя и его длительной неработоспособности. В то же вре­мя ошибка в коде CGI-приложения может, в худшем случае, привести только к аварийному завершению выполнения этого приложения, а сам сервер при этом сохранит работоспособность. Тогда в результате ошибки будет неверно отображена только какая-то одна HTML-страница либо часть страницы, а все остальные части сервера будут продолжать исправно работать.

Современные системы программирования, в том числе и те из них, что были рассмотрены в качестве примеров в данном пособии, позволяют создавать приложе­ния и библиотеки, рассчитанные на работу в глобальной сети в соответствии со стандартами CGI или ISAPI. При этом создание исходного кода приложения практически ничем не отличается от создания обычной исполняемой программы, компилятор по-прежнему порождает объектные файлы, но компоновщик со­бирает исполняемый файл или библиотеку с учетом того, что они будут испол­няться в архитектуре сервера глобальной сети. Функции загрузчика выполняет ОС по команде сервера либо сам Интернет-сервер.

Этот метод удобен, но имеет один серьезный недостаток: при изменении содержимого динамической HTML-страницы или же при изменении логики ее реакции на действия Интернет-клиента требуется создать новые код CGI или ISAPI-приложения. А для этого нужно выполнить полностью весь цикл построения ре­зультирующей программы, начиная от изменения исходного кода, включая ком­пиляцию и компоновку. Поскольку содержимое Web-страниц меняется довольно часто (в отличие от обычных программ), то такой подход нельзя признать очень эффективным. Кроме того, может потребоваться перенос Интернет-серве­ра с одной архитектуры вычислительной системы на другую, а это также потребует перестройки всех используемых CGI-приложений и ISAPI-библиотек.

Лучших результатов можно добиться, если не выполнять на сервере уже скомпилированный и готовый объектный код, а интерпретировать код программы, написанной на некотором языке. При интерпретации исходного кода сервер, конечно, будет иметь производительность ниже, чем при исполнении готового объектного кода, но чаще всего этим можно пренебречь, поскольку производи­тельность серверов Интернета ограничивает чаще всего не мощность вычис­лительной системы, а пропускная способность кайала обмена данными. Тогда зависимость кода сервера от архитектуры вычислительной системы будет мини­мальной, а изменить содержимое порождаемой HTML-страницы можно будет сразу же, как только будет изменен порождающий ее исходный код (без допол­нительной перекомпиляции).

Существует несколько языков и соответствующих им интерпретаторов, которые нашли применение в этой области и успешно служат цели порождения HTML-страниц. Среди них можно назвать язык Peri, лежащий в основе различных версий Web-технологии РНР (Personal home pages), и язык сценариев, на котором основана Web-технология ASP (Active server pages), — последний предложен и поддерживается известным производителем программного обеспечения — фирмой Microsoft. Компонент, интерпретирующий ASP, появился в составе версии US (Internet information server) 3.0. В результате разработчики получили более простые в применении и вместе с тем более мощные средства создания Web-приложений.

Текст на интерпретируемых языках, которые поддерживаются такими Web-технологиями, как ASP или РНР представляет собой часть текста обычных HTML-страниц со встроенными в них сценариями (script). Эти сценарии можно писать на любом языке, поддерживаемом сервером; Интернет-сервер обрабатывает их при поступлении запроса о URL-адресе соответствующего файла. Он разбирает текст HTML-страницы, находит в нем тексты сценариев, вырезает их и интер­претирует в соответствии с синтаксисом и семантикой данного языка. В резуль­тате интерпретации получается выходной текст на языке HTML, который сервер вставляет непосредственно в то место исходной страницы, где встретился сценарий. Так обрабатывается динамическая Web-страница на любом интерпретируемом языке, ориентированном на работу в глобальной сети. Естественно, для работы со страницей сервер должен иметь в своем составе интерпретатор соответствующего языка.

Все эти языки сценариев обладают присущими им характерными особенно­стями. Во-первых, они имеют мощные встроенные функции и средства для работы со строками, поскольку основной задачей программ, написанных с помощью таких языков, является обработка входных параметров (строковых) и порождение HTML-кода (который также является текстом). Во-вторых, все они имеют средства для работы в архитектуре «клиент—сервер» для обмена информацией с серверами БД, а многие современные версии таких языков (например, язык, под­держиваемый Web-технологией ASP) — средства для функционирования в трех­уровневой архитектуре для обмена данными с серверами приложений.

Технологии интерпретируемых языков сценариев, отделившие процесс написания кода HTML от процесса создания прикладных компонентов, способствовали более эффективному сотрудничеству между дизайнерами Web-страниц и разработчиками программ. Благодаря тому, что динамические данные и приложения генерируются с помощью интерпретируемых языков непосредственно на Интер­нет-сервере, информация остается там, где ею легче всего управлять.

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

вынужден строить HTML-описание, собирая его некоторым образом из каких-то своих данных, а затем Интернет-клиент на своей стороне разбирает (интерпрети­рует) полученное описание HTML-страницы. Таким образом, выполняется как бы двойная работа по генерации, а затем интерпретации текстов языка HTML. Кроме того, между клиентом и сервером по сети передаются довольно громозд­кие описания HTML-страниц, что может значительно увеличивать трафнк сети.

Тем не менее, несмотря на недостатки, данные методы довольно распространены в глобальной сети, поскольку они очень просты, а кроме того, не требуют от кли­ентского компьютера ничего, кроме способности интерпретировать тексты HTML. Эта особенность довольно существенна.

Есть и другие варианты генерации динамических HTML-страниц. Рассмотренные далее методы, хотя и снижают нагрузку на сеть, но предъявляют определен­ные требования к клиентской части, что не всегда приемлемо.

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

Язык Java был разработан компанией Sun в качестве средства Web-программирования. Этот язык, в отличие от языка описания гипертекста HTML, является полноценным языком программирования 0н содержит в себе все основные операторы, конструкции и структуры данных, присущие языкам программирования. Синтаксические конструкции и семантика языка Java большей частью были заимствованы из языков программирования С и C++.

Основная идея, отличающая язык Java от многих других языков программирова­ния, не ориентированных на применение в глобальной сети, заключается в том что Java не является полностью компилируемым языком. Исходная программа, созданная на языке Java, не преобразуется в машинные коды. Компилятор языка порождает некую промежуточную результирующую программу на специальном низкоуровневом двоичном коде (эта результирующая программа называется Java-апплетом, а код, на котором она строится, — Java байт-кодом). Именно этот код интерпретируется при исполнении результирующей Java-программы. Такой ме­тод исполнения кода, основанный на интерпретации, делает его практически независимым от архитектуры целевой вычислительной системы.

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

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

Менеджер памяти входит в состав виртуальной Java-машины и, безусловно, за-/ висит от архитектуры вычислительной системы, где функционирует эта машина, но интерпретируемые ею программы при этом остаются независимыми от архитектуры. Хороший менеджер памяти — важная составляющая виртуальной Java-машины наряду с быстродействующим интерпретатором промежуточного низ­коуровневого кода.

При выполнении Java-программы в глобальной сети компилятор, порождающий промежуточный низкоуровневый код, находится на стороне Интернет-сервера, а интерпретатор, выполняющий этот код, — на стороне клиента. По сети от сер­вера к клиенту передается только уже скомпилированный код. С этой точки зре­ния использование языка Java для исполнения программ в сети и организации динамических Web-страниц дает преимущества по сравнению с использованием других языков, выполняемых на стороне сервера, как описано выше. Преимущество заключается в том, что по сети не надо передавать громоздкие HTML-опи­сания страниц, что значительно снижает трафик в сети.

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

Еще одна особенность связана с необходимостью обеспечения безопасности при исполнении Java-программ. Поскольку код исполняемой программы поступает из глобальной сети, то нет никакой гарантии, что этот код не содержит фатальную ошибку. Кроме того, такой код может быть преднамеренно создан со злым умыслом. Имея все возможности языка программирования (в отличие от текста HTML) и исполняясь в среде вычислительной системы клиента, он может при­вести к выходу из строя этой системы или к повреждению хранящихся в ней данных. Потому при построении интерпретатора виртуальной Java-машины нужно целенаправленно выделять и отслеживать потенциально опасные команды (та­кие, как выполнение программ или обращение к/ файлам на клиентской маши­не). Несмотря на то что большинство производителей виртуальных Java-машин считаются с этим правилом, проблема безопасности остается актуальной при использовании языка Java.

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

Росту популярности языка программирования Java и построенных на его основе систем программирования способствовал также тот факт, что в его состав вхо­дят встроенные средства поддержки интерфейса с серверами БД, ориентирован­ные на разработку приложений, выполняющихся в архитектуре «клиент—сервер». Системы программирования языка Java совместимы также с известной группой стандартов, ориентированной на разработку результирующих программ, выполняющихся в трехуровневой архитектуре — CORBA.

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

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

Чтобы решить эти проблемы, был предложен командный язык Java Script, кото­рый можно назвать упрощенным вариантом языка Java.

Фрагменты кода, написанные на Java Script, передаются непосредственно внутри текста HTML-страниц. Синтаксис и семантика Java Script в целом соответст­вуют языку Java, но возможности его выполнения сильно ограничены — они не выходят за рамки той программы, которая интерпретирует HTML-страницу. В таком случае эта программа выступает и в роли виртуальной Java-машины для выполнения операторов Java Script. Чаще всего это программа навигации по сети — браузер. Он находит в тексте HTML-страницы операторы языка Java Script, выделяет их и исполняет по всем правилам языка Java. Однако выполне­ние Java Script происходит только в рамках адресного пространства программы-навигатора. Это, с одной стороны, ограничивает его возможности, но, с другой стороны, увеличивает безопасность выполнения операторов, так как в худшем1 случае при наличии некорректных операторов языка неработоспособной окажется только запущенная программа-навигатор, но не вся клиентская система в целом. Операторы Java Script сейчас широко используются для организации динами­ческих Web-страниц. Их выполнение (интерпретация) обеспечивается всеми современными программами-навигаторами в глобальной сети.

Структура программы на языке С++

Программа на языке C++ состоит из функций, описаний и директив препроцессора.
(Препроцессор — это программа, которая выполняет обработку файла исходного кода перед началом компиляции) .

Рассмотрим простейшую программу:

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

Следующая директива using открывает доступ к пространству имен (англ. namespace) std , в котором определяются средства стандартной библиотеки языка C++.
(Пространство имён — некоторое множество, созданное для логической группировки уникальных идентификаторов) .

Отправной точкой выполнения любой С++-программы является функция main() . Функция содержит четыре элемента:

  • возвращаемый тип (в нашем случае int);
  • имя функции (main);
  • список параметров, заключенный в круглые скобки (в данном случае список пуст);
  • заключенное в фигурные скобки, тело функции, представляющее собой блок инструкций.

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

В нашей программе тело функции содержит две инструкции:

    cout Hello, World , а затем возвращается в точку вызова значение 0, которое означает, что программа выполнена успешно.

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

  • директивы препроцессора, начинающиеся с символа # (например, #include);
  • составные операторы и блоки определения функций, которые обрамлены фигурными скобками — < >.

Copyright © 2014-2020, Урок информатики
Все права защищены

Илон Маск рекомендует:  Artisteer 3 - конструктор web-сайтов
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL