Массивом называется последовательность переменных одного типа, использующая одно имя; для ссылки на конкретное значение применяется индекс. С помощью массивов можно решить проблему работы с последовательностями. В приведенной ниже программе объявляется массив a, в котором можно хранить до 128 целых значений. Максимально возможный индекс последнего элемента i=127.
Пример:
Имя массива хранит в себе адрес в памяти на первый элемент массива. Первый элемент (с индексом 0 и значением 2) в этой программе располагается в памяти по адресу 00C8FBB0:
Массив может быть статическим или динамическим, т.е. храниться в статической или динамической памяти, при этом все элементы располагаются в памяти последовательно, т.е. зная, например, адрес в памяти, по которому хранится целочисленный элемент с индексом 2, можно вычислить, по какому адресу хранится любой другой элемент массива. Область динамической памяти необходимо своевременно возвращать в кучу, чтобы не было утечки памяти. Утечка памяти может привести к переполнению стека либо динамической памяти, что может являться причиной краха программы.
Задача с решением.
Написать программу, суммирующую элементы массива. Реализовать функции для вывода массива на экран дисплея и для получения суммы элементов. Функции должны быть описаны в заголовочных файлах. После создания заголовочных файлов их список можно увидеть в обозревателе решений:
Результат работы программы будет следующим:
Заголовочный файл display.h:
Заголовочный файл sum.h:
Файл .cpp с функцией main():
Инициализация массива
Массив может быть инициализирован сразу во время объявления, например:
float a [4] = {1.0, 2.0, 3.0, 4.0};
Здесь элементу a[0] присваивается 1, элементу a[1] – значение 2 и т.д.
Размер массива может определяться и количеством инициализирующих констант. Например, следующее объявление идентично представленному выше:
float a [] = {1.0, 2.0, 3.0, 4.0};
Все элементы массива можно инициализировать одним и тем же значением, указав его только один раз. Например, все 50 элементов массива a инициализируются значением 6:
int a [50] = {6};
Можно инициализировать массив без использования знака =
int a[3]{10, 30, 200};
или так:
Во время отладки можно увидеть, что заданными значениями инициализируются первые три элемента из 10, остальные по умолчанию инициализируются нулями:
Неинициализированный массив хранит мусор:
Чтобы незаполненный массив не хранил мусор, его можно автоматически заполнить нулями, дописав {}:
Выход за границы массива
Самая распространенная ошибка – неправильное обращение к последнему элементу массива, например, по адресу a[15] массива, состоящего из 15 элементов. Хотя это всего лишь следующий за концом массива элемент, записывать или считывать его не менее опасно, чем любой другой некорректный адрес.
Математики перечисляют содержимое массивов, начиная с элемента номер 1. Первым элементом математического массива a является a[1]. В некоторых языках программирования также начинают перечисление элементов массива с 1. Но в C++ массивы индексируются начиная с нуля. Первый элемент массива C++ обозначается как a[0]. Первый индекс массива C++ нулевой, поэтому последним элементом 15-элементного целочисленного массива a является a[14], а не a[15].
В C++ не проверяется выход индекса за пределы массива. C++ может предоставить доступ и к элементу a[500]. Более того, C++ позволит обратиться даже к a[-100]. Это можно объяснить с помощью следующей аналогии. Имеется улица, на которой 15 жилых домов. Если мы захотим найти 20-й дом, идя вдоль улицы и пересчитывая дома, то его просто может не быть. Тут могут быть заброшенные руины или, хуже того, дом, стоящий уже на другой улице. Чтение значения элемента a[20] может дать некоторое непредсказуемое значение или даже привести к ошибке нарушения защиты, а запись – к совершенно непредсказуемым результатам вплоть до полного краха программы.
Пример с появлением предупреждения:
Матрицы (многомерные массивы)
Иногда в некоторых приложениях приходится работать с последовательностями последовательностей, например, с таблицами, имеющими координаты – x и y.
В C++ матрицы определяются следующим образом:
int matrix [10] [5]; /* Эта матрица может иметь 10 элементов в одном измерении и 5 в другом, что в сумме составляет 50 элементов*/
matrix – 10-элементный массив, каждый элемент которого – массив из 5 элементов. Один угол матрицы обозначается matrix [0] [0], а противоположный – matrix [9] [4].
Матрицу можно инициализировать так же, как и массив:
int m [2] [3] = {{1, 2, 3} {4, 5, 6}};
здесь фактически выполняется инициализация двух трехэлементных массивов:
- m[0] значениями 1, 2 и 3,
- m[1] – значениями 4, 5 и 6.
Задача с решением.
Рассчитать среднее значение успеваемости студента за 5 учебных дней по трем предметам, если известно, что каждый день было три разных урока, и за каждый урок была получена оценка.
Решение:
Результат работы программы будет следующим:
Генерация "случайных" чисел и функция Sleep()
Задача с решением.
Написать программу, которая, используя функцию рандомизации, выводит значения температуры за каждые 6 часов за 3 дня и подсчитывает среднее арифметическое значение температуры за всё время. Температуру задать от -30 до +30. См. в \\simba\001 файл temperature.exe.
Результат работы программы будет следующим:
решения:
Примеры решения задач
1. Вывести содержимое неинициализированного массива (“мусор”) из 5 элементов.
2. Заполнить массив числами от 10 до -5. Вывести все элементы массива.
3. Вывести элементы массива на экран в обратном порядке.
4. Создать массив из 10 элементов. Выполнить заполнение массива случайными числами (от -100 до 100). Вывести массив.
5. Получить от пользователя значения для массива из 10 элементов.
Вывести наименьший и наибольший элементы массива.
6. Создать массив для хранения 8 вещественных чисел, получить значения элементов от пользователя. Затем каждый элемент массива разделить на значение, введенное пользователем.
Вывести получившийся массив.
1. Создать новый проект.
Сохранить. Написать программу, которая находит среднее арифметическое чисел, введенных пользователем. Предварительно программа должна вывести список введенных чисел. Ввод нулевого значения означает конец ввода последовательности. Нулевая сумма чисел приводит к завершению работы программы. Функции описывать в заголовочных файлах.
2. Известны данные о количестве осадков, выпавших за каждый день февраля. Верно ли, что по четным числам выпало больше осадков, чем по нечетным?
3. В массиве хранятся сведения о количестве осадков, выпавших за каждый день февраля. Определить количество дней, когда осадков не было.
4. В массиве записаны оценки по иностранному языку каждого из 22 учеников класса. Определить количество пятерок, количество четверок, количество троек и количество двоек.
5. Рост 25 учеников класса представлен в виде массива. Определить количество учеников, рост которых больше среднего роста по классу.
6. В одномерном массиве имеются только два одинаковых элемента. Найти их.
7. Дан массив из 20 элементов. Сформировать два массива размером 10, включив в первый из них элементы заданного массива с четными индексами, а во второй — с нечетными.
- Выполнить транспонирование квадратной матрицы. Длину сторон вводит пользователь.
- Дан двумерный массив.
- Вывести на экран элемент, расположенный в правом верхнем углу массива.
- Вывести на экран элемент, расположенный в левом нижнем углу массива.
- Дан двумерный массив. Поменять местами:
- элементы, расположенные в правом верхнем и левом нижнем углах;
- элементы, расположенные в правом нижнем и левом верхнем углах.
- Дан двумерный массив целых чисел. Выяснить:
- имеются ли четные числа в левом верхнем или в левом нижнем углу;
- имеются ли числа, оканчивающиеся нулем, в правом верхнем или в правом нижнем углу.
1 байт = 8 бит. Возможны 256 вариантов использования 0 и 1 в записи однобайтового символа (00000001, 00000010 и т.д.):
Вывод таблицы символов ASCII (читается áскú) с помощью явного преобразования типа:
Один из символов при этом вызывает звуковой сигнал. Первые 128 символов (от 0 до 127) всегда одинаковые. Все остальные символы используются для национальных кодировок.
В программе объявлен фиксированный массив символов, содержащий имя “Ivan”. Этот массив передается в функцию displayArray() вместе с его длиной:
Если в конце массива разместить специальный кодовый символ, то не потребуется передавать размеры массива (как это требуется в предыдущей программе). В C++ для этой цели зарезервирован нулевой символ:
Массив myName[] объявляется как массив символов с дополнительным нулевым символом в конце. Программа итеративно проходит по символьному массиву, пока не встретит нуль-символ.
Поскольку в этой программе функции displayArray() больше нет необходимости передавать длину символьного массива, использовать ее проще, чем в предыдущей программе. Включать нулевой символ в символьные массивы очень удобно, и в языке C++ он используется повсеместно. Для таких массивов даже придумано специальное имя - строка символов.
Строка символов – это символьный массив с завершающим нулевым символом.
Выбор нулевого символа в качестве завершающего не был случаен. Это связано с тем, что в C++ только нулевое значение преобразуется в логическое значение false, а все остальные – в true. Это означает, что цикл for можно записать (что обычно и делается) следующим образом:
for (int i = 0; stringArray [i]; i++)
Инициализировать строку в C++ можно с использованием двойных кавычек. Этот способ более удобен, чем тот, в котором используются одинарные кавычки для каждого символа. Следующие объявления идентичны:
char myName [] = {‘I’, ‘v’, ‘a’, ‘n’, ‘\0’};
char myName [] = “Ivan”;
Строка “Ivan” содержит 5, а не 4 символа (5-й – нулевой).
Если при инициализации массива не указать ни размер, ни терминирующий нуль, то массив будет выводиться до тех пор, пока случайно в мусоре не найдется этот нуль:
Тип String
Термин “строка” в C++ может означать как массив с завершающим нулевым символом, так и тип string.
cin записывает в переменную символы до тех пор пока не встретит пробельный символ.
Если вводить по одному слову, то конкатенация выполнится корректно:
Иначе программа будет вести себя неправильно:
Конструкция getline(cin, a); работает более корректно: она записывает в одну строку все символы (включая пробелы и tab'ы) до тех пор, пока пользователь не нажмет Enter.
Для её работы необходимо подключить библиотеку для работы со строками:
#include
Результатом станет корректное поведение программы:
- Составить программу, которая:
- запрашивает имя человека и повторяет его на экране;
- запрашивает имя человека и повторяет его на экране с приветствием.
- Составить программу, которая запрашивает отдельно имя и отдельно фамилию, а затем выводит их как одну символьную строку.
- Составить программу, которая запрашивает название романа и фамилию его автора, а затем выводит сообщение: "Писатель ... — автор романа ..." (на месте многоточий должны быть выведены соответствующие значения).
- Дано слово. Вывести на экран его третий символ.
- Дано слово. Определить, одинаковы ли второй и четвертый символы в нем.
Чтобы использовать функции работы со строками, нужно добавить в начале программы директиву #include
1. int strlen (string)
Возвращает количество символов в строке (без учета нулевого символа)
Пример:
2. int _stricmp (source1, source2)
Сравнивает две строки без учета регистра символов, возвращает 0 (равны) или 1 (не равны)
Пример:
3. char* strstr (source1, source2)
Находит первое вхождение строки source2 в source1
Пример:
4. char* strncat_s (target, source, n)
Присоединяет не более n символов строки source к концу строки target
Пример:
5. char* strncpy_s (target, source, n)
Копирует с заменой не более n символов строки source в target. В большинстве случаев используется для начала новой строки в d.
Пример:
- Дано предложение. Напечатать его в обратном порядке слов, например, предложение мама мыла раму должно быть напечатано в виде раму мыла мама.
- Дано предложение. Напечатать все его слова в порядке неубывания их длин.
- Даны два предложения. Для каждого слова первого предложения (в том числе для повторяющихся в этом предложении слов) определить, входит ли оно во второе предложение.
- Даны два предложения. Напечатать слова, которые встречаются в двух предложениях только один раз.
- Дан текст. Проверить, правильно ли в нем расставлены круглые скобки (т. е. находится ли справа от каждой открывающей скобки соответствующая ей закрывающая скобка, а слева от каждой закрывающей — соответствующая ей закрывающая). Предполагается, что внутри каждой пары скобок нет других скобок.
- Ответом должны служить слова да или нет.
- В случае неправильности расстановки скобок:
- если имеются лишние правые (закрывающие) скобки, то выдать сообщение с указанием позиции первой такой скобки;
- если имеются лишние левые (открывающие) скобки, то выдать сообщение с указанием количества таких скобок;
- если скобки расставлены правильно, то сообщить об этом.