Статический массив: объявление, заполнение, использование. Массивы Массивы в c

Продолжаем изучение основ C++. В этой статье мы рассмотрим массивы.

Массивы позволяют в удобном формате хранить большое количество данных. По сути, массив — это переменная, которая хранит множество значений под одним именем, но каждому значению присвоен свой индекс. — это список значений, для получения доступа к которым используются индексы.

Введение в массивы

Визуализировать массив можно следующим образом:

Это набор некоторых значений, которые хранятся друг за другом, под одним именем. Для получения этих значений вам не придется создавать новых переменных, нужно только указать индекс под которым хранится значение в массиве. Например, вам необходимо раздать набор из пяти игральных карт для покера, вы можете хранить эти карты в массиве и для выбора новой карты изменять только номер индекса, вместо использования новой переменной. Это позволит использовать один и тот же код для инициализации всех карт и перейти от такой записи:

Card1 = getRandomCard(); Card2 = getRandomCard(); Card3 = getRandomCard(); Card4 = getRandomCard(); Card5 = getRandomCard();

For (int i = 0; i < 5; i++) { card[i] = getRandomCard(); }

А теперь представьте разницу, если переменных 100!

Синтаксис

Для объявления массива необходимо указать две вещи (помимо имени): тип и размер массива:

Int my_array[ 6 ];

Данная строка объявляет массив из шести целочисленных значений. Обратите внимание, что размер массива заключен в квадратные скобки после имени массива.

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

My_array[ 3 ];

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


my_array ссылается на весь массив целиком, в то время как my_array только на первый элемент, my_array — на четвертый. Обратите внимание, что индексация элементов в массиве начинается с 0. Таким образом Обращение к элементам массива всегда будет происходить со смещением, например:

Int my_array[ 4 ]; // объявление массива my_array[ 2 ] = 2; // установить значение третьего (именно третьего!) равным 2

Объявление многомерных массивов в C++

Массивы могут также использоваться для представления многомерных данных, например, таких, как шахматная доска или поле для игры в крестики нолики. При использовании многомерных данных для доступа к элементам массива будут использоваться несколько индексов.

Для объявления двумерного массива необходимо указать размерность двух измерений:

Int tic_tac_toe_board;

Визуализация массива с индексами его элементов:

Для доступа к элементам такого массива потребуется два индекса — один для строки второй для столбца. На изображении показаны нужные индексы для доступа к каждому из элементов.

Использование массивов

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

Следующая программа демонстрирует использование цикла для создания таблицы умножения и хранения результата в двумерном массиве:

#include using namespace std; int main() { int array; // Объявляем массив, который выглядит как шахматная доска for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { array[i][j] = i * j; // Задаем значения каждого элемента } } cout << "Multiplication table:\n"; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { cout << "[ " << i << " ][ " << j << "] = "; cout << array[i][j] << " "; cout << "\n"; } } }

Передаем массивы в функции

Как видите, разные элементы языка C++ взаимодействуют друг с другом. Как и с циклами, массивы можно использовать вместе с .

Чтобы передать массив в функцию достаточно просто указать его имя:

Int values[ 10 ]; sum_array(values);

А при объявлении функции указать массив в качестве аргумента:

Int sum_array (int values);

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

Так как внутри функции мы не знаем размер массива, необходимо передать размерность в качестве второго аргумента:

Int sumArray(int values, int size) { int sum = 0; for (int i = 0; i < size; i++) { sum += values[ i ]; } return sum; }

Когда мы передаем многомерные массивы, надо указывать все размерности, за исключением первой:

Int check_tic_tac_toe (int board);

Вы, конечно, можете указать первую размерность, но она будет проигнорирована.

Подробнее эта тема будет раскрыта в статье про указатели.

А пока напишем функцию, которая вычисляет сумму элементов массива:

#include using namespace std; int sumArray(int values, int size) { int sum = 0; // цикл остановится когда i == size, потому что индекс последнего элемента = size - 1 for (int i = 0; i < size; i++) { sum += values[i]; } return sum; } int main() { int values; for (int i = 0; i < 10; i++) { cout << "Enter value " << i << ": "; cin >> values[i]; } cout << sumArray(values, 10) << endl; }

Сортировка массива

Решим задачу сортировки массива из 100 чисел, которые ввел пользователь:

#include using namespace std; int main() { int values[ 100 ]; for (int i = 0; i < 100; i++) { cout << "Enter value " << i << ": "; cin >> values[ i ]; } }

Готово, осталось только отсортировать этот массив 🙂 Как обычно люди сортируют массивы? Они ищут самый маленький элемент в нем и ставят его в начало списка. Затем они ищут следующее минимальное значение и ставят его сразу после первого и т.д.

Все это дело выглядит как цикл: пробегаем по массиву, начиная с первого элемента и ищем минимальное значение в оставшейся части, и меняем местами эти элементы. Начнем с написания кода для выполнения этих операций:

Void sort(int array, int size) { for (int i = 0; i < size; i++) { int index = findSmallestRemainingElement(array, size, i); swap(array, i, index); } }

Теперь можно подумать о реализации двух вспомогательных методов findSmallestRemainingElement и swap. Метод findSmallestRemainingElement должен пробегать по массиву и находить минимальный элемент, начиная с индекса i:

Int findSmallestRemainingElement(int array, int size, int index) { int index_of_smallest_value = index; for (int i = index + 1; i < size; i++) { if (array[ i ] < array[ index_of_smallest_value ]) { index_of_smallest_value = I; } } return index_of_smallest_value; }

Наконец, нам надо реализовать функцию swap. Так как функция изменит оригинальный массив, нам просто надо поменять значения местами, используя временную переменную:

Void swap(int array, int first_index, int second_index) { int temp = array[ first_index ]; array[ first_index ] = array[ second_index ]; array[ second_index ] = temp; }

Для проверки алгоритма заполним массив случайными числами и отсортируем. Весь код программы:

#include #include #include using namespace std; int findSmallestRemainingElement(int array, int size, int index); void swap(int array, int first_index, int second_index); void sort(int array, int size) { for (int i = 0; i < size; i++) { int index = findSmallestRemainingElement(array, size, i); swap(array, i, index); } } int findSmallestRemainingElement(int array, int size, int index) { int index_of_smallest_value = index; for (int i = index + 1; i < size; i++) { if (array[ i ] < array[ index_of_smallest_value ]) { index_of_smallest_value = i; } } return index_of_smallest_value; } void swap(int array, int first_index, int second_index) { int temp = array[ first_index ]; array[ first_index ] = array[ second_index ]; array[ second_index ] = temp; } // вспомогательная функция для вывода массива void displayArray(int array, int size) { cout << "{"; for (int i = 0; i < size; i++) { // если элемент не первый выведем запятую if (i != 0) { cout << ", "; } cout << array[ i ]; } cout << "}"; } int main() { int array[ 10 ]; srand(time(NULL)); for (int i = 0; i < 10; i++) { array[ i ] = rand() % 100; } cout << "Original array: "; displayArray(array, 10); cout << "\n"; sort(array, 10); cout << "Sorted array: "; displayArray(array, 10); cout << "\n"; }

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

Последнее обновление: 17.09.2017

Массив представляет набор однотипных данных. Формальное определение массива выглядит следующим образом:

Тип_переменной название_массива [длина_массива]

После типа переменной идет название массива, а затем в квадратных скобках его размер. Например, определим массив из 4 чисел:

Int numbers;

Данный массив имеет четыре числа, но все эти числа имеют неопределенное значение. Однако мы можем выполнить инициализацию и присвоить этим числам некоторые начальные значения через фигурные скобки:

Int numbers = {1,2,3,4};

Значения в фигурных скобках еще называют инициализаторами. Если инициализаторов меньше, чем элементов в массиве, то инициализаторы используются для первых элементов. Если в инициализаторов больше, чем элементов в массиве, то при компиляции возникнет ошибка:

Int numbers = {1, 2, 3, 4, 5, 6};

Здесь массив имеет размер 4, однако ему передается 6 значений.

Если размер массива не указан явно, то он выводится из количества инициализаторов:

Int numbers = {1, 2, 3, 4, 5, 6};

В данном случае в массиве есть 6 элементов.

Свои особенности имеет инициализация символьных массивов. Мы можем передать символьному массиву как набор инициализаторов, так и строку:

Char s1 = {"h", "e", "l", "l", "o"}; char s2 = "world";

Причем во втором случае массив s2 будет иметь не 5 элементов, а 6, поскольку при инициализации строкой в символьный массив автоматически добавляется нулевой символ "\0".

При этом не допускается присвоение одному массиву другого массива:

Int nums1 = {1,2,3,4,5}; int nums2 = nums1; // ошибка nums2 = nums1; // ошибка

После определения массива мы можем обратиться к его отдельным элементам по индексу. Индексы начинаются с нуля, поэтому для обращения к первому элементу необходимо использовать индекс 0. Обратившись к элементу по индексу, мы можем получить его значение, либо изменить его:

#include int main() { int numbers = {1,2,3,4}; int first_number = numbers; std::cout << first_number << std::endl; // 1 numbers = 34; // изменяем элемент std::cout << numbers << std::endl; // 34 return 0; }

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

Const int n = 4; int numbers[n] = {1,2,3,4};

Перебор массивов

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

#include int main() { int numbers = {1,2,3,4}; int size = sizeof(numbers)/sizeof(numbers); for(int i=0; i < size; i++) std::cout << numbers[i] << std::endl; return 0; }

Чтобы пройтись по массиву в цикле, вначале надо найти длину массива. Для нахождения длины применяется оператор sizeof . По сути длина массива равна совокупной длине его элементов. Все элементы представляют один и тот же тип и занимают один и тот же размер в памяти. Поэтому с помощью выражения sizeof(numbers) находим длину всего массива в байтах, а с помощью выражения sizeof(numbers) - длину одного элемента в байтах. Разделив два значения, можно получить количество элементов в массиве. А далее с помощью цикла for перебираем все элементы, пока счетчик i не станет равным длине массива. В итоге на консоль будут выведены все элементы массива:

Но также есть и еще одна форма цикла for , которая предназначена специально для работа с коллекциями, в том числе с массивами. Эта форма имеет следующее формальное определение:

For(тип переменная: коллекция) { инструкции; }

Используем эту форму для перебора массива:

#include int main() { int numbers = {1,2,3,4}; for(int number: numbers) std::cout << number << std::endl; return 0; }

При переборе массива каждый перебираемый элемент будет помещаться в переменную number, значение которой в цикле выводится на консоль.

Если нам неизвестен тип объектов в массиве, то мы можем использовать спецификатор auto для определения типа:

For(auto number: numbers) std::cout << number << std::endl;

Многомерные массивы

Кроме одномерных массивов в C++ есть многомерные. Элементы таких массивов сами в свою очередь являются массивами, в которых также элементы могут быть массивами. Например, определим двухмерный массив чисел:

Int numbers;

Такой массив состоит из трех элементов, при этом каждый элемент представляет массив из двух элементов. Инициализируем подобный массив:

Int numbers = { {1, 2}, {4, 5}, {7, 8} };

Вложенные фигурные скобки очерчивают элементы для каждого подмассива. Такой массив еще можно представить в виде таблицы:

1 2
4 5
7 8

Также при инициализации можно опускать фигурные скобки:

Int numbers = { 1, 2, 4, 5, 7, 8 };

Возможна также инициализация не всех элементов, а только некоторых:

Int numbers = { {1, 2}, {}, {7} };

И чтобы обратиться к элементам вложенного массива, потребуется два индекса:

Int numbers = { {1, 2}, {3, 4}, {5, 6} }; std::cout << numbers << std::endl; // 3 numbers = 12; // изменение элемента std::cout << numbers << std::endl; // 12

Переберем двухмерный массив:

#include int main() { const int rows = 3, columns = 2; int numbers = { {1, 2}, {3, 4}, {5, 6} }; for(int i=0; i < rows; i++) { for(int j=0; j < columns; j++) { std::cout << numbers[i] [j] << "\t"; } std::cout << std::endl; } return 0; }

Также для перебора элементов многомерного массива можно использовать другую форму цикла for:

#include int main() { const int rows = 3, columns = 2; int numbers = { {1, 2}, {3, 4}, {5, 6} }; for(auto &subnumbers: numbers) { for(int number: subnumbers) { std::cout << number << "\t"; } std::cout << std::endl; } return 0; }

Для перебора массивов, которые входят в массив, применяются ссылки. То есть во внешнем цикле for(auto &subnumbers: numbers) &subnumbers представляет ссылку на подмассив в массиве. Во внутреннем цикле for(int number: subnumbers) из каждого подмассива в subnumbers получаем отдельные его элементы в переменную number и выводим ее значение на консоль.

П усть нам необходимо работать с большим количеством однотипных данных. Например, у нас есть тысяча измерений координаты маятника с каким-то шагом по времени. Создавать 1000 переменных для хранения всех значений очень... обременительно. Вместо этого множество однотипных данных можно объединить под одним именем и обращаться к каждому конкретному элементу по его порядковому номеру.
Массив в си определяется следующим образом
<тип> <имя массива>[<размер>];
Например,
int a;
Мы получим массив с именем a , который содержит сто элементов типа int . Как и в случае с переменными, массив содержит мусор.
Для получения доступа до первого элемента, в квадратных скобках пишем его номер (индекс). Например

#include #include void main() { int a; a = 10; a = 333; a = 234; printf("%d %d %d", a, a, a); getch(); }

Первый элемент имеет порядковый номер 0. Важно понимать, почему. В дальнейшем будем представлять память компьютера в виде ленты. Имя массива - это указатель на адрес памяти, где располагаются элементы массива.

Рис. 1 Массив хранит адрес первого элемента. Индекс i элемента - это сдвиг на i*sizeof(тип) байт от начала

Индекс массива указывает, на сколько байт необходимо сместиться относительно начала массива, чтобы получить доступ до нужно элемента. Например, если массив A имеет тип int , то A означает, что мы сместились на 10*sizeof(int) байт относительно начала. Первый элемент находится в самом начале и у него смещение 0*sizeof(int) .
В си массив не хранит своего размера и не проверяет индекс массива на корректность. Это значит, что можно выйти за пределы массива и обратиться к памяти, находящейся дальше последнего элемента массива (или ближе).

Начальная инициализация массива.

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

#include #include void main() { int a = {1, 2, 5, 3, 9, 6, 7, 7, 2, 4}; unsigned i; int max; max = a; for (i = 1; i<10; i++) { if (a[i] >

Разберём пример. Сначала мы создаём массив и инициализируем его при создании. После этого присваиваем максимальному найденному элементу значение первого элемента массива.

Max = a;

После чего проходим по массиву. Так как мы уже просмотрели первый элемент (у него индекс 1), то нет смысла снова его просматривать.
Тот же пример, только теперь пользователь вводит значения

#include #include void main() { int a; unsigned i; int max; printf("Enter 10 numbers\n"); for (i = 0; i<10; i++) { printf("%d. ", i); scanf("%d", &a[i]); } max = a; for (i = 1; i<10; i++) { if (a[i] > max) { max = a[i]; } } printf("max element is %d", max); getch(); }

В том случае, если при инициализации указано меньше значений, чем размер массива, остальные элементы заполняются нулями.

#include #include void main() { int a = {1,2,3}; unsigned i; for (i = 0; i<10; i++) { printf("%d ", a[i]); } getch(); }

Если необходимо заполнить весь массив нулями, тогда пишем

Int a = {0};

Можно не задавать размер массива явно, например

Int a = {1, 2, 3};

массив будет иметь размер 3

Размер массива

М ассив в си должен иметь константный размер. Это значит, что невозможно, например, запросить у пользователя размер, а потом задать этот размер массиву.

Printf("Enter length of array "); scanf("%d", &length); { float x; }

Создание динамических массивов будет рассмотрено дальше, при работе с указателями и памятью
В некоторых случаях можно узнать размер массива с помощью функции sizeof.

#include #include void main() { int A; //sizeof возвращает размер всего массива в байтах //Для определения количества элементов необходимо //разделить размер массива на размер его элемента int size = sizeof(A) / sizeof(int); printf("Size of array equals to %d", size); getch(); }

Но это вряд ли будет полезным. При передаче массива в качестве аргумента функции будет передаваться указатель, поэтому размер массива будет невозможно узнать.
Статические массивы удобны, когда заранее известно число элементов. Они предоставляют быстрый, но небезопасный доступ до элементов.

Переполнение массива

П ускай у вас есть такой код

Int A; int i; for (i=0; i<=10; i++) { A[i] = 1; }

Здесь цикл for задан с ошибкой. В некоторых старых версиях компиляторов этот код зацикливался. Дело в том, что переменная i располагалась при компиляции сразу за массивом A . При выходе за границы массива счётчик переводился в 1.
Массивы небезопасны, так как неправильная работа с индексом может приводить к доступу к произвольному участку памяти (Теоретически. Современные компиляторы сами заботятся о том, чтобы вы не копались в чужой памяти).
Если вы работаете с массивами, то необходимо следить за тем, чтобы счётчик не превышал размер массива и не был отрицательным. Для этого, как минимум,

  • 1. Используйте тип size_t для индексирования. Он обезопасит вас от отрицательных значений и его всегда хватит для массива любого размера.
  • 2. Помните, что массив начинается с нуля.
  • 3. Последний элемент массива имеет индекс (размер массива - 1)
Никаких полноценных способов проверки, вышли мы за пределы массива или нет, не существует. Поэтому либо мы точно знаем его размер, либо храним в переменной и считываем при надобности.

Примеры

Т еперь несколько типичных примеров работы с массивами
1. Переворачиваем массив.

#include #include //Это макрос. SIZE в коде будет заменено на 10u #define SIZE 10u void main() { int A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; unsigned i, j; //счётчики unsigned half; //середина массива unsigned tmp; //временная переменная для обмена значениями half = SIZE / 2; //Один счётчик идёт слева напрво, другой справа налево for (i = 0, j = SIZE - 1; i < half; i++, j--) { tmp = A[i]; A[i] = A[j]; A[j] = tmp; } for (i = 0; i < SIZE; i++) { printf("%d ", A[i]); } getch(); }

Здесь незнакомая для вас конструкция

#define SIZE 10u

макрос. Во всём коде препроцессор автоматически заменит все вхождения SIZE на 10u.
2. Удаление элемента, выбранного пользователем.

#include #include #define SIZE 10u void main() { int A = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; unsigned i; //счётчик int index; //индекс, введённый пользователем //Выводим массив for (i = 0; i < SIZE; i++) { printf("(%d)=%d ", i, A[i]); } //Просим пользователя ввести валидный индекс while (1) { printf("\nEnter index of element to delete "); scanf("%d", &index); if (index > 0 && index < SIZE) { break; } } //Копируем следующий элемент массива на место удаляемого //и так до конца for (i = index; i < SIZE-1; i++) { A[i] = A; } //Выводим результат for (i = 0; i < SIZE-1; i++) { printf("(%d)=%d ", i, A[i]); } getch(); }

Удаление элемента в данном случае, конечно, не происходит. Массив остаётся того же размера, что и раньше. Мы просто затираем удаляемый элемент следующим за ним и выводим SIZE-1 элементов.
3. Пользователь вводит значения в массив. После этого вывести все разные значения, которые он ввёл.
Пусть пользователь вводит конечное число элементов, допустим 10. Тогда заранее известно, что всего различных значений будет не более 10. Каждый раз, когда пользователь вводит число будем проходить по массиву и проверять, было ли такое число введено.

#include #include #define SIZE 10u void main() { int A = {0}; unsigned i, j; int counter = 1; //сколько разных чисел введено. Как минимум одно. int input; int wasntFound; //флаг, что введённое число не было найдено //Вводим первое число. Оно ещё не встречалось. printf("0. "); scanf("%d", &A); for (i = 1; i < SIZE; i++) { printf("%d. ", i); scanf("%d", &input); wasntFound = 1; //Проверяем, встречалось ли такое число. Если да, //то выставляем флаг и выходим из цикла for (j = 0; j <= counter; j++) { if (input == A[j]) { wasntFound = 0; break; } } //Если флаг был поднят, то заносим число в массив if (wasntFound) { A = input; counter++; } } for (i = 0; i < counter; i++) { printf("%d ", A[i]); } getch(); }

4. Пользователь вводит число - количество измерений (от 2 до 10). После этого вводит все измерения. Программа выдаёт среднее значение, дисперсию, погрешность.

#include #include #include #define SIZE 20u void main() { //Коэффициенты Стьюдента идут, начиная с двух измерений const float student = {12.7, 4.3, 3.2, 2.8, 2.6, 2.4, 2.4, 2.3, 2.3}; float A; unsigned i; unsigned limit; float tmp; float sum = .0f; float mean; float disp; float absError; float relError; do { printf("Enter number of measurements "); scanf("%u", &limit); if (limit > 1 && limit < 11) { break; } } while(1); for (i = 0; i < limit; i++) { printf("#%d: ", i); scanf("%f", &A[i]); sum += A[i]; } mean = sum / (float)limit; sum = .0f; for (i = 0; i < limit; i++) { tmp = A[i] - mean; sum += tmp * tmp; } disp = sum / (float)limit; absError = student * sqrt(sum / (float)(limit - 1)); relError = absError / mean * 100; printf("Mean = %.6f\n", mean); printf("Dispertion = %.6f\n", disp); printf("Abs. Error = %.6f\n", absError); printf("Rel. Error = %.4f%", relError); getch(); }

5. Сортировка массива пузырьком

#include #include #define SIZE 10 #define false 0 #define true !false void main() { float a = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 0.0f}; float tmp; unsigned i, j; char flag; //Выводи массив for (i = 0; i < SIZE; i++) { printf("%.3f ", a[i]); } printf("\n"); //Пока массив не отсортирован do { flag = false; //Проходим по массиву. Если следующий элемент больше предыдущего, то //меняем их местами и по новой проверяем массив for (i = 1; i < SIZE; i++) { if (a[i] > a) { tmp = a[i]; a[i] = a; a = tmp; flag = true; } } } while(flag == true); //Выводим отсортированный массив for (i = 0; i < SIZE; i++) { printf("%.3f ", a[i]); } getch(); }

6. Перемешаем массив. Воспользуемся для этого алгоритмом

Массивы

Массив представляет собой совокупность переменных одного типа с общим для обращения к ним именем. В C# массивы могут быть как одномерными, так и многомерными. Массивы служат самым разным целям, поскольку они предоставляют удобные средства для объединения связанных вместе переменных.

Массивами в C# можно пользоваться практически так же, как и в других языках программирования. Тем не менее у них имеется одна особенность: они реализованы в виде объектов.

Для тoго чтобы воспользоваться массивом в программе, требуется двухэтапная процедура, поскольку в C# массивы реализованы в виде объектов. Во-первых, необходимо объявить переменную, которая может обращаться к массиву. И во-вторых, нужно создать экземпляр массива, используя оператор new.

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { // Объявляем массив int myArr = new int; // Инициализируем каждый элемент массива вручную myArr = 100; myArr = 23; myArr = 25; myArr = 31; myArr = 1; foreach (int i in myArr) Console.WriteLine(i); Console.ReadLine(); } } }

Следует иметь в виду, что если массив только объявляется, но явно не инициализируется, каждый его элемент будет установлен в значение, принятое по умолчанию для соответствующего типа данных (например, элементы массива типа bool будут устанавливаться в false, а элементы массива типа int - в 0).

Инициализация массива

Помимо заполнения массива элемент за элементом (как показано в предыдущем примере), можно также заполнять его с использованием специального синтаксиса инициализации массивов. Для этого необходимо перечислить включаемые в массив элементы в фигурных скобках { }. Такой синтаксис удобен при создании массива известного размера, когда нужно быстро задать его начальные значения:

// Синтаксис инициализации массива с использованием // ключевого слова new int myArr = new int {10,20,30,40,50}; // Синтаксис инициализации массива без использования // ключевого слова new string info = { "Фамилия", "Имя", "Отчество" }; // Используем ключевое слово new и желаемый размер char symbol = new char { "X","Y","Z","M" };

Обратите внимание, что в случае применения синтаксиса с фигурными скобками размер массива указывать не требуется (как видно на примере создания переменной myArr), поскольку этот размер автоматически вычисляется на основе количества элементов внутри фигурных скобок. Кроме того, применять ключевое слово new не обязательно (как при создании массива info).

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

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { var arr1 = new { 1, 2, 3 }; Console.WriteLine("Тип массива arr1 - {0}",arr1.GetType()); var arr2 = new { "One", "Two", "Three" }; Console.WriteLine("Тип массива arr2 - {0}",arr2.GetType()); Console.ReadLine(); } } }

Разумеется, как и при создании массива с использованием явного синтаксиса C#, элементы, указываемые в списке инициализации массива, должны обязательно иметь один и тот же базовый тип (т.е. должны все быть int, string или MyCar).

Определение массива объектов

В большинстве случаев при определении массива тип элемента, содержащегося в массиве, указывается явно. Хотя на первый взгляд это выглядит довольно понятно, существует одна важная особенность. В основе каждого типа в системе типов.NET (в том числе фундаментальных типов данных) в конечном итоге лежит базовый класс System.Object . В результате получается, что в случае определения массива объектов находящиеся внутри него элементы могут представлять собой что угодно:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { // Объявляем и инициализируем массив объектов object arrByObject = { true, 10, "Привет", 13.7m }; // Выведем в консоль тип каждого члена массива foreach (object me in arrByObject) Console.WriteLine("Тип {0} - {1}",me,me.GetType()); Console.ReadLine(); } } }

Массив это структура данных, представленная в виде группы ячеек одного типа, объединенных под одним единым именем. Массивы используются для обработки большого количества однотипных данных. Имя массива является , что такое указатели расскажу немного позже. Отдельная ячейка данных массива называется элементом массива. Элементами массива могут быть данные любого типа. Массивы могут иметь как одно, так и более одного измерений. В зависимости от количества измерений массивы делятся на одномерные массивы, двумерные массивы, трёхмерные массивы и так далее до n-мерного массива. Чаще всего в программировании используются одномерные и двумерные массивы, поэтому мы рассмотрим только эти массивы.

Одномерные массивы в С++

Одномерный массив — массив, с одним параметром, характеризующим количество элементов одномерного массива. Фактически одномерный массив — это массив, у которого может быть только одна строка, и n-е количество столбцов. Столбцы в одномерном массиве — это элементы массива. На рисунке 1 показана структура целочисленного одномерного массива a . Размер этого массива — 16 ячеек.

Рисунок 1 — Массивы в С++

Заметьте, что максимальный индекс одномерного массива a равен 15, но размер массива 16 ячеек, потому что нумерация ячеек массива всегда начинается с 0. Индекс ячейки – это целое неотрицательное число, по которому можно обращаться к каждой ячейке массива и выполнять какие-либо действия над ней (ячейкой).

//синтаксис объявления одномерного массива в С++: /*тип данных*/ /*имя одномерного массива*/; //пример объявления одномерного массива, изображенного на рисунке 1: int a;

где, int —целочисленный ;

А — имя одномерного массива;
16 — размер одномерного массива, 16 ячеек.

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

//ещё один способ объявления одномерных массивов int mas, a;

Объявлены два одномерных массива mas и а размерами 10 и 16 соответственно. Причём в таком способе объявления все массивы будут иметь одинаковый тип данных, в нашем случае — int .

// массивы могут быть инициализированы при объявлении: int a = { 5, -12, -12, 9, 10, 0, -9, -12, -1, 23, 65, 64, 11, 43, 39, -15 }; // инициализация одномерного массива

Инициализация одномерного массива выполняется в фигурных скобках после знака равно , каждый элемент массива отделяется от предыдущего запятой.

Int a={5,-12,-12,9,10,0,-9,-12,-1,23,65,64,11,43,39,-15}; // инициализации массива без определения его размера.

В данном случае компилятор сам определит размер одномерного массива. Размер массива можно не указывать только при его инициализации, при обычном объявлении массива обязательно нужно указывать размер массива. Разработаем простую программу на обработку одномерного массива.

// array.cpp: определяет точку входа для консольного приложения. #include "stdafx.h" #include << "obrabotka massiva" << endl; int array1 = { 5, -12, -12, 9, 10, 0, -9, -12, -1, 23, 65, 64, 11, 43, 39, -15 }; // объявление и инициализация одномерного массива cout << "indeks" << "\t\t" << "element massiva" << endl; // печать заголовков for (int counter = 0; counter < 16; counter++) //начало цикла { //вывод на экран индекса ячейки массива, а затем содержимого этой ячейки, в нашем случае - это целое число cout << "array1[" << counter << "]" << "\t\t" << array1 << endl; } system("pause"); return 0; }

// код Code::Blocks

// код Dev-C++

// array.cpp: определяет точку входа для консольного приложения. #include using namespace std; int main(int argc, char* argv) { cout << "obrabotka massiva" << endl; int array1 = { 5, -12, -12, 9, 10, 0, -9, -12, -1, 23, 65, 64, 11, 43, 39, -15 }; // объявление и инициализация одномерного массива cout << "indeks" << "\t\t" << "element massiva" << endl; // печать заголовков for (int counter = 0; counter < 16; counter++) //начало цикла { //вывод на экран индекса ячейки массива, а затем содержимого этой ячейки, в нашем случае - это целое число cout << "array1[" << counter << "]" << "\t\t" << array1 << endl; } return 0; }

В строках 10 — 11 объявлен и проинициализирован целочисленный одномерный массив с именем array1 , размер которого равен 16 ячейкам, то есть такой массив может хранить 16 чисел. Любая обработка массива осуществима только совместно с циклами. Какой цикл выбрать для обработки массива — это вам решать. Но лучше всего для этой задачи подходит . Переменную-счётчик counter будем использовать для обращения к элементам одномерного массива array1 . В условии продолжения цикла for стоит строгий знак неравенства, так как шестнадцатого индекса в одномерном массиве array1 нет. А так как нумерация ячеек начинается с нуля, то элементов в массиве 16. В теле цикла for оператор cout печатает элементы одномерного массива (см. Рисунок 2).

Obrabotka massiva indeks element massiva array1 5 array1 -12 array1 -12 array1 9 array1 10 array1 0 array1 -9 array1 -12 array1 -1 array1 23 array1 65 array1 64 array1 11 array1 43 array1 39 array1 -15 Для продолжения нажмите любую клавишу. . .

Рисунок 2 — Массивы в С++

Разработаем ещё одну программу на обработку одномерного массива в С++. Программа должна последовательно считывать десять введённых чисел с клавиатуры. Все введённые числа просуммировать, результат вывести на экран.

// array_sum.cpp: определяет точку входа для консольного приложения. #include "stdafx.h" #include << "Enter elementi massiva: " << endl; int sum = 0; for (int counter = 0; counter < 10; counter++) // цикл для считывания чисел cin >> << "array1 = {"; for (int counter = 0; counter < 10; counter++) // цикл для вывода элементов массива cout << array1 << " "; // выводим элементы массива на стандартное устройство вывода for (int counter = 0; counter < 10; counter++) // цикл для суммирования чисел массива sum += array1; // суммируем элементы массива cout << "}\nsum = " << sum << endl; system("pause"); return 0; }

// код Code::Blocks

// код Dev-C++

// array_sum.cpp: определяет точку входа для консольного приложения. #include using namespace std; int main(int argc, char* argv) { int array1; // объявляем целочисленный массив cout << "Enter elementi massiva: " << endl; int sum = 0; for (int counter = 0; counter < 10; counter++) // цикл для считывания чисел cin >> array1; // считываем вводимые с клавиатуры числа cout << "array1 = {"; for (int counter = 0; counter < 10; counter++) // цикл для вывода элементов массива cout << array1 << " "; // выводим элементы массива на стандартное устройство вывода for (int counter = 0; counter < 10; counter++) // цикл для суммирования чисел массива sum += array1; // суммируем элементы массива cout << "}\nsum = " << sum << endl; return 0; }

Перед тем как выполнять обработку массива его необходимо объявить, причём размер одномерного массива равен 10, так как это оговорено условием задачи. В переменной sum будем накапливать сумму элементов одномерного массива. Первый цикл for заполняет объявленный одномерный массив, введёнными с клавиатуры числами, строки 12 — 13 . Переменная счётчик counter используется для последовательного доступа к элементам одномерного массива array1 , начиная с индекса 0 и до 9-го включительно. Второй цикл for выводит на экран элементы массива, строки 15 — 16 . Третий цикл for последовательно считывает элементы одномерного массива и суммирует их, сумма накапливается в переменной sum , строки 17 — 18 . Результат работы программы смотреть на рисунке 3.

Enter elementi massiva: 0 1 2 3 4 5 6 7 8 9 array1 = {0 1 2 3 4 5 6 7 8 9 } sum = 45 Для продолжения нажмите любую клавишу. . .

Рисунок 3 — Массивы в С++

Сначала последовательно были введены все 10 чисел, после чего отобразился одномерный массив, и напечаталась сумма чисел массива.

Двумерные массивы в С++

До этого момента мы рассматривали одномерные массивы, которыми не всегда можно ограничиться. Допустим, необходимо обработать некоторые данные из таблицы. В таблице есть две характеристики: количество строк и количество столбцов. Также и в двумерном массиве, кроме количества элементов массива, есть такие характеристики как, количество строк и количество столбцов двумерного массива. То есть, визуально, двумерный массив — это обычная таблица, со строками и столбцами. Фактически двумерный массив — это одномерный массив одномерных массивов. Структура двумерного массива, с именем a , размером m на n показана ниже (см. Рисунок 4).

Рисунок 4 — Массивы в С++

где, m — количество строк двумерного массива;
n — количество столбцов двумерного массива;
m * n — количество элементов массива.

// синтаксис объявления двумерного массива /*тип данных*/ /*имя массива*/;

В объявлении двумерного массива, также как и в объявлении одномерного массива, первым делом, нужно указать:

  • тип данных;
  • имя массива.

После чего, в первых квадратных скобочках указывается количество строк двумерного массива, во вторых квадратных скобочках — количество столбцов двумерного массива. Двумерный массив визуально отличается от одномерного второй парой квадратных скобочек. Рассмотрим пример объявления двумерного массива. Допустим нам необходимо объявить двумерный массив, с количеством элементов, равным 15. В таком случае двумерный массив может иметь три строки и пять столбцов или пять строк и три столбца.

// пример объявление двумерного массива: int a;

  • a — имя целочисленного массива
  • число в первых квадратных скобках указывает количество строк двумерного массива, в данном случае их 5;
  • число во вторых квадратных скобках указывает количество столбцов двумерного массива, в данном случае их 3.

// инициализация двумерного массива: int a = { {4, 7, 8}, {9, 66, -1}, {5, -5, 0}, {3, -3, 30}, {1, 1, 1} };

В данном массиве 5 строк, 3 столбца. после знака присвоить ставятся общие фигурные скобочки, внутри которых ставится столько пар фигурных скобочек, сколько должно быть строк в двумерном массиве, причём эти скобочки разделяются запятыми. В каждой паре фигурных скобочек записывать через запятую элементы двумерного массива. Во всех фигурных скобочках количество элементов должно совпадать. Так как в массиве пять строк, то и внутренних пар скобочек тоже пять. Во внутренних скобочках записаны по три элемента, так как количество столбцов — три. Графически наш массив будет выглядеть, как двумерная таблица (см. Рисунок 5).

Рисунок 5 — Массивы в С++

В каждой ячейке двумерного массива a показано значение, в нижнем правом углу показан адрес данной ячейки. Адресом ячейки двумерного массива является имя массива, номер строки и номер столбца.

Разработаем несложную программу, на обработку двумерного массива, которая называется «Лабиринт». Лабиринт должен быть построен на основе двумерного массива. Размер лабиринта выберем на свое усмотрение.

// array2.cpp: определяет точку входа для консольного приложения. #include "stdafx.h" #include < 33; i++) //переключение по строкам { for (int j = 0; j < 20; j++)// переключение по столбцам if (mas[i][j] == 1) { // вывести два раза символ (номер которого 176 в таблице аски) в консоль cout << static_cast(176); cout << static_cast(176); } else cout << " "; // вывести два пробела cout << endl; } system("pause"); return 0; }

// код Code::Blocks

// код Dev-C++

// array2.cpp: определяет точку входа для консольного приложения. #include using namespace std; int main(int argc, char* argv) { // 1-условно "стенки лабиринта" // 2-"правильный путь, выход из лабиринта" // 0-"ложный путь" int mas = { {1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}, // инициализация двумерного массива {1,2,1,0,0,1,0,1,2,2,2,1,1,1,1,0,0,0,0,1,}, {1,2,1,1,0,1,0,1,2,1,2,2,2,2,1,0,1,1,0,1,}, {1,2,2,2,2,2,2,1,2,1,1,1,1,2,1,0,0,1,0,1,}, {1,1,1,1,1,1,2,1,2,1,0,0,1,2,1,1,0,1,0,1,}, {1,0,0,1,0,0,2,2,2,1,1,0,0,2,0,0,0,1,0,1,}, {1,0,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,1,0,1,}, {1,0,0,0,0,0,0,0,0,1,1,1,1,2,1,0,0,0,0,1,}, {1,1,1,1,1,1,0,1,1,1,2,2,2,2,1,0,1,1,1,1,}, {1,1,0,0,0,1,0,0,1,1,2,1,1,1,1,0,0,0,0,1,}, {1,0,0,1,0,0,0,0,0,1,2,2,2,2,1,1,1,1,0,1,}, {1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,0,0,0,1,}, {1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0,1,1,1,1,}, {1,2,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,}, {1,2,1,0,0,0,1,2,2,2,1,0,0,0,0,0,1,1,0,1,}, {1,2,1,1,1,1,1,2,1,2,1,1,1,0,1,0,0,0,0,1,}, {1,2,1,2,2,2,1,2,1,2,2,2,1,1,1,1,1,1,1,1,}, {1,2,1,2,1,2,1,2,1,0,1,2,2,2,2,2,2,2,2,1,}, {1,2,1,2,1,2,1,2,1,0,1,1,1,1,1,1,1,1,2,1,}, {1,2,1,2,1,2,1,2,1,0,0,0,0,0,0,0,0,0,2,1,}, {1,2,1,2,1,2,2,2,1,0,1,1,1,1,1,1,0,1,2,1,}, {1,2,1,2,1,1,1,1,1,0,0,0,1,0,1,0,0,1,2,1,}, {1,2,1,2,2,1,0,0,1,1,1,0,0,0,1,0,1,1,2,1,}, {1,2,1,1,2,1,1,0,0,0,0,0,1,0,1,0,0,1,2,1,}, {1,2,1,1,2,1,0,0,1,1,1,1,1,1,1,1,1,1,2,1,}, {1,2,1,1,2,1,1,0,1,2,2,2,2,2,2,2,2,2,2,1,}, {1,2,1,1,2,1,0,0,1,2,1,1,1,1,1,1,1,1,1,1,}, {1,2,1,1,2,1,0,1,1,2,1,1,1,1,1,1,1,1,2,2,}, {1,2,1,1,2,1,0,0,1,2,1,1,2,2,2,2,2,2,2,1,}, {1,2,1,1,2,1,0,1,1,2,1,1,2,1,1,1,1,1,1,1,}, {1,2,1,1,2,1,0,0,1,2,1,1,2,1,0,0,0,1,0,1,}, {1,2,2,2,2,1,0,1,1,2,2,2,2,0,0,1,0,0,0,1,}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,} }; // два цикла - внутренний и внешний, осуществляющие обращение к каждому элементу массива for (int i = 0; i < 33; i++) //переключение по строкам { for (int j = 0; j < 20; j++)// переключение по столбцам if (mas[i][j] == 1) { // вывести два раза символ (номер которого 176 в таблице аски) в консоль cout << static_cast(176); cout << static_cast(176); } else cout << " "; // вывести два пробела cout << endl; } return 0; }

Правильный и ложный пути можно было бы обозначать одной и той же цифрой, например, нулём, но для наглядности правильный путь обозначен цифрой 2. Инициализация массива выполнялась вручную, только для того, что бы упростить программу. Так как в программе выполняется обработка двумерного массива, нужны два цикла, для переключения между элементами двумерного массива. Первый цикл for выполняет переключение между строками двумерного массива. Так как строк в двумерном массиве 33, то и переменная-счетчик i инкрементируется от 0 до 33, строка 46 . Внутри первого цикла стоит цикл for , который переключается между элементами строки двумерного массива. В теле второго цикла for внутри выполняетcя унарная операция преобразования типа данных — static_cast<>() , которая печатает символ , под номером 176. операция преобразования типов данных дублируется для увеличения ширины лабиринта. Результат работы программы (см. Рисунок 6).

Рисунок 6 — Массивы в С++

Loading...Loading...