- •Издано в рамках Инновационной образовательной программы ннгу: Образовательно-научный центр «Информационно-телекоммуникационные системы: физические основы и математическое обеспечение»
- •Глава 1. Основные понятия 13
- •Глава 3. Работа с числовыми данными 42
- •Глава 4. Операторы. Ключевые слова 52
- •Глава 5. Управление и циклы 64
- •Глава 6. Массивы 77
- •Глава 7. Функции 84
- •Глава 8. Символы и строки 102
- •Глава 9. Препроцессор 113
- •Глава 10. Указатели и ссылки 119
- •Глава 11. О файлах и командной строке 133
- •Глава 12. Работа с экраном дисплея 145
- •Глава 13. Внутреннее представление чисел 157
- •Глава 14. Структуры, перечисления, объединения 179
- •Глава 15. Классы 204
- •Глава 16. Программы из нескольких файлов 233
- •Глава 21. Шаблоны, исключения 321
- •Предисловие
- •Глава 1.Основные понятия
- •1.1.Элементы языка программирования
- •Алфавит
- •Лексемы
- •Выражения
- •Функции
- •Комментарии
- •1.2.Процесс создания программы
- •1.3.Первая программа Программа 1. Приветствие
- •1.4.Состав программы
- •Загрузка
- •Работа с окнами
- •Настройка среды
- •Указание каталогов библиотек
- •Подключение графической библиотеки
- •Назначение текущего каталога
- •Работа с блоками текста в редакторе
- •Выполнение программы
- •Отладка программ
- •Программа 2. Деление чисел
- •Синтаксические ошибки
- •Ошибки в процессе работы программы
- •Трассировка программ
- •Просмотр текущих значений выражений
- •Разработка консольных приложений
- •Программа 3. Hello
- •Выполнение и отладка программы
- •Файлы проекта
- •Автоматическая генерация кода
- •Особенности ввода и вывода
- •Глава 3.Работа с числовыми данными
- •3.1.Целые типы
- •Целые константы
- •Программа 4. Операции над целыми
- •3.2.Числа с плавающей точкой
- •Плавающие константы
- •3.3.Ввод и вывод чисел
- •Программа 5. Точность плавающих чисел
- •3.4.Логический тип и логические операции
- •3.5.Математические функции
- •Глава 4.Операторы. Ключевые слова
- •4.1.Операторы
- •Унарные операторы
- •Бинарные операторы
- •Оператор запятая
- •Условное выражение
- •Операторы присваивания
- •4.2.Приоритеты операторов
- •4.3.Ключевые слова
- •Продолжение таблицы 23. Ключевые слова стандарта языка Cи
- •4.4.Структура программы
- •Объявления переменных
- •Объявления и определения
- •Инструкции и блоки
- •4.5.Константы
- •Задачи 1-17 . Простейшие вычисления
- •Глава 5.Управление и циклы
- •5.1.Условный оператор
- •Программа 6. Максимальное из двух чисел
- •5.2.Операторы цикла
- •Цикл с предусловием while
- •Программа 7. Суммирование цифр целого
- •Цикл for
- •Программа 8. Поиск максимума и минимума
- •Цикл do-while
- •Программа 9. Вычисление квадратного корня
- •5.3.Переключатель
- •Программа 10. День недели
- •5.4.Операторы break и continue
- •Программа 11. Сумма положительных чисел
- •Задачи 18-52. Выбор и циклы
- •Глава 6.Массивы
- •6.1.Одномерные массивы
- •Программа 12. Проверка упорядоченности массива
- •6.2.Двумерные массивы
- •Программа 13. Подсчет выручки
- •Задачи 53-69. Одно- и двумерные массивы
- •Глава 7.Функции
- •7.1.Определение функции
- •7.2.Формальные параметры и фактические аргументы
- •Пpограмма.14. Степени целых чисел
- •7.3.Автоматические и статические переменные
- •Программа 15. Автоматические и статические переменные
- •7.4.Прототипы функций
- •7.5.Массивы как аргументы функций
- •7.6.Внешние переменные
- •Программа 16. Сортировка массива
- •7.7.Рекурсия
- •Программа 17. Рекурсивная печать целого
- •7.8.Перегруженные имена функций
- •Программа 18. Перегрузка функций
- •7.9.Аргументы функций по умолчанию
- •Программа 19. Аргументы по умолчанию
- •Задачи 70-96. Функции
- •Глава 8.Символы и строки
- •8.1.Символы
- •Символьные константы
- •Программа 20. Представления символов
- •Ввод и вывод символов
- •Программа 22. Печать текста по словам
- •8.2.Строки символов
- •Строковые константы
- •Ввод и вывод строк
- •Средства работы со строками
- •Программа 23. Реверсирование строк
- •Задачи 97-121. Символы и строки
- •Глава 9.Препроцессор
- •9.1.Директивы препроцессора
- •9.2.Макросы
- •Программа 24. Возможности препроцессора
- •Задачи 122-124. Макросы
- •Глава 10.Указатели и ссылки
- •10.1.Указатели и адреса
- •Программа 25. Расчет треугольника
- •10.2.Указатели и массивы
- •10.3.Адресная арифметика
- •10.4.Символьные указатели
- •10.5.Массивы указателей
- •Программа 26. Названия месяцев
- •10.6.Указатели на функции
- •Программа 27. Поиск максимума функции
- •10.7.Ссылки
- •Программа 28. Использование ссылок
- •10.8.Операторы new и delete
- •Программа 29. Выделение и освобождение памяти
- •Задачи 125-134. Указатели и ссылки
- •Глава 11.О файлах и командной строке
- •11.1.Знакомство с файлами
- •Программа 30. Копирование файлов
- •11.2.Командная строка
- •11.3.Перенаправление стандартного ввода и вывода на файл
- •11.4.Аргументы командной строки
- •Программа 31. Эхо аргументов командной строки
- •Программа 32. Печать строк, содержащих образец
- •Задачи 135-147. Файлы и командная строка
- •Глава 12.Работа с экраном дисплея
- •12.1.Текстовый режим
- •Программа 33. Российский флаг
- •12.2.Графический режим
- •Графические драйверы и режимы
- •Инициализация графики
- •Функции рисования
- •Программа 34. Звезда
- •Задачи 148-158. Работа с экраном
- •Глава 13.Внутреннее представление чисел
- •13.1.Двоичная система счисления
- •13.2.Беззнаковые целые
- •13.3.Двоичный дополнительный код
- •13.4.Двоичный код с избытком
- •13.5.Побитовые операторы
- •Программа 35. Побитовые операторы
- •13.6.Дробные числа в двоичной системе
- •13.7. Внутреннее представление плавающих типов
- •13.8.Преобразование типов
- •Значения логических выражений
- •Арифметические преобразования
- •Преобразование при присваивании
- •Явное приведение типа
- •Задачи 159-166. Побитовые операторы
- •Глава 14.Структуры, перечисления, объединения
- •14.1.Объявление структур
- •14.2.Структуры и функции
- •14.3.Указатели на структуры
- •Программа 36. Точки и прямоугольники на экране
- •14.4.Массивы структур
- •Программа 37. Подсчет ключевых слов
- •14.5.Перечисления
- •Программа 38. Использование перечислений
- •14.6. Объединения
- •Программа 39. Внутреннее представление float
- •14.7.Битовые поля
- •14.8.О бинарных файлах
- •Программа 40. Анализ успеваемости
- •Задачи 167-174. Структуры
- •Глава 15.Классы
- •Программа 41. Время как структура
- •15.2.Встроенные функции
- •15.3.Классы. Скрытие данных
- •Программа 42. Класс дат
- •15.4.Конструкторы
- •Программа 43. Конструкторы в классе дат
- •15.5.Статические члены класса
- •Программа 44. Размер класса и объектов класса
- •15.6.Друзья класса
- •Программа 45. Статические члены и друзья класса
- •15.7.Копирование объектов класса
- •Программа 46. Копирование объектов
- •15.8.Управление доступом
- •Структуры и классы
- •Правила доступа
- •15.9.Ссылка на себя
- •Программа 47. Модификация дат
- •15.10.Деструкторы
- •Программа 48. Деструктор в классе дат
- •Программа 49. Многоугольники
- •Задачи 175-185. Работа с классами
- •Глава 16.Программы из нескольких файлов
- •16.1.Работа с проектами
- •16.2.Область действия имен
- •Программа 50. Глобальные и локальные имена
- •Статические имена
- •Программа 51. Сумматор чисел
- •16.3.Заголовочные файлы
- •Страж включения
- •Понятие стека
- •Программа 52. Реализация стека в виде массива
- •16.4.Пространства имен
- •Стандартные пространства имен
- •Задачи 186-189. Работа со стеком
- •Глава 17.Перегрузка операторов
- •Программа 53. Обыкновенные дроби
- •17.1.Правила перегрузки операторов
- •Программа 54. Комплексные числа
- •Задачи 190-196. Перегрузка операторов
- •Глава 18.Конструктор копирования и оператор присваивания
- •18.1.Проблемы при копировании
- •Программа 55. Вектора на плоскости
- •Задачи 197-198. Конструктор копирования
- •Глава 19.Ввод и вывод
- •19.1.Вывод
- •19.2.Ввод
- •19.3.Ввод и вывод определяемых пользователем типов
- •Программа 56. Перегрузка операторов ввода/вывода
- •19.4.Работа с файлами
- •Программа 57. Сравнение текстового и бинарного файлов
- •Задачи 199-202. Ввод и вывод
- •Глава 20.Взаимоотношения классов
- •20.1.Объекты как члены класса
- •20.2.Конструкторы встроенных типов
- •Программа 58. Личные данные
- •20.3.Наследование
- •Пример наследования
- •Программа 59. Наследование
- •Управление доступом при наследовании
- •Наследование и конструкторы
- •Программа 60. Производный класс личных данных
- •20.4. Виртуальные функции
- •Программа 61. Невиртуальные функции
- •Программа 62. Виртуальные функции
- •20.5.Абстрактные классы
- •Программа 63. Абстрактный класс фигур
- •Вызов виртуальных функций
- •20.6. Совместимость типов
- •20.7.Множественное наследование
- •Программа 64. Системы уравнений Класс алгебраических векторов Vector
- •Класс прямоугольных матриц
- •Объявление класса Matrix
- •Реализация класса Matrix
- •Класс систем линейных уравнений
- •Пример использования классов
- •Задачи 203-212. Наследование классов
- •Глава 21.Шаблоны, исключения
- •21.1.Шаблоны
- •21.2.Шаблоны функций
- •Программа 65. Объявление и определение шаблона функции
- •21.3.Классы и шаблоны
- •Программа 66. Шаблон классов векторов
- •Программа 67. Шаблон классов динамических массивов
- •21.4.Обработка исключений
- •Программа 68. Расчет нод
- •21.5.Стандартная библиотека шаблонов
- •Программа 69. Использование шаблона векторов
- •Литература
- •Предметный указатель
- •603950, Н. Новгород, пр. Гагарина, 23
- •603000, Н. Новгород, ул. Б. Покровская, 37.
15.10.Деструкторы
В конструкторах при создании объектов могут захватываться некоторые ресурсы, например, выделяться память, открываться файлы и т. п. При уничтожении объектов ресурсы должны освобождаться. Эту работу выполняют специальные функции-члены класса – деструкторы.
Имя деструктора совпадает с именем класса, только впереди добавляется знак ~ (тильда). Деструктор не имеет аргументов, и так же, как и конструктор, ничего не возвращает.
Деструкторы вызываются неявно, когда автоматическая переменная выходит из зоны видимости, когда оператором delete удаляется объект, созданный в свободной памяти оператором new.
Программа 48. Деструктор в классе дат
В классе дат деструктор не нужен, так как при создании переменных типа Date никакие ресурсы не выделяются, кроме памяти под d, m, y. При уничтении переменной типа Date, занимаемая ею память освобождается встроенными средствами. Можно сказать, что при этом работает деструктор по умолчанию.
Включим все-таки в класс Date деструктор, который будет лишь сигнализировать о своей работе.
// Файл DateCl_7.cpp
class Date{
int d, m, y; // День, месяц и год
// …
public:
Date(int = 0, int = 0, int = 0); // Конструктор
~Date(); // Деструктор
// …
};
// Реализация деструктора
Date::~Date()
{
cout << ”\nРаботает деструктор для ”; // Сообщаем о себе,
Print(); // выводим дату
}
int main()
{
Date Today; // Сегодня
{ // Начало блока
Date Rev(7, 11, 1917); // Создание локальной переменной в блоке
} // Конец блока. Rev уничтожается
return 0;
} // Здесь уничтожается Today
Программа выдает:
Работает деструктор для 7.11.1917
Работает деструктор для 19.4.2006
Данный пример подтверждает, что деструктор действительно вызывается неявно при уничтожении объектов класса.
Программа 49. Многоугольники
В программе разработан класс Plgn для моделирования многоугольников на плоскости. В конструкторе этого класса динамически выделяется память под координаты вершин, а в деструкторе освобождается память, выделенная в конструкторе. В классе предусмотрены функции – члены для изображения многоугольника на экране, для его стирания с экрана, а также для перемещения и вращения многоугольника.
При решении задачи надо решить вопрос о совмещении математической плоскости, с помощью которой мы будем моделировать многоугольник, с физической плоскостью экрана. На рис.69 показана схема экрана и действующая на нем физическая экранная система координат xs, ys. Совместим начало математической системы координат x, y с центром экрана (x0, y0). Будем считать, что математическая плоскость отображается на плоскость экрана в масштабе 1:1, то есть математическая единица длины соответствует расстоянию между соседними пикселями на экране. Приведенные соображения реализованы в программе. В функциях рисования нужны физические координаты пикселей. Переход от математических координат к физическим производится по формулам:
xs = x0 + x, ys = y0 – y.
Знак минус учитывает разное направление вертикальных осей в физической и математической системах координат.
Рис.69. Плоскость экрана и математическая система координат
// Файл Polygon.cpp
class Plgn // Класс многоугольников
{
int n; // Число вершин
float *x; // Указатель на массив абсцисс
float *y; // Указатель на массив ординат
static int x0, y0; // Координаты центра экрана
public:
Plgn(int n = 3); // Конструктор с аргументом по умолчанию
~Plgn(); // Деструктор
void Show(); // Функция рисования многоугольника
void Hide(); // Функция, убирающая изображение
void Move(int dx, int dy); // Смещение многоугольника на dx, dy
void Rotate(float angle); // Поворот на угол angle градусов
void Movement(); // Движение, пока не нажата Esc
static void SetBegCoord(int xn, int yn) // Установка координат центра
{ x0 = xn; y0 = yn; }
};
# include <iostream.h>
# include <graphics.h> // Графика
# include <stdlib.h> // Доступ к random
# include <conio.h>
# include <math.h>
Plgn::Plgn(int nn) // Конструктор
{
n = nn;
x = new float [n]; // Выделение памяти под массив абсцисс
y = new float [n]; // Выделение памяти под массив ординат
for(int i = 0; i < n; i++){ // Заполнение массивов координат
x[i] = x0 - random(x0 * 2); // случайными числами
y[i] = y0 - random(y0 * 2);
}
}
Для простоты координаты вершин многоугольника задаются в конструкторе случайными числами с использованием функции
int random(int num);
которая генерирует случайное целое число из диапазона от 0 до num – 1; Таким образом, случайные координаты вершин многоугольника будут находиться в диапазонах [-x0, x0] и [-y0, y0] и, следовательно, не выйдут за пределы экрана.
Plgn::~Plgn() // Деструктор
{
delete [] x; // Освобождение
delete [] y; // памяти
}
void Plgn::Show() // Рисует многоугольник, рядом
{ // с вершиной выводит ее номер
char num[20]; // Память под номер вершины
for(int i = 0; i < n; i++){
line(x0 + x[i], y0 - y[i], // Изображение
x0 + x[(i + 1) % n], y0 - y[(i + 1) % n]); // i-й стороны
itoa(i, num, 10); // Получение номера вершины
outtextxy(x0 + x[i], y0 - y[i], num); // Вывод номера вершины
}
}
Функция line рисует отрезки, соединяющие соседние вершины. Возле вершин многоугольника выводятся их номера. Для вывода текста на экран в графическом режиме использована функция
void outtextxy(int x, int y, char *textstring);
которая выводит строку символов textstring, начиная с пикселя экрана с координатами x, y.
Для получения строки с номером вершины использована функция (заголовочный файл stdlib.h)
char *ltoa(long value, char *string, int radix);
которая преобразует число value в строку цифр string, дающую представление числа в системе счисления с основанием radix.
void Plgn::Hide() // Стереть изображение
{
int clr = getcolor(); // Запоминаем цвет рисования
setcolor(getbkcolor()); // Цветом рисования делаем цвет фона
Show(); // Рисуем цветом фона, изображение исчезает
setcolor(clr); // Восстанавливаем прежний цвет рисования
}
void Plgn::Move(int dx, int dy) // Смещение многоугольника на dx
{ // по горизонтали и на dy по вертикали
Hide(); // Убираем изображение
for(int i = 0; i < n; i++) // Смещение
x[i] += dx, y[i]+=dy; // каждой вершины
Show(); // Снова показываем многоугольник
}
Выпишем формулы, нужные для программирования поворота многоугольника вокруг центра масс. На рис.70 показан многоугольник и одна из его вершин M в исходном положении и после его поворота вокруг точки C на угол β. Новое положение вершины обозначено M1.
В качестве центра масс можно взять точку C с координатами:
.
Здесь n – число вершин многоугольника, xi, yi, i=1,…, n – координаты вершин. Данная формула действительно будет давать координаты центра масс, если вся масса многоугольника сосредоточена в его вершинах и массы вершин одинаковы.
Как видно из рис.70, координаты точки M относительно центра масс C равны:
.
Рис.70. Поворот многоугольника вокруг центра масс
Так как
,
то относительные координаты точки M1
после поворота выразятся формулами:
Таким образом, новые абсолютные координаты точки M будут:
Эти формулы используются в функции вращения многоугольника:
void Plgn::Rotate(float angle) // Функция поворота многоугольника
{ // на угол angle (задается в градусах)
float xC = 0, yC = 0, xr, yr;
int i;
angle = angle*M_PI/180; // Перевод угла в радианы
Hide(); // Убираем изображение
for(i = 0; i < n; i++){ // Вычисление координат
xC += x[i]; yC += y[i]; // центра масс
}
xC /= n; yC /= n;
for(i = 0; i < n; i++){ // Получение координат вершин после поворота
xr = x[i] - xC; // Координаты вершины
yr = y[i] - yC; // относительно центра масс
x[i] = xC + xr * cos(angle) - yr * sin(angle); // Координаты вершины
y[i] = yC + xr * sin(angle) + yr * cos(angle); // после поворота
}
Show(); // Показываем многоугольник
}
void Plgn::Movement() // Движение при нажатии клавиш
{ // со стрелками, пока не нажата Esc
const int UP = 72, DOWN = 80, LFTUP = 76, // Константы
RIGHT = 77, LEFT = 75, ESC = 27; // для кодов клавиш
char c = 32; // Начальное значение для c должно отличаться от ESC
while(c != ESC){ // Пока не нажата клавиша esc
c = getch(); // Читаем код клавиши
if(c == 0) // Если у клавиши двухбайтовый код,
c = getch(); // читаем второй байт
switch(c){
case LEFT: Move(-1, 0); break; // Нажата стрелка влево
case RIGHT: Move(1, 0); break; // Нажата стрелка вправо
case UP: Move(0, 1); break; // Нажата стрелка вверх
case DOWN: Move(0, -1); break; // Нажата стрелка вниз
case LFTUP: Rotate(5); break;
}
}
}
Перемещение многоугольника производится нажатием клавиш со стрелками. Вращение – нажатием клавиши 5 на дополнительной цифровой клавиатуре. При этом не должна гореть лампочка NumLock, чтобы клавиши дополнительной цифровой клавиатуры работали как управляющие, а не как цифровые.
// Определение статических членов класса – координат центра экрана
int Plgn::x0, Plgn::y0;
void main()
{
int gd = DETECT, gmode, n, x;
char c;
randomize(); // Инициализация датчика случайных чисел
initgraph(&gd, &gmode, "C:\\TC30\\BGI"); // Установка граф. режима
// Задаем координаты центра экрана
Plgn::SetBegCoord(getmaxx() / 2, getmaxy() / 2);
cout << "Введите число вершин: ";
cin >> n; // Ввод числа вершин
Plgn mnog(n); // Многоугольник
setcolor(WHITE); // Установка цвета
mnog.Show(); // Вывод многоугольника
mnog.Movement(); // Перемещения многоугольника
mnog.Hide(); // Убираем многоугольник
Plgn triangle; // Многоугольник по умолчанию (треугольник)
triangle.Show(); // Показываем треугольник
triangle.Movement(); // Движение треугольника
triangle.Hide(); // Скрываем треугольник
closegraph(); // Переход в текстовый режим
}
Вызов статической функции
Plgn::SetBegCoord(getmaxx() / 2, getmaxy() / 2);
устанавливает для статических членов класса Plgn::x0, Plgn::y0 значения координат центра экрана.
В главной функции сначала создается многоугольник mnog, число вершин которого следует ввести. Затем для mnog вызывается функция Movement, которая позволяет его двигать и вращать. Далее создается треугольник triangle с использованием конструктора по умолчанию. Треугольником также можно «поиграть».
Для чтения кодов нажимаемых клавиш использована функция int getch() (заголовочный файл conio.h), которая возвращает для обычных алфавитно-цифровых клавиш однобайтовый код, равный коду соответствующего символа, а для управляющих и функциональных клавиш – двухбайтовый код. Для таких клавиш при первом вызове getch() возвращает 0, а при втором – некоторый код, свой для каждой клавиши. Коды, возвращаемые getch(), можно узнать с помощью программы:
// Файл CodeKeys.cpp
// Получение кодов клавиш функцией getch()
#include <iostream.h>
#include <conio.h>
void main()
{
cout << "\nНажмите клавишу\n";
int c = getch();
if(0 == c){
c = getch();
cout << "\nУ клавиши двухбайтовый код: 0 " << c << endl;
}
else
cout << "\nУ клавиши однобайтовый код: " << c ;
getch();
}
