- •2011 Декабрь
- •Выражения. Правила вычисления выражений.
- •Операции и выражения
- •Алгоритмы линейного типа. Операторы ввода-вывода. Генератор случайных чисел.
- •Алгоритмы с ветвлением. Условные выражения. Инструкция if (полная и неполная форма). Вложенные if-инструкции. Конструкция if-else-if.
- •Алгоритмы с ветвлением. Инструкция switch. Вложенные инструкции switch. Примеры в реальных задачах.
- •Алгоритмы циклического типа. Цикл с фиксированным числом повторений for. Параметр цикла. Инструкции break, continue. Бесконечный цикл. Примеры.
- •Цикл с предусловием while. Управление выполнением цикла. Примеры использования цикла. Зацикливание. Инструкция break.
- •Цикл с постусловием do. Управление выполнением цикла. Примеры использования. Зацикливание. Инструкция break.
- •Возможности стандартной библиотеки conio.H. Управление экраном в текстовом режиме. Управление движением объекта.
- •Управление выводом на экран Структура экрана в текстовом режиме
- •Установка нужного текстового режима
- •Текстовое окно и работа с ним
- •Установка цвета для текстовой информации
- •Ввод-вывод в текстовом режиме
- •Управление курсором в текстовом режиме
- •Перемещение изображения
- •Структурированные типы данных: одномерные массивы. Создание и заполнение массива информацией. Доступ к элементу массива. Основные операции с одномерным массивом.
- •Различные алгоритмы сортировок одномерного массива.
- •6.4. Сортировка массивов
- •6.4.1. Сортировка методом простого включения (вставки)
- •6.4.2. Сортировка методом простого выбора
- •6.4.3. Сортировка методом простого обмена
- •6.5. Поиск в отсортированном массиве
- •Указатели. Описание указателя. Операции над указателем. Указатель и одномерный массив. Доступ к элементам массива через указатель.
- •Функции. Назначение функций. Прототип, описание и вызов функции. Правила действия областей видимости функций. Передача параметров по значению и ссылке.
- •Структурированные типы данных: двумерные массивы. Создание и заполнение массива. Доступ к элементу массива. Основные операции с двумерным массивом.
- •Строки. Стандартные команды обработки строк. Обработки строк и текстов. Команды ввода-вывода строк.
- •17.Структуры. Создание и заполнение структур информацией. Доступ к полям структуры.
- •18.Графика. Возможности стандартной библиотеки graphics.H. Алгоритмы построения графических изображений.
- •19.Понятие и назначение файлов. Открытие файла, чтение и запись информации в файл, закрытие файла, проверка достижения конца файла.
- •21.Перегрузка функций. Встраиваемые функции.
- •22.Основные концепции ооп. Классы. Оператор разрешения области видимости. Объекты. Доступ к членам класса. Массивы объектов. Указатели на объекты.
- •23.Конструкторы и деструкторы. Параметризованные конструкторы. Встраиваемые функции в объявлении класса.
- •24.Дружественные функции. Присваивание объектов. Передача объектов функциям.
- •25.Понятие о наследовании. Управление доступом к членам базового класса. Использование защищенных членов.
-
Структурированные типы данных: двумерные массивы. Создание и заполнение массива. Доступ к элементу массива. Основные операции с двумерным массивом.
В этой главе мы рассматриваем массивы. Массив (array) — это коллекция переменных одинакового типа, обращение к которым происходит с применением общего для всех имени. В C++ массивы могут быть одно- или многомерными, хотя в основном используются одномерные массивы. Массивы представляют собой удобное средство группирования связанных переменных.
Чаще всего используются символьные массивы, в которых хранятся строки. Как упоминалось выше, в C++ не определен встроенный тип данных для хранения строк. Поэтому строки реализуются как массивы символов. Такой подход к реализации строк дает С++-программисту больше "рычагов" управления по сравнению с теми языками, в которых используется отдельный строковый тип данных.
Двумерные массивы
В C++ можно использовать многомерные массивы. Простейший многомерный массив — двумерный. Двумерный массив, по сути, представляет собой список одномерных массивов. Чтобы объявить двумерный массив целочисленных значений размером 10x20 с именем twod, достаточно записать следующее:
int twod[10][20] ;
Обратите особое внимание на это объявление. В отличие от многих других языков программирования, в которых при объявлении массива значения размерностей отделяются запятыми, в C++ каждая размерность заключается в собственную пару квадратных скобок.
Чтобы получить доступ к элементу массива twod с координатами 3,5, необходимо использовать запись twod[3] [5]. В следующем примере в двумерный массив помещаются последовательные числа от 1 до 12.
#include <iostream>
using namespace std;
int main() {
int t, i, num[3] [4] ;
for(t=0; t<3; ++t) {
for(i=0; i<4; ++i) {
num[t][i] = (t*4)+i+l;
cout << num[t] [i] << “ “ ;
}
cout << '\n';
}
return 0;
}
В этом примере элемент num[0] [0] получит значение 1, элемент num[0] [1] — значение 2, элемент num[0] [2] — значение 3 и т.д. Значение элемента num[2] [3] будет равно числу 12. Схематически этот массив можно представить, как показано на рис. 5.1.
В двумерном массиве позиция любого элемента определяется двумя индексами. Если представить двумерный массив в виде таблицы данных, то один индекс означает строку, а второй — столбец. Из этого следует, что, если доступ к элементам массива предоставить в порядке, в котором они реально хранятся в памяти, то правый индекс будет изменяться быстрее, чем левый.
0 1 2 3 |
|
||||
0 |
1 |
2 |
3 |
4 |
|
1 |
5 |
6 |
7 |
8 |
|
2 |
9 |
10 |
11 |
12 |
Левый индекс num [1] [2] Правый индекс
Рис. 5.1. Схематическое представление массива пит
Необходимо помнить, что место хранения для всех элементов массива определяется во время компиляции. Кроме того, память, выделенная для хранения массива, используется в течение всего времени существования массива. Для определения количества байтов памяти, занимаемой двумерным массивом, используйте следующую формулу.
число байтов = число строк х число столбцов х размер типа в байтах
Следовательно, двумерный целочисленный массив размерностью 10x5 занимает в памяти 10x5x2, т.е. 100 байт (если целочисленный тип имеет размер 2 байт).
Многомерные массивы
В C++, помимо двумерных, можно определять массивы трех и более измерений. Вот как объявляется многомерный массив.
ТИП имя[размер1] [размер2] ...[размеры] ;
Например, с помощью следующего объявления создается трехмерный целочисленный массив размером 4x10x3.
int multidim[4] [10] [3] ;
Как упоминалось выше, память, выделенная для хранения всех элементов массива, используется в течение всего времени существования массива. Массивы с числом изменений, превышающим три, используются нечасто, хотя бы потому, что для их хранения требуется большой объем памяти. Например, хранение элементов четырехмерного символьного массива размером 10x6x9x4 займет 2 160 байт. А если каждую размерность увеличить в 10 раз, то занимаемая массивом память возрастет до 21 600 000 байт. Как видите, большие многомерные массивы способны "съесть" большой объем памяти, а программа, которая их использует, может очень быстро столкнуться с проблемой нехватки памяти.
Инициализация массивов
В C++ предусмотрена возможность инициализации массивов. Формат инициализации массивов подобен формату инициализации других переменных.
ТИП имя_массива [размер] = {список_значений};
Здесь элемент список_значений представляет собой список значений инициализации элементов массива, разделенных запятыми. Тип каждого значения инициализации должен быть совместим с базовым типом массива (элементом тип). Первое значение инициализации будет сохранено в первой позиции массива, второе значение — во второй и т.д. Обратите внимание на то, что точка с запятой ставится после закрывающей фигурной скобки (}).
Например, в следующем примере 10-элементный целочисленный массив инициализируется числами от 1 до 10.
int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
После выполнения этой инструкции элемент i [ 0 ] получит значение 1, а элемент i [ 9 ] — значение 10.
Для символьных массивов, предназначенных для хранения строк, предусмотрен сокращенный вариант инициализации, который имеет такую форму.
char имя_массива[размер] = "строка";
Например, следующий фрагмент кода инициализирует массив str фразой "привет",
char str[7] = "привет";
Это равнозначно поэлементной инициализации.
char str[7] = {'п’, 'р', 'и', 'в', 'е', 'т', '\0'};
Поскольку в C++ строки должны завершаться нулевым символом, убедитесь, что при объявлении массива его размер указан с учетом признака конца. Именно поэтому в предыдущем примере массив str объявлен как 7-элементный, несмотря на то, что в слове "привет" только шесть букв. При использовании строкового литерала компилятор добавляет нулевой признак конца строки автоматически.
Многомерные массивы инициализируются по аналогии с одномерными. Например, в следующем фрагменте программы массив sqrs инициализируется числами от 1 до 10 и квадратами этих чисел. int sqrs[10][2] = {
-
1,
-
4,
-
9,
-
16,
-
25,
-
36,
-
49,
-
64,
-
81,
10, 100 };
Теперь рассмотрим, как элементы массива sqrs располагаются в памяти (рис. 5.2).
При инициализации многомерного массива список инициализаторов каждой размерности (подгруппу инициализаторов) можно заключить в фигурные скобки. Вот, например, как выглядит еще один вариант записи предыдущего объявления.
int sqrs[10][2] = { {1, 1}, {2, 4}, {3, 9}, (4, 16}, (5, 25},
{6, 36), {7, 49}, {8, 64}, (9, 81}, {10, 100}};
1 21 41 3 9 4 16 100 100 Правый
индекс 0
1
1 0
1
2
3
4
10
Левый
индекс
Рис. 5.2. Схематическое представление инициализированного массива sqrs
При использовании подгрупп инициализаторов недостающие члены подгруппы будут инициализированы нулевыми значениями автоматически.
В следующей программе массив sqrs используется для поиска квадрата числа, введенного пользователем. Программа сначала выполняет поиск заданного числа в массиве, а затем выводит соответствующее ему значение квадрата.
#include <iostream.h>
int sqrs[10][2] = {
{1, 1},
{2, 4},
{3, 9},
{4, 16},
{5, 25},
{6, 36},
{7, 49},
{8, 64},
(9, 81}, {10, 100}
int main () {
int i, j;
cout << "Введите число от 1 до 10: ";
cin >> i;
// Поиск значения i.
for(j=0; j<10; j++)
if(sqrs[j][0]==i) break;
cout << "Квадрат числа " << i « " равен ";
cout << sqrs[j][1];
return 0; }
Глобальные массивы инициализируются в начале выполнения программы, а локальные — при каждом вызове функции, в которой они содержатся. Рассмотрим пример.
#include <iostream.h>
#include <string.h>
void fl() ;
int main() {
fl() ;
fl();
return 0; }
void fl() {
char s[80]="Эto просто тест\n";
cout << s;
strcpy(s, "ИЗМЕНЕН0\n"); // Изменяем значение строки s.
cout << s; }
При выполнении этой программы получаем такие результаты.
Это просто тест
ИЗМЕНЕНО
Это просто тест
ИЗМЕНЕНО
В этой программе массив s инициализируется при каждом вызове функции f1(). Тот факт, что при ее выполнении массив s изменяется, никак не влияет на его повторную инициализацию при последующих вызовах функции f1(). Поэтому при каждом входе в нее на экране отображается следующий текст.
Это просто тест
"Безразмерная" инициализация массивов
Предположим, что мы используем следующий вариант инициализации массивов для построения таблицы сообщений об ошибках.
char el [14] = "Деление на 0\n";
char e2[23] = "Конец файла\n";
char еЗ[21] = "В доступе отказано\n";
Нетрудно предположить, что вручную неудобно подсчитывать символы в каждом сообщении, чтобы определить корректный размер массива. К счастью, в C++ предусмотрена возможность автоматического определения длины массивов путем использования их «безразмерного» формата. Если в инструкции инициализации массива не указан его размер, C++ автоматически создаст массив, размер которого будет достаточным для хранения всех значений инициализаторов. При таком подходе предыдущий вариант инициализации массивов для построения таблицы сообщений об ошибках можно переписать так.
char el[] = "Деление на 0\n";
char е2[] = "Конец файла\n";
char еЗ[] = "В доступе отказано\n";
Помимо удобства в первоначальном определении массивов, метод "безразмерной" инициализации позволяет изменить любое сообщение без пересчета его длины. Тем самым устраняется возможность внесения ошибок, вызванных случайным просчетом.
"Безразмерная" инициализация массивов не ограничивается одномерными массивами. При инициализации многомерных массивов вам необходимо указать все данные, за исключением крайней слева размерности, чтобы С++-компилятор мог должным образом
индексировать массив. Используя "безразмерную" инициализацию массивов, можно создавать таблицы различной длины, позволяя компилятору автоматически выделять область памяти, достаточную для их хранения.
В следующем примере массив sqrs объявляется как "безразмерный".
int sqrs[] [2] = {1, 1, 2, 4, 3, 9, 4, 16, 5, 25, 6, 36, 7, 49, 8, 64, 9, 81, 10, 100};
Преимущество такой формы объявления перед "габаритной" (с точным указанием всех размерностей) состоит в том, что программист может удлинять или укорачивать таблицу значений инициализации, не изменяя размерности массива.