Урок №74. Массивы

  Юрий  | 

  |

  Обновл. 4 Сен 2021  | 

 148298

 ǀ   22 

На уроке о структурах мы узнали, что с их помощью можно объединять переменные разных типов под одним идентификатором. Это идеально, когда нужно смоделировать объект, который имеет много разных свойств. Однако удобство работы со структурами при наличии большого количества элементов оставляет желать лучшего.

Что такое массив?

К счастью, структуры не являются единственным агрегированным типом данных в языке C++. Есть еще массив — совокупный тип данных, который позволяет получить доступ ко всем переменным одного и того же типа данных через использование одного идентификатора.

Рассмотрим случай, когда нужно записать результаты тестов 30 студентов в классе. Без использования массива нам придется выделить 30 почти одинаковых переменных!

С использованием массива всё гораздо проще. Следующая строка эквивалентна коду, приведенному выше:

В объявлении переменной массива мы используем квадратные скобки [], чтобы сообщить компилятору, что это переменная массива (а не обычная переменная), а в скобках — количество выделяемых элементов (это называется длиной или размером массива).

В примере, приведенном выше, мы объявили фиксированный массив с именем testResult и длиной 30. Фиксированный массив (или «массив фиксированной длины») представляет собой массив, размер которого известен во время компиляции. При создании testResult, компилятор выделит 30 целочисленных переменных.

Элементы массива


Каждая из переменных в массиве называется элементом. Элементы не имеют своих собственных уникальных имен. Вместо этого для доступа к ним используется имя массива вместе с оператором индекса [] и параметром, который называется индексом, и который сообщает компилятору, какой элемент мы хотим выбрать. Этот процесс называется индексированием массива.

В вышеприведенном примере первым элементом в нашем массиве является testResult[0], второй — testResult[1], десятый — testResult[9], последний — testResult[29]. Хорошо, что уже не нужно отслеживать и помнить кучу разных (хоть и похожих) имен переменных — для доступа к разным элементам нужно изменять только индекс.

Важно: В отличие от повседневной жизни, отсчет в программировании и в языке С++ всегда начинается с 0, а не с 1!

В массиве длиной N элементы массива будут пронумерованы от 0 до N-1! Это называется диапазоном массива.

Пример программы с использованием массива

Здесь мы можем наблюдать как определение, так и индексирование массива:

Результат выполнения программы:

The array element with the smallest index has the value 3
The sum of the first 5 numbers is 29

Типы данных и массивы


Массив может быть любого типа данных. Например, объявляем массив типа double:

Результат выполнения программы:

The average is 3.1

Массивы также можно сделать из структур, например:

Чтобы получить доступ к члену структуры из элемента массива, сначала нужно выбрать элемент массива, затем использовать оператор выбора члена структуры, а затем требуемый член структуры:

Индексы массивов

В языке C++ индексы массивов всегда должны быть интегрального типа данных (т.е. типа char, short, int, long, long long, bool и т.д.). Эти индексы могут быть либо константными значениями, либо неконстантными значениями. Например:

Объявление массивов фиксированного размера


При объявлении массива фиксированного размера, его длина (между квадратными скобками) должна быть константой типа compile-time (которая определяется во время компиляции). Вот несколько разных способов объявления массивов с фиксированным размером:

Обратите внимание, в двух последних случаях мы должны получить ошибку, так как длина массива не является константой типа compile-time. Некоторые компиляторы могут разрешить использование таких массивов, но они являются некорректными в соответствии со стандартами языка C++ и не должны использоваться в программах, написанных на C++.

Чуть-чуть о динамических массивах

Поскольку массивам фиксированного размера память выделяется во время компиляции, то здесь мы имеем два ограничения:

   Массивы фиксированного размера не могут иметь длину, основанную на любом пользовательском вводе или другом значении, которое вычисляется во время выполнения программы (runtime).

   Фиксированные массивы имеют фиксированную длину, которую нельзя изменить.

Во многих случаях эти ограничения являются проблематичными. К счастью, C++ поддерживает еще один тип массивов, известный как динамический массив. Размер такого массива может быть установлен ​​во время выполнения программы и его можно изменить. Однако создание динамических массивов несколько сложнее фиксированных, поэтому мы поговорим об этом несколько позже.

Заключение

Фиксированные массивы обеспечивают простой способ выделения и использования нескольких переменных одного типа данных до тех пор, пока размер массива известен во время компиляции.

На следующем уроке мы рассмотрим больше тем, связанных с фиксированными массивами.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (500 оценок, среднее: 4,89 из 5)
Загрузка...

Комментариев: 22

  1. Edman:

    Почему width здесь является типа runtime? Ведь значение temp присвоится width во время компиляции, а не во время выполнения программы. Или значения переменных присваиваются другим переменным во время выполнения?

    1. eugene:

      добавь на 2 строку что-то типа:

      после чего temp введенный at runtime упадет в width, который уже определит размер массива. MinGW это схавает и соберет EXE

  2. Виктор:

    что происходит в данном коде и почему он выводит много разных значений

    1. Никита:

      У тебя размер массива равен 10, а ты пытаешься в цикле for вывести значения, которые выходят за пределы массива (элементы с индексом 10, 11, 12, 13 … 2020). Поэтому и происходит неразбериха. Тебе нужно сделать следующим образом:

    2. warner12:

      Массива в Си, как такового не существует. Массив является указателем на первый элемент, а индексация — это передвижение "каретки" по памяти с прыжком равным количеством бит используемого типа данных самого массива.

      Когда пытаешься запросить индекс выходящий за пределы массива — ты обращаешься к памяти, которая не резервируется этим массивом и используется как угодно: может быть мусором, кучей, существующими переменными, объектами и т.д. и интерпретируется в тип данных массива.

      В таком случае, результат программы непредсказуем, и не является корректным. Делать так — запрещено при любых обстоятельствах.

  3. Алексей:

    Изучаю и UE4, там массивы вообще не рекомендуют использовать)
    Хотя недавно делал инициализацию структуры при случаи, это был выбор сложности для Hi-Lo.

    С массивами немного легче, хотя кто знает)

    1. Александр:

      Алексей, а где, если не секрет, вы изучаете UE4? Кстати, выходит UE5 =)

  4. Владислав:

    Всем здравствуйте! Друзья может кто помочь с решением такой задачи. Знаю что базовое задание, но в программировании не силен, но решить нужно.
    Задание: Массив A = (15, 9, –6, 12, –9, 18, 0) преобразован к виду A = (5, 3, 0, 4, 0, 6, 0). Размер массива A — 20 элементов из диапазона [–25,25]. Вычислить сумму четных элементов преобразованного массива.
    Вот что то попробовал но не уверен что работает правильно.

    1. Юшка:

  5. SuRprizZe:

    Почему элементу массива которого как бы не существует,если вначале объявляется элемент с 4 значениями,можно 5 элементу присвоить что-то хотя его нет и как вообще это объяснить?!

    1. Роман:

      Как я понимаю, объявляя массив Array[n], мы резервируем n-ое количество элементов памяти соответствующего типу данных размера, а Array[i] — это указатель на i-ый элемент памяти такого размера, начиная с нулевого (Array[0]). Следовательно, если мы напишем "Array[n]=чему-то", мы обратимся к элементу памяти, следующему за местом хранения последнего члена массива (Array[n-1]), — куда и будет помещено наше "что-то" и будет до поры до времени там спокойно лежать. Программу такая "просьба" ни капли не затруднит.
      Однако, поскольку мы договорились с программой, что хранит она наш массив только в n элементах, то, как только ей понадобится ближайшая к массиву ячейка памяти, программа немедленно, без зазрения совести, выбросит наше "что-то" в забвение и мы уже никогда, никогда его не найдем…
      К слову, тут, мне кажется, может быть еще хуже: программа зарезервирует кусок памяти, идущий вслед за массивом, под некую нашу переменную x, со значением, скажем Y — а мы возьми и помести туда наш n+1-ый элемент!.. И будет, обратно, он там лежать, покуда иксу не присвоят новое значение. Или программа вовсе уйдет в глюк.

  6. alien:

    Почему вы используете std::
    Если вместо этого можно написать
    using namespace std; ??
    Думаю лучше добавить эту библиотеку и не писать каждый раз std::
    просто небольшой совет 😉

    1. Фото аватара Юрий:

      Читайте уроки 24 и 54.

    2. Александр:

      С ростом объемов кода этот "небольшой совет" превращается в "большую проблему"… А при попытке отладки этого кода может перерасти вообще в "катастрофу" :)))

      1. Jdvin:

        В небольшых кодах проще использовать "using namespace std"

        В кодах побольше этого делать не надо, так как будет серёзная проблема…. Вот и всё)

  7. Александр:

    Вот тоже всегда считал и всем рассказывал, что размер массива должен задаваться константой compile time, а недавно в техностриме mail.ru (или яндекса) услышал, что в текущем стандарте (то ли с С++14, то ли с С++17) можно и переменными задавать и это считается корректным… причем считается это лучшей идеей, чем выделять динамический массив, вроде как потому, что он самоубивается корректно…

    Хотя мне все равно кажется, что "безопасней" работать с константными размерами

  8. Игорь:

    Почему в конце инициализируется значением 8 массив с индексом 4. (array[index] = 8). ведь последний индекс у этого массива 3 (array[3] )?

    1. ffolax:

      Ошибка допущена. Значение будет записано в ячейку следующую за последним элементом массива. Место под ту ячейку не зарезервировано массивом и может в любой момент быть изменено другим процессом.

    2. SuRprizZe:

      Тут общее количество элементов в массиве , считая с 1

  9. Oleksiy:

    Пример программы с использованием массива…

    "The lowest number is: " << array[0]

    самое маленькое число находится в array[1]

  10. KiFoR:

    О Даэдра… Как же я ненавижу массивыы…

    1. Фото аватара Юрий:

      Увы, но от этого ничего не поменяется 🙂

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *