
- •Общие сведения
- •Средства разработки
- •Структура программы
- •Алфавит
- •Лексемы
- •1.2. Переменные. Типы данных
- •Простые типы данных
- •Структурированные типы данных
- •1.3. Константы
- •1.4. Операции Арифметические
- •Присваивание
- •1.5. Операторы ветвления и цикла
- •1.6. Функции Описание и вызов
- •Неявно заданные параметры функции
- •Рекурсия
- •Механизм вызова функций, подставляемые функции
- •Перегрузка функций. Параметры по умолчанию
- •1.7. Указатели. Массивы. Строки Обзор
- •Приведение типов
- •Типизированные и нетипизированные указатели
- •Операции над указателями
- •Массивы
- •Многомерные массивы
- •Указатели в качестве параметров функций
- •Указатель на функцию
- •Функции работы с указателями и памятью
- •Строки.
- •1.8. Организация ввода-вывода
- •Форматированный ввод-вывод
- •1.9. Директивы препроцессора
- •1.10. Метки. Безусловный переход
- •1.11. Время жизни и область видимости переменных
- •1. 12. Многофайловые проекты
- •1.13. Введение в объектно-ориентированное программирование
- •2.3. Проблемы разработки сложных программных систем
- •2.4. Жизненный цикл программного продукта
- •Модели жц.
- •Экстремальное программирование
- •2.5. Оценка качества процессов создания программного обеспечения
- •2.6. Проектирование надёжного программного средства
- •2.7. Процессы проектирования
- •2.8. Требования, цели
- •2.9. Внешнее проектирование
- •Диаграммы потоков данных (Data Flow Diagrams).
- •Диаграммы переходов состояний (State Transition Diagrams). Функциональные диаграммы.
- •Описание структур данных
- •2.10. Проектирование архитектуры
- •2.11. Проектирование модульной структуры. Модуль
- •Внешнее проектирование модулей
- •Модульная декомпозиция
- •2.12. Кодирование.
- •2.13. Тестирование
- •2.14. Документирование
- •2.15. Проектирование пользовательского интерфейса
- •Реализация многомерных массивов
- •Очередь и стек
- •Ассоциативные массивы
- •3.3. Упорядоченные структуры данных.
- •Сортировка методом пузырька
- •Быстрая сортировка
- •3.4. Деревья
- •Бинарное дерево
- •Обход дерева
- •3.5. Множества, графы Множества
- •3.6. Строки Константные строки
- •Списковое представление строк
- •Представление массива строк
- •3.7. Библиотека stl
- •3.8. Реализация некоторых структур данных Реализация двусвязанного списка.
- •Реализация массива переменного размера:
- •Примеры программ
- •Список литературы
1.10. Метки. Безусловный переход
Идентификатор с последующим двоеточием является меткой. Метка является адресом оператора, следующего за меткой. Используется в операторах switch и goto. Областью видимости метки является функция, то есть переход может быть осуществлен только внутри функции, а в разных функциях имена меток могут повторяться. Более того, метки имеют независимое пространство имен, то есть имя метки может повторять имя другого объекта, при этом компилятор их будет различать.
Пример:
int s=0, i=0;
l1: s+=i++;
if (i<100) goto l1;
Дополнительные средства организации безусловного перехода, позволяющие производить переход, в том числе, между функциями, определены в библиотеке stdjmp.h.
1.11. Время жизни и область видимости переменных
В языках С / С++, как и в большинстве остальных ЯВУ есть три класса переменных.
1. Статические. Статическими являются переменные, объявленные вне какой-либо функции, а также объявленные внутри функций и классов с использованием служебного слова static. Такие переменные создаются при запуске программы, уничтожаются при её завершении и доступны из любой функции программы.
2. Автоматические. Это все переменные, объявленные внутри какой-либо функции (кроме объявленных с использованием слова static). Такие переменные создаются при их объявлении и уничтожаются при выходе за пределы операторных скобок фрагмента программы, в котором они определены. Эти переменные размещаются в стеке. Поэтому максимальный размер всех автоматических переменных ограничен размером выделенного стека, на это следует обращать внимание при создании больших автоматический массивов.
3. Динамические. Это переменные, созданные с помощью специальных функций (malloc, calloc и др.) или операций (new, new[]). Временем жизни таких переменных управляет программист. Область видимости определяется доступностью указателей. Такие переменные расположены как правило в «куче» (heap). В Ms Windows при завершении приложения все динамические переменные также уничтожаются в связи с уничтожением кучи, связанной с данным приложением.
Пример (С++).
int main()
{
char a = 5;
…
{
int b = a + 5; //здесь a существует и доступно
…
} //уничтожена переменная b
short c;
c = a + b; // ошибка, т.к. b уже не существует
for(int i = 0;i<10;i++) {…}
c = i; //ошибка, i существует только в теле цикла for
int i=0; //переменная может быть объявлена, т.к. i объявленная выше уже не существует
for(;i<10;i++) {…}
c = i; //допустимо, т.к. i объявлено в этом же блоке
i = 10;
{
int i = 3; //допустимо, перекрывает видимость i, объявленной ранее
…
}
// здесь i=10;
} //уничтожены переменные a,c,i
1. 12. Многофайловые проекты
1.13. Введение в объектно-ориентированное программирование
Объе́ктно-ориенти́рованное программи́рование (ООП) — парадигма программирования, в которой основными концепциями являются понятия объектов и классов.
Класс — это тип, описывающий устройство объектов. Понятие «класс» подразумевает некоторое поведение и способ представления. Понятие «объект» подразумевает нечто, что обладает определённым поведением и способом представления. Говорят, что объект — это экземпляр класса.
Абстракция данных
Объекты представляют собою упрощенное, идеализированное описание реальных сущностей предметной области. Если соответствующие модели адекватны решаемой задаче, то работать с ними оказывается намного удобнее, чем с низкоуровневым описанием всех возможных свойств и реакций объекта.
– Инкапсуляция — это принцип, согласно которому любой класс должен рассматриваться как чёрный ящик — пользователь класса должен видеть и использовать только интерфейсную часть класса (т. е. список декларируемых свойств и методов класса) и не вникать в его внутреннюю реализацию. Поэтому данные принято инкапсулировать в классе таким образом, чтобы доступ к ним по чтению или записи осуществлялся не напрямую, а с помощью методов. Принцип инкапсуляции (теоретически) позволяет минимизировать число связей между классами и, соответственно, упростить независимую реализацию и модификацию классов.
– Сокрытие данных — неотделимая часть ООП, управляющая областями видимости. Является логическим продолжением инкапсуляции. Целью сокрытия является невозможность для пользователя узнать или испортить внутреннее состояние объекта.
– Наследованием называется возможность порождать один класс от другого с сохранением всех свойств и методов класса-предка (прародителя, иногда его называют суперклассом) и добавляя, при необходимости, новые свойства и методы. Набор классов, связанных отношением наследования, называют иерархией. Наследование призвано отобразить такое свойство реального мира, как иерархичность.
– Полиморфизмом называют явление, при котором функции (методу) с одним и тем же именем соответствует разный программный код (полиморфный код) в зависимости от того, объект какого класса используется при вызове данного метода. Полиморфизм обеспечивается тем, что в классе-потомке изменяют реализацию метода класса-предка с обязательным сохранением сигнатуры метода. Это обеспечивает сохранение неизменным интерфейса класса-предка и позволяет осуществить связывание имени метода в коде с разными классами — из объекта какого класса осуществляется вызов, из того класса и берётся метод с данным именем. Такой механизм называется динамическим (или поздним) связыванием — в отличие от статического (раннего) связывания, осуществляемого на этапе компиляции.
С++
Класс состоит из полей (данных) и методов (функций). То есть класс в простейшем понимании – это структура данных (struct), дополненная функциями их обработки.
Пример.
class A
{
public:
double x,y,z;
double sum() {return x+y+z;}
} ;
Поля и методы, описанные в секции «public» доступны для доступа из вне класса.
A a;
a.x = 5.2; a.y = 7.4; a.z = 8;
double t = a.sum();
Существуют специальные методы: конструктор (вызывается при создании экземпляра класса) и деструктор (вызывается при уничтожении объекта). Имя конструктора совпадает с именем класса. Имя деструктора – имя класса, перед которым стоит символ «~» (тильда). Возвращаемый тип для конструктора и деструктора не указывается.
Пример.
class String
{
private:
char *text;
public:
String(int len) {text = new char[len];}
~String() {delete [] text;}
…
};
Поля и методы, описанные в секции «private» не доступны из вне класса.
Создание объекта класса происходит аналогично объявлению переменной:
String t(10); //требуется указывать размер строки, т.к. определен конструктор с параметром
int y = strlen(t.text); // вызовет ошибку, т.к. text – закрытое поле
Перегрузка функций – позволяет создавать функции с одинаковым названием, но различными аргументами. Компилятор сам выбирает подходящую функцию по фактическим аргументам
Перегрузка операций – позволяет переопределять операции для конкретных классов.
Более подробно объектно-ориентированное программирование в данном курсе не рассматривается.
Пример реализации массива из п. 1.12 с использованием классов приведен в приложении.
1.14. Примеры программ
Часть 2. Введение в технологию программирования.
2.1 Понятие технологии программирования
Технология программирования – совокупность методов и средств, используемых в процессе разработки программных средств.
Технология программирования включает:
– указание последовательности выполнения технологических операций;
– перечисление условий, при которых выполняется операция;
– описание самих операций;
– способы описания моделей, используемых на различных этапах разработок.
2.2. Этапы развития программирования
1. Стихийное программирование (до сер. 60-х годов):
– программирование в двочиных кодах;
– появление ассемблеров;
– появление ЯВУ (Fortran, Algol);
– появление подпрограмм, работающих с глобальными данными);
– локализация данных в подпрограммах;
– стихийное использование подхода «снизу-вверх», сложные интерфейсы функций.
2. Структурное программирование (сер. 60 – сер. 80):
В основе СП лежит декомпозиция сложных систем. Процедурная декомпозиция – разбиение на подпрограммы (несколько десятков операторов).
– проектирование «сверху вниз»;
– использование 3 базовых алгоритмических конструкций (следование, ветвление, цикл);
– структурирование данных, пользовательские типы;
– модульное программирование – выделение группы подпрограмм, использующих одни данные, в отдельно компилируемые модули.
Языки: PL/1, Algol-68, Pascal, C.
3. Объектный подход (сер. 80 – конец 90).
– представление программы в виде совокупности объектов, которые являются экземплярами определённого класса;
– классы образуют иерархию с наследованием свойств;
– система сообщений;
– ООП обеспечивает более естественную декомпозицию ПО, что реализует наиболее полную локализацию данных и позволяет вести независимую разработку классов;
– визуальное программирование.
Примеры языков: Simula, Smalltalk, C++, Modula, Java, Object Pascal.
4. Компонентный подход и CASE-технологии.
– построение программного обеспечения из отдельных компонентов – отдельно существующих частей ПО, взаимодействующих между собой через стандартизованные двоичные интерфейсы;
– компоненты собираются в двоичные библиотеки или исполняемые файлы;
Примеры:
COM (Component Object Model) – определяет общую парадигму взаимодействия программ любых типов, позволяя одному программному обеспечению использовать функции (службы), предоставляемые другой.
Объекты COM функционируют в составе сервера: внутреннего, локального, удалённого.
На его основе построены OLE-Automation и ActiveX.
CORBA (Common Object Request Broker Architecture).
CASE-технологии (Computer-Aided Software/System Engineering) – автоматизированные технологии разработки и сопровождения ПО.