Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
21-34_ПР-ИЕ.doc
Скачиваний:
12
Добавлен:
28.08.2019
Размер:
328.19 Кб
Скачать

21. Основные понятия структурного программирования. Идентификаторы. Переменные и константы. Тип данных. Выражения. Инструкция присваивания. Теорема о структурировании. Базовые управляющие структуры.

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

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

В соответствии с данной методологией

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

    • последовательное исполнение — однократное выполнение операций в том порядке, в котором они записаны в тексте программы;

    • ветвление — однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия;

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

  2. Разработка программы ведётся пошагово, методом «сверху вниз».

Идентификатор

Ид-р - просто ИМЯ некоей сущности в программе (переменная, константа, функция, тип и т.п.).

Правила создания идентификаторов.

  • идентификаторы могут состоять из символов латинских букв, арабских цифр 0-9 и символа подчеркивания ( _ );

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

  • длина идентификатора ограничивается 255 символами (учитываются первые 31);

  • идентификаторы должны быть информативными, т.е. соответствовать смыслу соответствующей именованной сущности (переменной, константы, типа, процедуры и т.п.);

  • регистр букв в идентификаторах учитывается (в языке C/C++);

  • зарезервированные слова нельзя использовать в качестве идентификаторов.

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

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

Константы и переменные

  1. Константы

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

CONST Имя_константы = Выражение [, Имя_константы "Выражение]...

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

  1. Переменные

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

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

Примечание: Следите за тем, чтобы имена переменных и констант соответствовали их содержанию. С переменными height!, telefon$, length! сразу ассоциируется их применение.

Тип данных

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

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

Типы данных бывают следующие:

  1. Простые.

    • Перечислимый тип. Может хранить только те значения, которые прямо указаны в его описании.

  • Числовые. Хранятся числа. Могут применяться обычные арифметические операции.

  • Целочисленные: со знаком, то есть могут принимать как положительные, так и отрицательные значения; и без знака, то есть могут принимать только неотрицательные значения.

  • Вещественные.

  • Символьный тип. Хранит один символ. Могут использоваться различные кодировки.

  • Логический тип. Имеет два значения: истина и ложь, при троичной логике может иметь и третье значение — «не определено» (или «неизвестно»). Могут применяться логические операции. Используется в операторах ветвления и циклах. В некоторых языках является подтипом числового типа, при этом ложь=0, истина=1.

  1. Составные (сложные). Множество. В основном совпадает с обычным математическим понятием множества. Допустимы стандартные операции с множествами и проверка на принадлежность элемента множеству. В некоторых языках рассматривается как составной тип.

Массив. Является индексированным набором элементов одного типа. Одномерный массив — вектор, двумерный массив — матрица.

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

Запись (структура). Набор различных элементов (полей записи), хранимый как единое целое. Возможен доступ к отдельным полям записи. Например, struct в C или record в Pascal.

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

Класс.

Указатель. Хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — указатель на переменную.

Выражения

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

Привести пример выражения

Инструкция присваивания

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

В общем виде инструкция присваивания выглядит так:

ИмяПеременной:= Выражение;

где:

Имя - переменная, значение которой изменяется в результате выполнения инструкции присваивания;

:= - символ инструкции присваивания.

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

Пример:

Summa := Сеnа * Kol;

Skidka := 10;

Found := False;

Базовые управляющие структуры

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

Базовый управляющие Структуры:

  1. условные операторы

  2. циклы

  3. блоки (следование, составная инструкция).

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

Процедурное программирование

Процедурное программирование – идеология программирования, которая является развитием структурного программирования. Основана на структурировании программы с помощью выделения подпрограмм. Улучшается структура, читаемость программы, «лишний» код скрывается в теле подпрограмм, есть возможность многократного вызова подпрограмм в программе с разными входными параметрами. Ограниченные возможности по повторному использованию кода в различных программах. Переросла в модульное программирование и далее в ООП. Примеры языков: Pascal, C, Fortran, BASIC, Lua и др.

Пользовательские подпрограммы

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

Подпрограммы могут возвращать результат через имя и выходные формальные аргументы (функции) и только через формальные аргументы – процедуры.

Восходящее и нисходящее программирование

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

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

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

Недостатки нисходящего проектирования:

  • Необходимость заглушек.

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

Преимущество нисходящего проектирования – удобна коллективная разработка.

Преимущество восходящего программирования – не нужно писать заглушки.

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

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

Описание и вызов подпрограмм

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

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

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

program SubProgExample;

// Описание подпрограммы subprog

procedure subprog; // Заголовок, включающий имя подпрограммы

begin // начало тела подпрограммы

WriteLn('Bye');

end; // конец тела подпрограммы

begin

WriteLn('Hello');

subprog; // 1-й вызов

subprog; // 2-й вызов

subprog; // 3-й вызов

end.

Результатом выполнения такой программы станет вывод строки «Hello» и трёх строк «Bye».

Определение вложенных ППР допустимо в нек-рых ЯП, но нежелательно.

Параметры-переменные и значения

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

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

ВАЖНО! В качестве фактических параметров подпрограммы, подставляемых на место фомальных параметров-значений, могут выступать: переменные, константы и выражения (точнее их значения), причем их типы должны быть совместимы по присваиванию с типами соответствующих формальных параметров-значений.

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

Описание параметров-переменных отличается от описание параметров-значений лишь наличием ключевого слова VAR перед идентификатором параметра.

ВАЖНО! В качестве фактических параметров подпрограммы, подставляемых на место фомальных параметров-переменных, могут выступать ТОЛЬКО ИДЕНТИФИКАТОРЫ ПЕРЕМЕННЫХ.

Глобальные и локальные переменные

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

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

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

Время жизни –это время между размещением переменной в стеке и ее унчтожением- может быть постоянным (в течение выполнения программы) и временным (в течение выполнения блока).

Пример конкретной задачи

23. Классификация типов данных. Классификация типов - на примере языка Паскаль. Порядковые типы. Стандартные и пользовательские типы. Простые и сложные типы. Указатели и процедурные типы. Файловые типы. Примеры.

Классификация типов данных

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

Классификация типов - на примере языка Паскаль

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

Иерархия типов в языке Паскаль такая:

  1. Простые

    • Порядковые

      1. Целые

      2. Логические

      3. Символьные

      4. Перечисляемые

      5. Интервальные

    • Вещественные

  2. Структуированные

    • Массивы

    • Строки

    • Множества

    • Записи

    • Файлы

  3. Указатели

Порядковые типы

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

Синтаксис порядкового типа имеет следующий вид:

Порядковый тип:

        • Отрезок типа

        • Перечислимый тип

        • Идентификатор порядкового типа

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

Стандартные и пользовательские типы. В первом случае множество значений преопределено, во втором (до)определяется программистом. Примеры стандартных типов - integer, real, char, boolean, string, text; пользовательских типов - перечислимый, интервальный, record, set.

Простые и сложные типы

Простые типы определяют упорядоченные множества значений.

Простой тип:

  • Порядковый тип

  • Вещественный тип

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

Идентификатор

Длина (байт)

Диапазон значений

Операции

Целые типы

Byte

1

0..255

+, -, /, *, Div, Mod, >=, <=, =, <>, <, >

Вещественные типы

Real

6

2,9x10-39 - 1,7x1038

+, -, /, *, >=, <=, =, <>, <, >

Логический тип

Boolean

1

true, false

Not, And, Or, Xor, >=, <=, =, <>, <, >

Символьный тип

Char

1

все символы кода ASCII

+, >=, <=, =, <>, <, >

Указатели и процедурные типы

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

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

Файловые типы

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

Файловый тип: file of тип

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

Стандартный файловый тип Text определяет файл, содержащий символы, упорядоченные в строки. Текстовые файлы используют специальные процедуры ввода-вывода.

Пример

24. Процесс создания программ. Этапы общей процедуры создания программного продукта. Этапы создания программы на языке высокого уровня. Трансляция и интерпретация программ. Компоновка программ. Виды ошибок в программах и средства для их исправления. Отладка программ. Классификация языков программирования.

Этапы общей процедуры создания программного продукта

Основные этапы проектирования программ:

  1. Постановка задачи. Задача формулируется на естественном языке. Определяются цели. Подготавливается техническое задание на разработку программы.

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

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

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

  5. Кодирование средствами выбранного языка программирования.

  6. Верификация и проверка корректности. Аналитическое доказательство правильности программы.

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

  8. Отладка программы в случае обнаружения ошибок. Локализация обнаруженных ошибок. Коррекция ошибок. Возврат к этапу тестирования.

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

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

  11. Промышленная эксплуатация. Сопровождение программы. Обработка требований к новым версиям программы.

Трансляция и интерпретация программ

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

Компиляция – преобразование инструкций программы (модуля) на ЯП высокого уровня в машинный код, объединение его с данными программы с созданием исполняемого (объектного) модуля.

Интерпретация – трансляция в машинный код отдельных инструкций программы с немедленным их выполнением без создания объектного или исполняемого модуля.

Модульное программирование, компоновка

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

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

  1. когда сами пишем модульную программу;

  2. когда используем стандартные библиотечные функции.

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

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

Существует три + к ним можно добавить ошибки сборки (компоновки) основных типа ошибок: ошибки этапа компиляции, ошибки этапа выполнения и логические ошибки.

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

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

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

Отладка программ

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

  • узнавать текущие значения переменных;

  • выяснять, по какому пути выполнялась программа.

Существуют две взаимодополняющие технологии отладки.

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

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

Классификация языков программирования

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

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

Следующую, существенно более многочисленную группу составляют языки программирования высокого уровня. Это Фортран, Алгол, Кобол, Паскаль, Бейсик, Си, Пролог и т.д. Эти языки машинно-независимы, т.к. они ориентированы не на систему команд той или иной ЭВМ, а на систему операндов, характерных для записи определенного класса алгоритмов. Однако программы, написанные на языках высокого уровня, занимают больше памяти и медленнее выполняются, чем программы на машинных языках.

К языкам сверхвысокого уровня можно отнести лишь Алгол-68 и APL. Повышение уровня этих языков произошло за счет введения сверхмощных операций и операторов.

Другая классификация делит языки на вычислительные и языки символьной обработки. К первому типу относят Фортран, Паскаль, Алгол, Бейсик, Си, ко второму типу - Лисп, Пролог, Снобол и др.

Широко распространены следующие процедурные языки: Паскаль, Си, Ада, ПЛ/1, Фортран, Бейсик, Фокал.

Непроцедрное (декларативное) программирование появилось в начале 70-х годов 20 века, но стремительное его развитие началось в 80-е годы, когда был разработан японский проект создания ЭВМ пятого поколения, целью которого явилась подготовка почвы для создания интеллектуальных машин. К непроцедурному программированию относятся функциональные и логические языки.

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

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

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

Языки описания сценариев, такие как Perl, Python, Rexx, Tcl и языки оболочек UNIX, предполагают стиль программирования, весьма отличный от характерного для языков системного уровня. Они предназначаются не для написания приложения с нуля, а для комбинирования компонентов, набор которых создается заранее при помощи других языков. Развитие и рост популярности Internet также способствовали распространению языков описания сценариев. Так, для написания сценариев широко употребляется язык Perl, а среди разработчиков Web-страниц популярен JavaScript.

25. Абстрактные линейные структуры данных: Массивы и списки. Строки Основные операции со структурами данных. Перебор компонентов, добавление, удаление компонентов. Особенности работы со строковыми данными. Типичные операции со строками.

Абстра́ктный тип да́нных (АТД) — это тип данных, который предоставляет для работы с элементами этого типа определённый набор функций, а также возможность создавать элементы этого типа при помощи специальных функций. Вся внутренняя структура такого типа спрятана от программиста — в этом суть абстракции. АТД определяет набор независимых от конкретной реализации типа функций для оперирования его значениями. Конкретные реализации АТД называются структурами данных. Абстрактный тип данных (АТД) обеспечивает обобщение и инкапсуляции: 1)АТД можно рассматривать как обобщение стандартных типов данных. 2) АТД инкапсулирует типы данных таким образом, что определение типа и все операторы, выполняемые над данными этого типа помещаются в один раздел программы.

Массив

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

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

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

Объявление массива в ЯП С++

int Array[10]; // Статический, размер 10, базовый тип данных - целое число (int)

double Array[12][15]; // Статический массив, 2 измерения, базовый тип данных – число с дробной частью (double)

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

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

float *array1; // Одномерный массив

int **array2; // Многомерный массив

array1 = new float[10];// выделение 10 блоков размером типа float

array2 = new int*[16];// выделение 16 блоков размером типа указателя на int

for(int i = 0; i < 16; i++)

array2[i] = new int[8];

Достоинства

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

  • одинаковое время доступа ко всем элементам

  • малый размер элементов: они состоят только из информационного поля

Недостатки

  • для статического массива — отсутствие динамики, невозможность удаления или добавления элемента без сдвига других

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

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

Списки

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

Если для обработки таких данных не использовать внешнюю память (файлы), то разумно расположить их в динамической памяти. Во-первых, динамическая память позволяет хранить больший объем информации, чем статическая. А во-вторых, в динамической памяти эти числа можно организовать в связанный список, который не требует предварительного указания количества чисел, подобно массиву. Что же такое "связанный список"? Схематически он выглядит так:

Здесь Inf — информационная часть звена списка (величина любого простого или структурированного типа, кроме файлового), Next — указатель на следующее звено списка; First — указатель на заглавное звено списка.

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

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

Type U = ^Zveno;

Zveno = Record Inf : BT; Next: U End;

Здесь BT — некоторый базовый тип элементов списка.

Если указатель ссылается только на следующее звено списка (как показано на рисунке и в объявленной выше структуре), то такой список называют однонаправленным или односвязным, если на следующее и предыдущее звенья — двунаправленным или двусвязным списком. Если указатель в последнем звене установлен не в Nil, а ссылается на заглавное звено списка, то такой список называется кольцевым или циклическим. Кольцевыми могут быть и однонаправленные, и двунаправленные списки.

Выделим типовые операции над списками:

  • добавление звена в начало списка;

  • удаление звена из начала списка;

  • добавление звена в произвольное место списка, отличное от начала (например, после звена, указатель на которое задан);

  • удаление звена из произвольного места списка, отличного от начала (например, после звена, указатель на которое задан);

  • проверка, пуст ли список;

  • очистка списка;

  • печать списка.

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