Массив значений может вам облегчить работу с векторами и матрицами, так как обладает очень важным свойством — свойством простотой записи. Например, два массива можно умножить так :
ar3 = ar1 * ar2;
Достаточно простая запись, не правда ли? Кроме умножения, массивы значений также поддерживают все остальные арифметические операции: +
, -
, /
и даже операцию — остаток от деления. По сути, массив значений — это одномерный массив, нумерация элементов которого, как и в обычных массивах, начинается с нуля. Чтобы воспользоваться массивом значений, достаточно подключить заголовочный файл — valarray
:
#include <valarray>
Давайте рассмотрим пример использования массива значений в следующей программе:
#include <iostream> #include <valarray> // заголовочный файл массивов значений #include <cstdlib> #include <iomanip> using namespace std; int main() { srand(time(NULL)); valarray<int> array1(15); // создаем массив значений размером - 15 элементов valarray<int> array2(15); // создаем массив значений размером - 15 элементов cout << setw(38) << left << "Первый массив: "; for(int i = 0; i < array1.size(); i++) { array1[i] = rand() % 10; cout << setw(2) << array1[i] << " "; } cout << endl << setw(38) << "Второй массив: "; for(int i = 0; i < array2.size(); i++) { array2[i] = rand() % 10; cout << setw(2) << array2[i] << " "; } cout << "\nСумма элементов массивов: "; valarray<int> array3 = array1 + array2; for(int i = 0; i < array3.size(); i++) { cout << setw(2) << array3[i] << " "; } return 0; }
Результат работы программы:
Первый массив: 5 3 0 0 1 6 5 3 4 7 1 7 0 0 9 Второй массив: 0 5 6 6 0 9 3 8 3 0 8 9 3 7 4 Сумма элементов массивов: 5 8 6 6 1 15 8 11 7 7 9 16 3 7 13
В строке 2 мы подключили заголовок массивов значений. Строки 10-11, это пример того, как нужно объявлять массивы значений. Ничего сложного в этом нет, как всегда, сначала указывается тип данных, в нашем случае — int
. В круглых скобках указан размер одномерного массива — количество элементов. Строки 14-23 просто инициализируют и выводят на экран элементы массивов. Обратите внимание на строку 26, тут выполняется операция сложения одномерных массивов, эта запись вмещается всего в одну строку. Попробуйте сделать тоже самое с обычными массивами. Ничего у вас не получится, так как с обычными массивами придется использовать как минимум цикл, который будет перебирать каждый элемент всех трех массивов. С помощью массивов значений, это делается всего в одну строку:
valarray<int> array3 = array1 + array2;
Вот ради такого упрощения записей и стоит пользоваться этим классом — <valarray>
. Давайте еще рассмотрим случай с обычным массивом, например, у нас есть одномерный массив:
int ar[5] = {1, 7, 34, 23, 56};
Мы можем создать объект массива значений используя массив ar
. При объявлении массива значений достаточно в первом параметре указать имя массива, а во втором — размер массива, как показано в примере ниже:
valarray<int> array1(ar, sizeof(ar)/sizeof(ar[0]));
Таким образом мы получим, массив значений, инициализированный элементами статического массива С++. Еще необходимо запомнить такую вещь, если мы выполняем какие-то арифметические операции с массивами значений, их типы данных должны быть одинаковыми, в противном случае возникнет ошибка. Вот пример:
valarray<float> array(5); array = 4 * array; // ошибка
Как видно из фрагмента кода, в нем объявлен массив значений — array
. После этого, во второй строке выполняется умножение, каждого элемента массива на значение 4
. В результате компиляции будет ошибка:
Ошибка говорит о том, что тип данных у множимого — int
, а у множителя — float
. Типы данных различны, и по этой причине умножение не может выполняться. Поэтому, необходимо сделать так:
array = float(4) * array;
Даже, если бы вместо типа данных int
был тип данных double
, это все равно считается несоответствием типов данных. Помните об этом и не допускайте таких ошибок. Давайте вернемся к операторам сравнения. Как и в других контейнерах STL, в valarray
операции отношений также перегружены, но возвращаемый ими результат в корне отличается. К примеру, рассмотрим следующий код:
#include <iostream> #include <valarray> // заголовочный файл массивов значений #include <cstdlib> using namespace std; int main() { srand(time(NULL)); // создаем два массива значений типа int на 5 элементов valarray<int> array1(5); valarray<int> array2(5); cout << "Первый массив: "; for(int i = 0; i < array1.size(); i++) { cout << (array1[i] = rand() % 10) << " "; } array2 = rand() % 10; // всем элементам массива array2 присвоили случайное значение cout << "\nВторой массив: "; for(int i = 0; i < array2.size(); i++) { cout << array2[i] << " "; } valarray<bool> res(5); res = (array1 < array2); // в результате выполнения этой операции возвращается массив булевых значений cout << "\nРезультат: "; for(int i = 0; i < res.size(); i++) { cout << res[i] << " "; } return 0; }
Посмотрите на строку 19, в ней мы присваиваем каждому элементу массива значений array2
случайное число, при этом мы воспользовались лишь операцией присваивания. Конечно же, гвоздем программы является код в строке 27. На первый взгляд может показаться, что результатом будет одно логическое значение: true
или false
. На самом деле это не так. На самом деле, эта строка:
res = (array1 < array2);
делает следующее:
res[0] = (array1[0] < array2[0]); res[1] = (array1[1] < array2[1]); res[2] = (array1[2] < array2[2]); . . . res[n] = (array1[n] < array2[n]);
где n
— индекс последнего элемента массивов. Поэтому в результате выполнения сравнения мы получим массив булевых значений. Остальные операции отношения: >
, ==
, >=
, <=
действуют также. Результат работы предыдущей программы:
Первый массив: 5 7 4 2 2 Второй массив: 7 7 7 7 7 Результат: 1 0 1 1 1
Из результата видно, что второй элемент массива array1
не меньше второго элемента массива array2
, поэтому в массиве res
второй элемент — 0
. Во всех остальных случаях результат сравнивания значений получился истинным.
Также вам полезно будет узнать о существовании таких функций как:
sum()
— возвращает суму элементов одного множества;
max()
— возвращает первое максимальное значение множества;
min()
— возвращает первое минимальное значение множества;
На этом все, надеюсь все было понятно и интересно. Вопросы, пожалуйста, задавайте в комментариях или на форуме.
Комментарии
olegovich22
Даже, если бы вместо типа данных
int
был тип данныхdouble
, это все равно считается несоответствием типов данных.Возможно в данной ситуации имелось в виду не int, а float.
Sergrey
Классная статья. Все понятненко написано, не знал о таких возможностях. Обязательно буду использовать в будущем. Автору спасибо