Массив является наиболее распространенной структурой данных в информатике, поскольку он является частью каждого языка программирования, хотя в некоторых языках он может называться как-то иначе, например списком. В этой статье я собираюсь обсудить, как создавать и использовать массивы в 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.