- •Преимущества
- •Связь: ooa→oop→ood
- •Механизм работы virtual
- •Абстрактный класс
- •Виртуальный деструктор
- •{Основные элементы языка программирования}
- •Основные подходы к семантике:
- •Формальное описание семантики:
- •Среда программирования
- •Объекты данных
- •Атрибуты объекта данных
- •Система типизации данных
- •Реализация типов данных
- •Типизация
- •Система типизации данных
- •Реализация типов данных
- •Связывание переменных
- •Контроль типов
- •Статистический контроль типов
- •Алгоритм статистического контроля типов
- •Динамический контроль типов
- •Параллелизм
- •Полиморфизм
- •Статический полиморфизм
- •Динамический полиморфизм
- •Преобразование типов
- •Связь: ooa→oop→ood
- •Среда программирования
- •Цель технологий параллелизма
- •Схемы параллелизма
- •Проблемы параллельного программирования
- •Показатели эффективности параллельного алгоритма Ускорение
- •Закон Густавсона-Барсиса
- •Масштабируемый алгоритм
- •Схемы параллелизма
- •Подтипы данных
- •Разновидности массивов. Статические
- •Кортежи
- •Разновидности массивов. Статические
- •Динамические
- •Атрибуты объекта данных
- •Операции над целыми числами
- •Вещественные числа
- •Числа с фиксированной точкой
- •Числа с плавающей точкой(float)
- •Ошибки вычислений с вещественными числами
- •Утечки памяти и повисшие указатели
- •Указатели на указатели
- •Типизированные указатели
- •Указатели на функции
- •[Отличия указателей и ссылок]
- •Параметры подпрограмм
- •Преимущества подпрограмм
- •Позиционное сопоставление
- •Сопоставление по имени
- •Методы передачи параметров:
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Передача параметров по значению-результату
- •Параметр по результату
- •Стековые языки
- •Циклы и рекурсия
- •Циклы со счетчиком
- •Операторы циклы без заданного числа повторений (бесконечно)
- •Динамический полиморфизм
- •Родовые (настраиваемые) сегменты и шаблоны
Динамический полиморфизм
• Динамический полиморфизм – структурная неопределенность сохраняется до этапа выполнения.
1. Вариантные и неограниченные записи – одна переменная может иметь значение разных типов.
2. Диспетчеризация во время выполнения – механизм, посредством которого разрешение обращения к преопределенному методу осуществляется во время выполнения, а не во время компиляции. Этот полиморфизм реализуется с помощью виртуальных функций.
65. Родовые (настраиваемые) сегменты.
Родовой (настраиваемый) сегмент – параметризованный шаблон подпрограммы, используется для создания различных конкретных экземпляров подпрограмм.
Родовые (настраиваемые) сегменты и шаблоны
• Понятие «родовые настраиваемые сегменты» старо и использовалось Ada.
• Родовые функции в языке С++ называются функциями-шаблонами
• Объявление функции-шаблона имеет следующую общую форму:
Template <Template <параметры шаблона>
• функция-шаблон должна иметь хотя бы один родовой параметр, представляемый в одной из следующих форм:
•class имя_родового_параметра
•typename имя_родового_параметра
Template<typename T>
T max (T a, T b)
{return a>b? A:b;}
66. Шаблоны.
Шаблоны - предназначены для кодирования обобщённых алгоритмов, без привязки к некоторым параметрам (например, типам данных, размерам буферов, значениям по умолчанию).
Шаблоны позволяют создавать параметризованные классы и функции. Параметром может быть любой тип или значение одного из допустимых типов (целое число, enum, указатель на любой объект с глобально доступным именем, ссылка).
Typedef – объявление своего типа
Typedef enum { black =0,green=2..)
Color a,b;
A=black;
B=a+2;//результат =green
Многие языки требуют явной типизации значений типа перечислений при таких операциях.
67. Вариантные записи.
Вариантные и неограниченные записи – одна переменная может иметь значение разных типов.
Вариантные записи - это записи с фиксированными частями. Они имеют во всех ситуациях строго определенную структуру. Соответственно, записи с вариантами в различных ситуациях могут иметь различную структуру.
Понятие записи, также как и понятие массива, является механизмом структурирования данных. Однако, в отличие от массива, запись позволяет сгруппировать в одном объекте набор объектов которые могут принадлежать различным типам. При этом объекты из которых состоит запись часто называют компонентами или полями записи.
Для работы с записями, Ада предлагает средства подобные тем, которые предоставляют другие современные языки программирования, а также дополняет их некоторыми своими особенностями. Также как и для массивов, для записей предусматривается использование агрегатов. Использование дискриминантов позволяет создавать вариантные записи, указывать размер для записи переменного размера и выполнять инициализацию компонентов записи.
68. Средства описания действий над данными. Операторы, выражения, модули, блоки в языках программирования.
<Элементы (операторы)>
•Редактор - инструментальное средство для создания и изменения исходных файлов(текстов), содержащих написанную на ЯП программу.
•Транслятор - переводит синтаксические конструкции исходного кода в т.н. объектный модуль, который содержит команды в машинном коде конкретного вычислительного устройства.
•Библиотекарь - поддерживает совокупность объектных файлов, называемых библиотеками.
•Компоновщик - собирает объектные файлы отдельных компонентов программы и разрешает внешние ссылки от одного компонента к другому, формируя исполняемый файл.
•Загрузчик – копирует исполняемый файл с диска в память и инициализирует компьютер перед выполнением программы.
•Отладчик – Инструментальное средство, которое дает возможность программисту управлять выполнением программы на уровне отдельных операторов. (диагностика ошибок)
◘Используется для диагностики ошибок:
Трассировка (пошаговое выполнение программы)
Контрольная точка – ограничение (ставит точки от каких и до каких пределов трассировать)
Проверка и изменение данных – (Зафиксировали данные в регистре, потом проверяем изменения после использования программы).
Профилировщик – измеряет трудемкость отдельных частей программы.
Среда тестирования – автоматизирует процесс тестирования программ, создавая и выполняя тесты и анализируя результаты тестирования.
Средства конфигурирования – автоматизируют поддержку версий программного продукта.
Процессор(макропроцессор) – собирает предварительную информацию, необходимую для компоновки программы, осуществляет раскрытие сокращений, называемых макросами.
Средства автоматизированной генерации кода и средства визуальной разработки – позволяет на основе некоторых шаблонов и визуальных инструментов автоматически генерировать исходный код.
Операторы и управляющие структуры
• Операторы – команды языка программирования. Каждый оператор транслируется в цепочку команд машинного кода.
Реализуют:
Простые операторы: присваивание..
Составные операторы: условия, циклы..
Основные операторы:
Оператор присваивания
Оператор ветвления
Оператор безусловного перехода
•Все остальные операторы можно реализовать через основные 3
Оператор присваивания
Классическая форма записи:
Left:=right
Выполняются следующие действия:
Вычисление значения выражения в правой части.
Вычисление значения выражения в левой части, которое трактуется как адрес ячейки памяти.
Запись значения правой части в ячейку по адресу, вычисленному в левой части
• В различных ЯП может отличаться порядок вычисления левой и правой частей.
• На транслятор возлагается обязанность контроля соответствия типа – соответствия типов левой и правой частей.
• При этом возможны три варианта при несовпадении типов:
Ничего не делать, оставить как есть. Может привести к появлению пустых ячеек или к перезатиранию ячеек, не относящихся к переменной.
Неявно преобразовать значение к типу переменной.
Строгий контроль соответствия типов – не выполнять действие и сообщить об ошибке в случае несоответствия.
ЯП, реализующие третий подход, называют строго типизированными.
Управляющие операторы и структуры
•Отвечают только за порядок выполнения операторов программы:
Оператор безусловного перехода 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
○Низкоуровневые языки: (Примитивные и ориентированные на численные расчеты)
•Программы представляют собой линейные последовательности элементарных операций с регистрами, в которых хранятся данные.
•Они оптимизированы под конкретную ЭВМ.
•Как правило, не стандартизированы.
◘Низкоуровневое программирование – программирование, основанное на прямом использовании возможностей особенностей конкретной вычислительной системы.
Нужно знать:
Структуру и функционирование системы в целом.
Организацию оперативной памяти.
Состав внешних устройств, их адреса и форматы регистров.
Организацию и функционирование процессора, состав и формат его регистров, способы адресации системы команд.
Систему прерываний.
Вычислительная система – совокупность не только аппаратных, но и программных средств, которые также оказывают влияние.
Виды:
•Машинные коды – программа представлена в виде последовательности чисел, являющихся кодами команд процессора, адресами оперативной памяти, номерами регистров процессора и внешних устройств.
•Мнемокоды – вместо чисел позволяли использовать мнемонические (символьные) имена, отражающие смысл выполняемой команды.
•Ассемблер – отличается от мнемокодов обширным набором директив транслятора, существенно упрощающих процесс кодирования программы в виде логически законченных элементов.
•Макроассемблеры – расширение ассемблера за счет включения макросредств т.е. предоставляет возможность определения и использования новых более мощных команд.
○Высокоуровневые языки:
•Повышение эффективности труда разработчиков за счет абстрагирования от конкретных деталей аппаратного обеспечения
•Снижение уровня зависимости реализации от аппаратного обеспечения.
•Появление трансляторов.
•Высокая переносимость программ.
Высокоуровневый язык программирования — язык программирования, разработанный для быстроты и удобства использования программистом. Основная черта высокоуровневых языков — это абстракция, то есть введение смысловых конструкций, кратко описывающих такие структуры данных и операции над ними, описания которых на машинном коде (или другом низкоуровневом языке программирования) очень длинны и сложны для понимания.
Языки же высокого уровня имитируют естественные языки, используя некоторые слова разговорного языка и общепринятые математические символы. Эти языки более удобны для человека.
Языки высокого уровня делятся на:
процедурные (алгоритмические) (Basic, Pascal, C и др.), которые предназначены для однозначного описания алгоритмов; для решения задачи процедурные языки требуют в той или иной форме явно записать процедуру ее решения;
логические (Prolog, Lisp и др.), которые ориентированы не на разработку алгоритма решения задачи, а на систематическое и формализованное описание задачи с тем, чтобы решение следовало из составленного описания;
объектно-ориентированные (Object Pascal, C++, Java и др.), в основе которых лежит понятие объекта, сочетающего в себе данные и действия над нами.Программа на объектно-ориентированном языке, решая некоторую задачу, по сути описывает часть мира, относящуюся к этой задаче. Описание действительности в форме системы взаимодействующих объектов естественнее, чем в форме взаимодействующих процедур.
Язык высокого уровня - Язык программирования, средства которого обеспечивают описание задачи в наглядном, легко воспринимаемом виде, удобном для программиста. Он не зависит от внутренних машинных кодов ЭВМ любого типа, поэтому программы, написанные на языках высокого уровня, требуют перевода в машинные коды программами транслятора либо интерпретатора. К языкам высокого уровня относят Фортран , ПЛ/1 , Бейсик , Паскаль , Си , Ада и др.
Язык низкого уровня - Язык программирования, предназначенный для определенного типа ЭВМ и отражающий его внутренний машинный код (см. ниже также “машинный язык “, “ машинно-ориентированный язык “ и “ язык ассемблера “).
71. Показатели качества программных средств.
Функциональная пригодность детализируется пригодностью для применения, точностью, защищенностью, способностью к взаимодействию и согласованностью со стандартами и правилами проектирования.
Надежность рекомендуется характеризовать уровнем завершенности (отсутствия ошибок), устойчивостью к ошибкам и перезапускаемостью.
Применимость предлагается описывать понятностью, обучаемостью и простотой использования.
Эффективность рекомендуется характеризовать ресурсной и временной экономичностью.
Сопровождаемость характеризуется удобством для анализа, изменяемостью, стабильностью и тестируемостью.
Переносимость предлагается отражать адаптируемостью, структурированностью, замещаемостью и внедряемостью.
Оценка качества декомпозиции предметной области
• Для оценки качества классов и объектов существуют 5 критериев:
1. Зацепление – степень глубины связи между отдельными модулями. (чем меньше связность тем лучше)
2. Связность – степень взаимодействия между элементами отдельного модуля. (чем крепче связь тем лучше)
3. Достаточность – степень необходимого для реализации логичного и эффективного поведения в классе. (не наполнять лишним функционалом)
4. Полнота – в интерфейсной части класса должны быть учтены все характеристики абстракции. (Не исключать главное)
5. Примитивность - примитивными являются только те операции, которые требуют доступа к внутренней реализации абстракции. (операции внутренние не обращаются к другим классам, дополнение связности)
72. Отношения между классами в объектно-ориентированном программировании.
Ассоциация показывает структурные отношения между объектами-экземплярами класса, т.е. соединения между классами.
Когда класс участвует в ассоциации, он играет в этом отношении определенную роль.
Мощность ассоциации бывает одного из трех типов:
один-к-одному;
один-ко-многим;
многие-ко-многим
Зависимость - это отношение, которое показывает, что изменение в одном классе (независимом) может влиять на другой класс (зависимый), который использует его.
С помощью зависимости уточняют, какая абстракция является клиентом, а какая — поставщиком определенной услуги.
Пунктирная стрелка зависимости направлена от клиента к поставщику.
Агрегация обозначает отношения классов в иерархии «целое/часть». Говорят, что агрегация образует «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, которая обеспечивает пересылку данных между двумя регистрами или между регистром и ячейкой памяти. В некоторых микропроцессорах реализуется пересылка между двумя ячейками памяти, а также групповая пересылка содержимого нескольких регистров в память или их загрузка из памяти.
