- •Предисловие
- •Глава 1. Основные понятия
- •1.1. Элементы языка программирования
- •1.2. Процесс создания программы
- •1.3. Первая программа
- •1.4. Состав программы
- •Глава 2. Средства разработки на C++
- •2.1. Системы Turbo C++ 3.0/Borland C++ 3.1
- •2.2. Система C++ Builder
- •Глава 3. Работа с числовыми данными
- •3.1. Целые типы
- •3.2. Числа с плавающей точкой
- •3.3. Ввод и вывод чисел
- •3.4. Логический тип и логические операции
- •3.5. Математические функции
- •Глава 4. Операторы. Ключевые слова
- •4.1. Операторы
- •4.2. Приоритеты операторов
- •4.3. Ключевые слова
- •4.4. Структура программы
- •4.5. Константы
- •Задачи - . Простейшие вычисления
- •Глава 5. Управление и циклы
- •5.1. Условный оператор
- •5.2. Операторы цикла
- •5.3. Переключатель
- •5.4. Операторы break и continue
- •Задачи -. Выбор и циклы
- •Глава 6. Массивы
- •6.1. Одномерные массивы
- •6.2. Двумерные массивы
- •Задачи -. Одно- и двумерные массивы
- •Глава 7. Функции
- •7.1. Определение функции
- •7.2. Формальные параметры и фактические аргументы
- •7.3. Автоматические и статические переменные
- •7.4. Прототипы функций
- •7.5. Массивы как аргументы функций
- •7.6. Внешние переменные
- •7.7. Рекурсия
- •7.8. Перегруженные имена функций
- •7.9. Аргументы функций по умолчанию
- •Задачи -. Функции
- •Глава 8. Символы и строки
- •8.1. Символы
- •8.2. Строки символов
- •Задачи -. Символы и строки
- •Глава 9. Препроцессор
- •9.1. Директивы препроцессора
- •9.2. Макросы
- •Задачи -. Макросы
- •Глава 10. Указатели и ссылки
- •10.1. Указатели и адреса
- •10.2. Указатели и массивы
- •10.3. Адресная арифметика
- •10.4. Символьные указатели
- •10.5. Массивы указателей
- •10.6. Указатели на функции
- •10.7. Ссылки
- •10.8. Операторы new и delete
- •Задачи -. Указатели и ссылки
- •Глава 11. О файлах и командной строке
- •11.1. Знакомство с файлами
- •11.2. Командная строка
- •11.3. Перенаправление стандартного ввода и вывода на файл
- •11.4. Аргументы командной строки
- •Задачи -. Файлы и командная строка
- •Глава 12. Работа с экраном дисплея
- •12.1. Текстовый режим
- •12.2. Графический режим
- •Задачи -. Работа с экраном
- •Глава 13. Внутреннее представление чисел
- •13.1. Двоичная система счисления
- •13.2. Беззнаковые целые
- •13.3. Двоичный дополнительный код
- •13.4. Двоичный код с избытком
- •13.5. Побитовые операторы
- •13.6. Дробные числа в двоичной системе
- •13.7. Внутреннее представление плавающих типов
- •13.8. Преобразование типов
- •Задачи -. Побитовые операторы
- •Глава 14. Структуры, перечисления, объединения
- •14.1. Объявление структур
- •14.2. Структуры и функции
- •14.3. Указатели на структуры
- •14.4. Массивы структур
- •14.5. Перечисления
- •14.6. Объединения
- •14.7. Битовые поля
- •14.8. О бинарных файлах
- •Задачи -. Структуры
- •Глава 15. Классы
- •15.1. Структуры в C++. Инкапсуляция
- •15.2. Встроенные функции
- •15.3. Классы. Скрытие данных
- •15.4. Конструкторы
- •15.5. Статические члены класса
- •15.6. Друзья класса
- •15.7. Копирование объектов класса
- •15.8. Управление доступом
- •15.9. Ссылка на себя
- •15.10. Деструкторы
- •Задачи -. Работа с классами
- •Глава 16. Программы из нескольких файлов
- •16.1. Работа с проектами
- •16.2. Область действия имен
- •16.3. Заголовочные файлы
- •16.4. Пространства имен
- •Задачи -. Работа со стеком
- •Глава 17. Перегрузка операторов
- •17.1. Правила перегрузки операторов
- •Задачи -. Перегрузка операторов
- •Глава 18. Конструктор копирования и оператор присваивания
- •18.1. Проблемы при копировании
- •Задачи -. Конструктор копирования
- •Глава 19. Ввод и вывод
- •19.1. Вывод
- •19.2. Ввод
- •19.3. Ввод и вывод определяемых пользователем типов
- •19.4. Работа с файлами
- •Глава 20. Взаимоотношения классов
- •20.1. Объекты как члены класса
- •20.2. Конструкторы встроенных типов
- •20.3. Наследование
- •20.4. Виртуальные функции
- •20.5. Абстрактные классы
- •20.6. Совместимость типов
- •20.7. Множественное наследование
- •Задачи -. Наследование классов
- •Глава 21. Шаблоны, исключения
- •21.1. Шаблоны
- •21.2. Шаблоны функций
- •21.3. Классы и шаблоны
- •21.4. Обработка исключений
- •21.5. Стандартная библиотека шаблонов
- •Литература
- •Предметный указатель
77
Глава 6. Массивы
Массив представляет собой набор последовательно пронумерованных элементов одного типа. Все элементы массива имеют одно имя, но каждый элемент имеет свой номер, с помощью которого отличается от других элементов.
Нумерация элементов массива начинается с нуля.
Впамяти элементы массива располагаются подряд, один за другим.
6.1.Одномерные массивы
При объявлении массива после его имени в квадратных скобках указывается количество элементов, например,
double x[100];
Здесь x – это имя массива из 100 элементов типа double.
При обращение к элементу массива его номер указывается в квадратных скобках.
Так как нумерация элементов массива начинается с нуля, то x[0] есть первый элемент массива, x[99] – последний. Не существует элемента x[100], в том смысле, что под него не выделяется память, хотя после 99-го элемента память не заканчивается и к ней можно обратиться посредством выражения x[100]. Поскольку этот участок памяти не числится за массивом x, он может использоваться для других целей или программой, или операционной системой, поэтому обращение к нему, особенно запись в него какого-то значения, может привести к ошибочному, непредсказуемому поведению программы. В других языках, например, в Паскале, контролируется выход индекса за границы массива. В C++ такого контроля нет, сам программист должен следить за этим.
Массивы в языке C++ имеют всегда конкретную размерность, нельзя определять массивы переменной длины.
Массив может состоять из элементов любых типов.
Массив можно инициализировать при его определении, указав в фигурных скобках список значений элементов. Например, массив с количеством дней в каждом месяце можно инициализировать так:
int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
78 6
Если размер массива не указан, то длину массива вычисляет компилятор по списку инициализации. Для приведенного примера это 12.
Если количество инициализаторов меньше заданного размера массива, оставшиеся элементы будут нулевыми. Пусть, например, определен массив:
int y[6] = {1, 2, 3};
У массива y элементы будут иметь следующие значения: y[0] = 1,
y[1] = 2, y[2] = 3, y[3] = 0, y[4] = 0, y[5] = 0.
Задание слишком большого числа инициализаторов является ошибкой, например,
int z[3] = {1, 2, 3, 4, 5}; // Ошибка, слишком много инициализаторов
Оператор sizeof, примененный к массиву, дает размер массива в байтах. Например, для массива days выражение sizeof(days) / sizeof(int) равно 12, так как массив состоит из 12 элементов типа int. Здесь sizeof(days) – размер памяти в байтах, выделенной под массив, sizeof(int) – размер типа int в байтах.
Над массивами в целом нельзя выполнять какие-либо действия (присваивать, складывать и т.п.), можно работать только с отдельными элементами массива.
Программа 12. Проверка упорядоченности массива
В программе создается массив x целых чисел путем инициализации. Размер массива n устанавливается автоматически при компиляции с помощью выражения
sizeof(x) / sizeof(int).
Программа проверяет, является ли массив упорядоченным по возрастанию. Массив называется упорядоченным по возрастанию, если каждый следующий элемент больше предыдущего или равен ему. Сначала делается предположение, что упорядоченность имеет место. Это фиксируется установкой переменной flag в 1. Затем в цикле сравниваются соседние элементы, и если окажется, что какой-то элемент больше следующего, предположение об упорядоченности отвергается, что фиксируется установкой flag в 0.
//Файл OrderArr.cpp
//Проверка упорядоченности массива #include <iostream.h>
#include <conio.h> int main()
Массивы 79
{ |
|
|
int x[] = {77, 1, 3, 4, 7, 13, 17, 19, 23}; |
// Массив |
|
int n = sizeof(x) / sizeof(int); |
|
// Размер массива |
int i; |
|
// Параметр цикла |
cout << "Задан массив: \n"; |
|
|
for(i = 0; i < n ; i++) |
// Вывод массива |
|
cout << x[i] << ", "; |
|
|
int flag = 1; // Предполагаем, что массив упорядочен по возрастанию // Цикл сравнений соседних элементов
for(i = 0; i < n - 1; i++) if(x[i] > x[i + 1]){
flag = 0; break;
}
if(flag)
cout << "\nМассив упорядочен \n"; else
cout << "\nМассив не упорядочен \n"; getch();
return 0;
}
Так как оператор if(выр) сравнивает числовое значение выражения выр с нулем, можно писать if(flag) вместо if(flag ==1).
Ниже представлены результаты двух запусков программы.
Задан массив:
1, 3, 4, 7, 13, 17, 19, Массив упорядочен
Задан массив:
77, 1, 3, 4, 7, 13, 17, 19, Массив не упорядочен
6.2. Двумерные массивы
Кроме одномерных массивов с одним индексом, можно создавать многомерные массивы с несколькими индексами. Здесь рассмотрим двумерные массивы, которые встречаются чаще, чем массивы с большим числом измерений.
Двумерный массив рассматривается как одномерный, элементами которого являются массивы.
Разберем работу с двумерными массивами на конкретном примере. Пусть предприниматель имеет три магазина, по которым ведет ежедневный учет выручки от продажи четырех видов продуктов
80 6
(например, чая, сахара, крупы, колбасы). Для учета продаж можно использовать следующий двумерный массив:
double r[3][4];
Здесь имеем две пары квадратных скобок. Первые скобки говорят, что r есть массив из 3 элементов, причем каждый из этих трех элементов есть массив из 4-х элементов типа double, о чем говорят вторые квадратные скобки.
Память под многомерные массивы отводится построчно, то есть сначала размещаются первые 4 элемента, затем вторые 4 и т.д.. Схема расположения элементов двумерного массива в памяти показана на рис.32.
·· |
r[0][0] r[0][1] r[0][2] |
r[0][3] r[1][0] r[1][1] r[1][2] |
r[1][3] r[2][0] r[2][1] r[2][2] |
·· |
· |
· |
|||
|
1 строка |
2 строка |
3 строка |
Рис.32. Построчное расположение двумерного массива в памяти
Многомерные массивы при их определении можно инициализировать, записывая инициализаторы для всех массивов, начиная с первого. Для целей тестирования программы массив r можно было бы проинициализировать так:
double r[3][4] = {{500, 700, 450, 1000}, {600, 710, 480, 1100}, {800, 750, 550, 1200} };
Программа 13. Подсчет выручки
Пусть предприниматель, о котором речь шла выше, каждый день подводит итоги: выручку каждого магазина, выручку от продажи каждого товара и общую выручку за день. Эти расчеты можно выполнить с помощью следующей программы.
//Файл Receipts.cpp
//Анализ дневной выручки сети магазинов #include <iostream.h>
int main()
{
const int NSHOP = 3; |
// Число магазинов |
const int NGOODS = 4; |
// Число товаров |
double r[NSHOP][NGOODS]; |
// Двумерный массив для выручки |
int i, j; |
// Параметры циклов |
double srshop, srg, sum; // Выручка по магазинам, товарам, общая
|
|
|
|
Массивы 81 |
cout << "\nВведите выручку от чая, сахара, крупы, колбасы \n"; |
||||
// Ввод данных |
|
|
|
|
for(i = 0; i < NSHOP; i++){ |
|
// Перебор магазинов |
||
cout << "Магазин " << i + 1 << ": "; |
||||
for(j = 0; j < NGOODS; j++) |
// Перебор товаров |
|||
cin >> r[i][j]; // Ввод выручки i-го магазина от продажи j-го товара |
||||
} |
|
|
|
|
cout << "Выручка по магазинам: \n"; |
||||
for(i = 0; i < NSHOP; i++){ |
|
// Перебор магазинов |
||
srshop = 0; |
|
|
|
|
for(j = 0; j < NGOODS; j++) |
// Перебор товаров |
|||
srshop += r[i][j]; |
|
|
||
cout << srshop << "\n"; |
|
|
||
} |
|
|
|
|
sum = 0; |
|
|
|
|
cout << "Выручка по товарам: \n"; |
|
|||
for(j = 0; j < NGOODS; j++){ |
// Перебор товаров |
|||
srg = 0; |
|
|
|
|
for(i = 0; i < NSHOP; i++) |
// Перебор магазинов |
|||
srg += r[i][j]; |
|
|
|
|
cout << srg << ", "; |
|
|
||
sum += srg; |
|
|
// Подсчет общей выручки |
|
} |
|
|
|
|
cout << "\nВсего продано за день на: " << sum; |
||||
return 0; |
|
|
|
|
} |
|
|
|
|
Пример работы программы: |
|
|||
Введите выручку от чая, сахара, крупы, колбасы |
||||
Магазин 1: |
543.50 |
764.45 |
456.70 |
1003.50 |
Магазин 2: |
604.17 |
710.33 |
550.20 |
1221.80 |
Магазин 3: |
804.0 |
765 |
480.34 |
1100 |
Выручка по магазинам: 2768.15 3086.5 3149.34
Выручка по товарам:
1951.67, 2239.78, 1487.24, 3325.3, Всего продано за день на: 9003.99
Здесь важно, что размеры массива задаются константами, значения которых известны на этапе компиляции, поэтому компилятор может зарезервировать под массив память конкретного размера.
При работе с многомерными массивами приходится использовать вложенные циклы. Обработка двумерного массива ведется по строкам