Массив является наиболее распространенной структурой данных в информатике, поскольку он является частью каждого языка программирования, хотя в некоторых языках он может называться как-то иначе, например списком. В этой статье я собираюсь обсудить, как создавать и использовать массивы в C ++. Я собираюсь ограничить свое обсуждение одномерными массивами, и я расскажу о многомерных массивах в будущей статье.
Определенные массивы
Массив - это набор непрерывных адресов памяти, которые зарезервированы для хранения данных определенного типа. Массив должен быть объявлен с именем, типом данных и размером, что означает количество элементов данных для хранения в массиве.
Размеры массивов фиксированы в C ++, что может создать проблемы, когда программе требуется больше места для хранения, чем было выделено изначально.
Доступ к элементам массива осуществляется через позицию индекса элемента в массиве. Элементы массива упорядочиваются, начиная с позиции 0, а последний элемент сохраняется в позиции индекса, которая на 1 меньше количества элементов в массиве.
Объявление массивов
Как я упоминал выше, массив объявляется с типом данных, именем и размером. Обычно для размера массива указывается константа, потому что любая программа, использующая массив, должна будет много раз ссылаться на размер массива.
Вы можете объявить массив без указания данных, которые будут храниться в массиве, или вы можете предоставить список инициализаторов с данными для массива.
Вот шаблон синтаксиса для первого типа объявления массива:
тип данных имя-массива [количество-элементов];
Вот шаблон синтаксиса для второго типа объявления массива:
тип-данных имя-массива [(количество-элементов)] = {список-данных-данных, разделенных запятыми};
Спецификация количества элементов указана в круглых скобках, потому что вы можете не указывать это при предоставлении списка инициализаторов, и компилятор определит размер массива, подсчитав количество элементов в списке.
Вот несколько примеров первой формы объявления массива:
const int numElements = 10; int grades[numElements]; string names[numElements]; bool flags[numElements]; char letters[numElements];
Теперь давайте посмотрим на некоторые объявления, в которых используется список инициализаторов:
const int numElements = 5; int numbers[numElements] = {1,2,3,4,5}; const int numNames = 3; string names[] = {"Cynthia", "Jonathan", "Raymone"}; cont int numFlags = 4; bool flags[] = {false, true, true, false};
Я написал пару объявлений, заключив количество элементов в скобки и позволив компилятору определить количество элементов. Однако даже если вы разрешите компилятору определять количество элементов в массиве, вы все равно должны объявить константу с количеством элементов в массиве.
Доступ к массивам
Доступ к элементам массива осуществляется путем указания позиции индекса нужного элемента с помощью оператора []
. Например, вот несколько операторов, которые присваивают некоторые данные массиву:
numbers[0] = 101; numbers[1] = 103; numbers[2] = 105;
Доступ к сохраненным данным осуществляется из массива также с помощью оператора []
. Например:
int subtotal = numbers[0] + numbers[1] + numbers[2];
Вот еще один пример доступа к массиву, на этот раз с использованием цикла for
для инициализации массива набором чисел:
#include <iostream> using namespace std; int main() { const int numElements = 5; int numbers[numElements]; for (int i = 0; i < numElements; i++) { numbers[i] = i + 1; } return 0; }
Вот еще один пример использования цикла for
, на этот раз доступ к массиву как часть процесса вычисления среднего:
int main() { const int numElements = 5; int grades[numElements] = {81, 78, 91, 77, 66}; int total = 0; for (int i = 0; i < numElements; i++) { total += grades[i]; } double average = static_cast<double>(total) / numElements; cout << "The average grade is: " << average << endl; return 0; }
Вот результат этой программы:
The average grade is: 78.6
Поскольку это вводная статья, я использовал int
для инициализации переменной управления циклом for. Если бы это была более сложная статья, я бы использовал вместо нее size_t
.
Я также должен упомянуть, что лучший способ пройти массив от начала до конца, когда вы хотите получить доступ к каждому элементу, - это использовать цикл range for
. Вот программа, переписанная с учетом этого:
int main() { const int numElements = 5; int grades[numElements] = {81, 78, 91, 77, 66}; int total = 0; for (auto grade : grades) { total += grade; } double average = static_cast<double>(total) / numElements; cout << "The average grade is: " << average << endl; return 0; }
Массивы как аргументы функции
Я особо подчеркивал, что вы всегда должны объявлять константу, которая содержит количество элементов в массиве. Первая причина, по которой вам нужно это сделать, заключается в том, что при написании цикла index for
для обхода массива у вас будет доступная константа, чтобы цикл знал, когда остановиться.
Это важно, потому что массивы C ++ не имеют проверки границ, что означает, что вы можете случайно получить доступ к памяти вне массива, не вызывая ошибки. Как однажды сказал кто-то, возможно, известный: «С ++ дает достаточно веревки, чтобы повеситься». Когда это произойдет, новый язык вызовет исключение, но C ++ просто предполагает, что это именно то, что вы хотели сделать.
Еще одна причина иметь постоянное количество элементов массива - это когда вы хотите передать массив функции. Вы не можете использовать цикл range for
для доступа к элементам массива из тела функции, поэтому вы должны использовать цикл index for
. Это означает, что вам нужно знать, когда остановить цикл, и постоянный параметр предоставляет это значение.
Зная это, я могу показать вам, как передать массив функции. Я перепишу программу усреднения оценок сверху, добавив функцию, которая вычисляет среднее значение:
double gradeAvg(int arr[], int arraySz) { int total = 0; for (int i = 0; i < arraySz; i++) { total += arr[i]; } double average = static_cast<double>(total) / arraySz; return average; } int main() { const int numElements = 5; int grades[numElements] = {81, 78, 91, 77, 66}; int total = 0; double average = gradeAvg(grades, numElements); cout << "The average grade is: " << average << endl; return 0; }
Результат этой программы:
The average grade is: 78.6
Массивы также могут быть возвращены из функции, но для этого требуются указатели, поэтому мне придется сохранить это обсуждение на другой день.
Массивы - это здорово, но векторы могут быть лучше
Хотя я посвятил эту статью объяснению того, как использовать массивы, большинство программистов на C ++ сейчас используют векторы в качестве первой структуры данных для хранения последовательных данных. Для этого есть несколько причин, в том числе тот факт, что реализация класса векторов в стандартной библиотеке шаблонов сейчас очень эффективна, и, что, вероятно, наиболее важно, векторы могут увеличиваться и уменьшаться по мере необходимости. В следующей статье я расскажу, как использовать векторы в C ++, и вы увидите их преимущества перед массивами.
Спасибо за чтение, напишите мне с комментариями и предложениями. Если вас интересуют мои онлайн-курсы по компьютерному программированию, посетите https://learningcpp.teachable.com.