
- •Лекция 1 Основы алгоритмизации
- •1.1 Языки программирования
- •1.2 Этапы решения задач на компьютере
- •1.3 Понятие алгоритма и его свойства
- •1.4 Графическое описание алгоритмов. Схемы алгоритмов
- •Блоки для изображения схем алгоритмов и программ
- •1.5 Типы алгоритмов
- •Лекция 2 Начальные сведения о языке
- •2.3 Компиляция и выполнение программы
- •Лекция 3 Имена, переменные и константы
- •3.1 Имена
- •3.2 Переменные
- •3.3 Константы
- •Лекция 4 Операции и выражения
- •4.1 Выражения
- •4.2 Операция присваивания
- •4.3.1 Арифметические операции
- •4.3.2 Операции сравнения
- •4.4 Порядок вычисления выражений
- •Лекция 5 Операторы
- •5.1 Что такое оператор
- •5.1.1 Операторы-выражения
- •5.1.2 Объявления имен
- •5.1.3 Операторы управления
- •5.1.3.1 Условные операторы
- •5.1.3.2 Операторы цикла
- •5.1.3.3 Оператор возврата
- •5.1.3.4 Оператор перехода
- •Лекция 6 Функции
- •6.1 Вызов функций
- •6.2 Имена функций
- •6.3 Необязательные аргументы функций
- •6.4 Рекурсия
- •Лекция 7 Встроенные типы данных
- •7.1 Общая информация
- •7.2 Целые числа
- •7.3 Вещественные числа
- •7.4 Логические величины
- •7.5 Символы и байты
- •7.6 Кодировка, многобайтовые символы
- •7.7 Наборы перечисляемых значений
- •Лекция 8 Классы и объекты
- •8.1 Понятие класса
- •8.2 Определение методов класса
- •8.3 Переопределение операций
- •8.4 Подписи методов и необязательные аргументы
- •8.4.1 Запись классов
- •Лекция 9 Производные типы данных
- •9.1 Массивы
- •9.2 Структуры
- •9.2.1 Битовые поля
- •9.3 Объединения
- •9.4 Указатели
- •9.4.1 Адресная арифметика
- •9.4.2 Связь между массивами и указателями
- •9.4.3 Бестиповый указатель
- •9.4.4 Нулевой указатель
- •9.5 Строки и литералы
- •Лекция 10 Распределение памяти
- •10.1 Автоматические переменные
- •10.2 Статические переменные
- •10.3 Динамическое выделение памяти
- •10.4 Выделение памяти под строки
- •10.5 Рекомендации по использованию указателей и динамического распределения памяти
- •10.6 Ссылки
- •10.6 Распределение памяти при передаче аргументов функции
- •10.6.1 Рекомендации по передаче аргументов
- •Лекция 11 Производные классы, наследование
- •11.1 Виртуальные методы
- •11.1.1 Виртуальные методы и переопределение методов
- •11.2 Преобразование базового и производного классов
- •11.3 Внутреннее и защищенное наследование
- •11.4 Абстрактные классы
- •11.5 Множественное наследование
- •11.5.1 Виртуальное наследование
- •15.2 Проблема использования общих функций и имен
- •15.3 Использование включаемых файлов
- •15.4 Препроцессор
- •15.4.1 Определение макросов
- •Условная компиляция
- •15.4.2 Дополнительные директивы препроцессора
- •Лекция 16 Определение, время жизни и области видимости переменных в больших программах
- •16.1 Файлы и переменные
- •16.1.1 Общие данные
- •16.1.2 Глобальные переменные
- •16.1.3 Повышение надежности обращения к общим данным
- •16.2 Область видимости имен
- •16.3 Оператор определения контекста namespace
- •Лекция 17 Обработка ошибок
- •17.1 Виды ошибок
- •17.2 Возвращаемое значение как признак ошибки
- •17.3 Исключительные ситуации
- •17.3.1 Обработка исключительных ситуаций
- •17.3.2 Примеры обработки исключительных ситуаций
- •Лекция 18 Bвод-вывод
- •18.1 Потоки
- •18.3 Манипуляторы и форматирование ввода-вывода
- •18.4 Строковые потоки
- •18.5 Ввод-вывод файлов
- •Лекция 19 Шаблоны
- •19.1 Назначение шаблонов
- •19.2 Функции-шаблоны
- •19.3 Шаблоны классов
- •19.3.1 "Интеллигентный указатель"
- •19.3.2 Задание свойств класса
- •Список использованных источников
- •Содержание
9.2 Структуры
Структуры – это не что иное, как классы, у которых разрешен доступ ко всем их элементам (доступ к определенным атрибутам класса может быть ограничен, о чем мы узнаем в лекции 11). Пример структуры:
struct Record {
int number;
char name[20];
};
Так же, как и для классов, операция "." обозначает обращение к элементу структуры.
В отличие от классов, можно определить переменную-структуру без определения отдельного типа:
struct {
double x;
double y;
} coord;
Обратиться к атрибутам переменной coord можно coord.x и coord.y.
9.2.1 Битовые поля
В структуре можно определить размеры атрибута с точностью до бита. Традиционно структуры используются в системном программировании для описания регистров аппаратуры. В них каждый бит имеет свое значение. Не менее важной является возможность экономии памяти – ведь минимальный тип атрибута структуры это байт (char), который занимает 8 битов. До сих пор, несмотря на мегабайты и даже гигабайты оперативной памяти, используемые в современных компьютерах, существует немало задач, где каждый бит на счету.
Если после описания атрибута структуры поставить двоеточие и затем целое число, то это число задает количество битов, выделенных под данный атрибут структуры. Такие атрибуты называют битовыми полями. Следующая структура хранит в компактной форме дату и время дня с точностью до секунды.
struct TimeAndDate
{
unsigned hours :5; // часы от 0 до 24
unsigned mins :6; // минуты
unsigned secs :6; // секунды от 0 до 60
unsigned weekDay :3; // день недели
unsigned monthDay :6; // день месяца от 1 до 31
unsigned month :5; // месяц от 1 до 12
unsigned year :8; // год от 0 до 100
};
Одна структура TimeAndDate требует всего 39 битов, т.е. 5 байтов (один байт — 8 битов). Если бы мы использовали для каждого атрибута этой структуры тип char, нам бы потребовалось 7 байтов.
9.3 Объединения
Особым видом структур данных является объединение. Определение объединения напоминает определение структуры, только вместо ключевого слова struct используется union:
union number {
short sx;
long lx;
double dx;
};
В отличие от структуры, все атрибуты объединения располагаются по одному адресу. Под объединение выделяется столько памяти, сколько нужно для хранения наибольшего атрибута объединения. Объединения применяются в тех случаях, когда в один момент времени используется только один атрибут объединения и, прежде всего, для экономии памяти. Предположим, нам нужно определить структуру, которая хранит "универсальное" число, т.е. число одного из предопределенных типов, и признак типа. Это можно сделать следующим образом:
struct Value {
enum NumberType { ShortType, LongType,
DoubleType };
NumberType type;
short sx; // если type равен ShortType
long lx; // если type равен LongType
double dx; // если type равен DoubleType
};
Атрибут type содержит тип хранимого числа, а соответствующий атрибут структуры – значение числа.
Value shortVal;
shortVal.type = Value::ShortType;
shortVal.sx = 15;
Хотя память выделяется под все три атрибута sx, ls и dx, реально используется только один из них. Сэкономить память можно, используя объединение:
struct Value {
enum NumberType { ShortType, LongType,
DoubleType };
NumberType type;
union number {
short sx;
long lx;
double dx;
} val;
}; // если type равен ShortType
// если type равен LongType
// если type равен DoubleType
Теперь память выделена только для максимального из этих трех атрибутов (в данном случае dx). Однако и обращаться с объединением надо осторожно. Поскольку все три атрибута делят одну и ту же область памяти, изменение одного из них означает изменение всех остальных. На рисунке поясняется выделение памяти под объединение. В обоих случаях мы предполагаем, что структура расположена по адресу 1000. Объединение располагает все три своих атрибута по одному и тому же адресу.
Замечание. Объединения существовали в языке Си, откуда без изменений и перешли в C++. Использование наследования классов, описанное в следующей главе, позволяет во многих случаях добиться того же эффекта без использования объединений, причем программа будет более надежной.
Рис.
9.1. Использование памяти в
объединениях.