Управляющие операторы и структуры
•Отвечают только за порядок выполнения операторов программы:
· Оператор безусловного перехода goto и подобные ему break,continue,esit,return.
· Операторы ветвления/проверки условий if,else,elseif…
· Оператор выбора switch,case.
· Операторы цикла for,while,do while,foreach…
· Операторы вызова подпрограмм и возвращения из программы.
· Если в ЯП реализованы только первые два типа операторов – это структурное программирование.
69. Ленивые и жадные вычисления в процедурном и функциональном программировании.
Ленивое вычисление — стратегия вычисления, которая откладывает вычисления выражения до момента, когда значение этого выражения будет необходимо.
Бесконечная структура данных — структура, определение которых дано в терминах бесконечных диапазонов или непрекращающейся рекурсии, но реальные значения вычисляются только в момент, когда они необходимы.
Ленивое вычисление — применяемая в некоторых языках программирования стратегия вычисления, согласно которой вычисления следует откладывать до тех пор, пока не понадобится их результат.
Ленивые и жадные вычисления — две крайности управления, берущего свое начало от данных. Принцип ленивости направляет процесс от требуемых результатов, его можно рассматривать как получение (рекурсивного) ответа на вопрос:
Что из того, что требуется для продуцирования результатов, может быть и, следовательно, должно быть вычислено?
Принцип жадности направляет процесс от исходных данных, отвечая на вопрос:
Что может быть и, следовательно, должно быть вычислено, используя наличествующие сейчас данные?
Функциона́льное программи́рование — раздел дискретной математики и парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).
Процеду́рное программи́рование — программирование на императивном языке, при котором последовательно выполняемые операторы можно собрать в подпрограммы, то есть более крупные целостные единицы кода, с помощью механизмов самого языка.
70. Языки высокого уровня.
[Низкоуровневые и высокоуровневые языки]
Высший Fortran, pascal,ada
Средний C,C++,C#,Java, Basic
Низший Assembler
○Низкоуровневые языки: (Примитивные и ориентированные на численные расчеты)
•Программы представляют собой линейные последовательности элементарных операций с регистрами, в которых хранятся данные.
•Они оптимизированы под конкретную ЭВМ.
•Как правило, не стандартизированы.
◘Низкоуровневое программирование – программирование, основанное на прямом использовании возможностей особенностей конкретной вычислительной системы.
Нужно знать:
1. Структуру и функционирование системы в целом.
2. Организацию оперативной памяти.
3. Состав внешних устройств, их адреса и форматы регистров.
4. Организацию и функционирование процессора, состав и формат его регистров, способы адресации системы команд.
5. Систему прерываний.
6. Вычислительная система – совокупность не только аппаратных, но и программных средств, которые также оказывают влияние.
Виды:
•Машинные коды – программа представлена в виде последовательности чисел, являющихся кодами команд процессора, адресами оперативной памяти, номерами регистров процессора и внешних устройств.
•Мнемокоды – вместо чисел позволяли использовать мнемонические (символьные) имена, отражающие смысл выполняемой команды.
•Ассемблер – отличается от мнемокодов обширным набором директив транслятора, существенно упрощающих процесс кодирования программы в виде логически законченных элементов.
•Макроассемблеры – расширение ассемблера за счет включения макросредств т.е. предоставляет возможность определения и использования новых более мощных команд.
○Высокоуровневые языки:
•Повышение эффективности труда разработчиков за счет абстрагирования от конкретных деталей аппаратного обеспечения
•Снижение уровня зависимости реализации от аппаратного обеспечения.
•Появление трансляторов.
•Высокая переносимость программ.
Высокоуровневый язык программирования — язык программирования, разработанный для быстроты и удобства использования программистом. Основная черта высокоуровневых языков — это абстракция, то есть введение смысловых конструкций, кратко описывающих такие структуры данных и операции над ними, описания которых на машинном коде (или другом низкоуровневом языке программирования) очень длинны и сложны для понимания.
Языки же высокого уровня имитируют естественные языки, используя некоторые слова разговорного языка и общепринятые математические символы. Эти языки более удобны для человека.
Языки высокого уровня делятся на:
· процедурные (алгоритмические) (Basic, Pascal, C и др.), которые предназначены для однозначного описания алгоритмов; для решения задачи процедурные языки требуют в той или иной форме явно записать процедуру ее решения;
· логические (Prolog, Lisp и др.), которые ориентированы не на разработку алгоритма решения задачи, а на систематическое и формализованное описание задачи с тем, чтобы решение следовало из составленного описания;
· объектно-ориентированные (Object Pascal, C++, Java и др.), в основе которых лежит понятие объекта, сочетающего в себе данные и действия над нами.Программа на объектно-ориентированном языке, решая некоторую задачу, по сути описывает часть мира, относящуюся к этой задаче. Описание действительности в форме системы взаимодействующих объектов естественнее, чем в форме взаимодействующих процедур.
Язык высокого уровня - Язык программирования, средства которого обеспечивают описание задачи в наглядном, легко воспринимаемом виде, удобном для программиста. Он не зависит от внутренних машинных кодов ЭВМ любого типа, поэтому программы, написанные на языках высокого уровня, требуют перевода в машинные коды программами транслятора либо интерпретатора. К языкам высокого уровня относят Фортран , ПЛ/1 , Бейсик , Паскаль , Си , Ада и др.
Язык низкого уровня - Язык программирования, предназначенный для определенного типа ЭВМ и отражающий его внутренний машинный код (см. ниже также “машинный язык “, “ машинно-ориентированный язык “ и “ язык ассемблера “).
71. Показатели качества программных средств.
Функциональная пригодностьдетализируется пригодностью для применения, точностью, защищенностью, способностью к взаимодействию и согласованностью со стандартами и правилами проектирования.
Надежностьрекомендуется характеризовать уровнем завершенности (отсутствия ошибок), устойчивостью к ошибкам и перезапускаемостью.
Применимостьпредлагается описывать понятностью, обучаемостью и простотой использования.
Эффективность рекомендуется характеризовать ресурсной и временной экономичностью.
Сопровождаемость характеризуется удобством для анализа, изменяемостью, стабильностью и тестируемостью.
Переносимость предлагается отражать адаптируемостью, структурированностью, замещаемостью и внедряемостью.
Оценка качества декомпозиции предметной области
• Для оценки качества классов и объектов существуют 5 критериев:
1. Зацепление – степень глубины связи между отдельными модулями. (чем меньше связность тем лучше)
2. Связность – степень взаимодействия между элементами отдельного модуля. (чем крепче связь тем лучше)
3. Достаточность – степень необходимого для реализации логичного и эффективного поведения в классе. (не наполнять лишним функционалом)
4. Полнота – в интерфейсной части класса должны быть учтены все характеристики абстракции. (Не исключать главное)
5. Примитивность - примитивными являются только те операции, которые требуют доступа к внутренней реализации абстракции. (операции внутренние не обращаются к другим классам, дополнение связности)
72. Отношения между классами в объектно-ориентированном программировании.
Ассоциация показывает структурные отношения между объектами-экземплярами класса, т.е. соединения между классами.
Когда класс участвует в ассоциации, он играет в этом отношении определенную роль.
• Мощность ассоциации бывает одного из трех типов:
1. один-к-одному;
2. один-ко-многим;
3. многие-ко-многим
Зависимость - это отношение, которое показывает, что изменение в одном классе (независимом) может влиять на другой класс (зависимый), который использует его.
С помощью зависимости уточняют, какая абстракция является клиентом, а какая — поставщиком определенной услуги.
Пунктирная стрелка зависимости направлена от клиента к поставщику.
Агрегация обозначает отношения классов в иерархии «целое/часть». Говорят, что агрегация образует «part of»-иерархию классов (и объектов).
Агрегация обеспечивает возможность перемещения от целого (агрегата) к его частям (атрибутам).
Нефизическое включение – агрегация.
Композиция – физическое включение.
Один класс без другого не может существовать.
Реализация - это отношение между классами, в котором класс-приемник выполняет реализацию операций интерфейса класса-источника.
Класс Каталог должен реализовать интерфейс Обработчик каталога, то есть Обработчик каталога рассматривается как источник, а Каталог — как приемник.
Обобщение — отношение между общей сущностью и специализированной разновидностью этой сущности.
Наследование - это отношение, при котором один класс разделяет структуру и поведение, определенные в одном другом (простое наследование) или во многих других (множественное наследование) классах.
73. Файлы, обработка файлов. Типы доступа к файлам.
Файл – именованный набор байтов, который может быть сохранен на некотором накопителе.
Работа с файлами реализуется средствами операционных систем. Многие операционные системы приравнивают к файлам и обрабатывают сходным образом и другие ресурсы:
•области данных (необязательно на диске);
•устройства — как физические, например, порты или принтеры, так и виртуальные (/dev/null, /dev/random, /dev/urandom);
•потоки данных (именованный канал);
•сетевые ресурсы, сокеты;
•прочие объекты операционной системы.
Метод доступа - действия, выполняемые при сохранении или извлечении записей из файла.
Поскольку некоторые методы доступа могут применяться только к файлам с определенным типом организации (например, нельзя применять индексный метод доступа к файлу, не имеющему индекса), термины "организация файла" и "метод доступа" часто рассматриваются как эквивалентные. Дальше в этом приложении описаны основные типы структуры файлов и соответствующие им методы доступа. В главе 16 представлена методология физического проектирования базы данных для реляционных систем вместе с рекомендациями по выбору наиболее подходящей структуры файлов и индексов.
74. Абстрактные типы данных: инкапсуляция, спецификация, реализация, параметризация.
Инкапсуляция – сокрытие деталей реализации, которое позволяет вносить изменения в части программы безболезненно для других ее частей, что упрощает сопровождение и модификацию ПО.
Реализация типов данных определяет, каким образом данные виртуальной среды вычислений отображаются на аппаратные и программные средства.
Абстра́ктный тип да́нных (АТД) — это множество объектов, определяемое списком компонентов (операций , применимых к этим объектам, и их свойств). Вся внутренняя структура такого типа спрятана от разработчика программного обеспечения — в этом и заключается суть абстракции. Абстрактный тип данных определяет набор функций, независимых от конкретной реализации типа, для оперирования его значениями.
75. Основные группы команд, операторы, средства взаимодействия с операционной системой в языках ассемблера.
Регистры – это специальные ячейки памяти, расположенные непосредственно в процессоре. Работа с регистрами выполняется намного быстрее, чем с ячейками оперативной памяти, поэтому регистры активно используются как в программах на языке ассемблера, так и компиляторами языков высокого уровня.
Названия регистров происходят от их назначения:
· EAX/AX/AH/AL (accumulator register) – аккумулятор;
· EBX/BX/BH/BL (base register) –регистр базы;
· ECX/CX/CH/CL (counter register) – счётчик;
· EDX/DX/DH/DL (data register) – регистр данных;
· ESI/SI (source index register) – индекс источника;
· EDI/DI (destination index register) – индекс приёмника (получателя);
· ESP/SP (stack pointer register) – регистр указателя стека;
· EBP/BP (base pointer register) – регистр указателя базы кадра стека.
Флаг – это бит, принимающий значение 1 («флаг установлен»), если выполнено некоторое условие, и значение 0 («флаг сброшен») в противном случае. Процессор имеет регистр флагов, содержащий набор флагов, отражающий текущее состояние процессора.
Каждая программа имеет область памяти, называемую стеком. Стек используется для передачи параметров в процедуры и для хранения локальных данных процедур. Как известно, стек – это область памяти, при работе с которой необходимо соблюдать определённые правила, а именно: данные, которые попали в стек первыми, извлекаются оттуда последними. С другой стороны, если программе выделена некоторая память, то нет никаких физических ограничений на чтение и запись.
Команды языка ассемблера – это символьная форма записи машинных команд. Команды имеют следующий синтаксис:
[<метка>:] <мнемокод> [<операнды>] [;<комментарий>]
Метка – это имя. Метка обязательно должна отделяться двоеточием, но может размещаться отдельно, в строке, предшествующей остальной части команды.
Метки нужны для ссылок на команды из других мест, например, в командах перехода. Компилятор языка ассемблера заменяет метки адресами команд.
Мнемокод – это служебное слово, указывающее операцию, которая должна быть выполнена. Язык ассемблера использует не цифровые коды операций, а мнемокоды, которые легче запоминаются. Мнемокод является обязательной частью команды.
Операнды команды, если они есть, отделяются друг от друга запятыми.
В качестве операндов команд языка ассемблера могут использоваться:
•регистры, обращение к которым осуществляется по именам;
•непосредственные операнды – константы, записываемые непосредственно в команде;
•ячейки памяти – в команде записывается адрес нужной ячейки.
Команда ADD складывает операнды и записывает их сумму на место первого операнда. Команда SUB вычитает из первого операнда второй и записывает полученную разность на место первого операнда. Операнды должны иметь одинаковый размер. Если первый операнд – регистр, то второй может быть также регистром, ячейкой памяти и непосредственным операндом. Если первый операнд – ячейка памяти, то второй операнд может быть регистром или непосредственным операндом.
Команды пересылки. Основной командой этой группы является команда MOV, которая обеспечивает пересылку данных между двумя регистрами или между регистром и ячейкой памяти. В некоторых микропроцессорах реализуется пересылка между двумя ячейками памяти, а также групповая пересылка содержимого нескольких регистров в память или их загрузка из памяти.