Массивы значений в С++

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

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;
}

Результат работы программы:

CppStudio.com
Первый массив:            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. В результате компиляции будет ошибка:

main.cpp:10: error: no match for ‘operator*’ (operand types are ‘int’ and ‘std::valarray<float>’)

Ошибка говорит о том, что тип данных у множимого — 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 — индекс последнего элемента массивов. Поэтому в результате выполнения сравнения мы получим массив булевых значений. Остальные операции отношения: >, ==, >=, <= действуют также. Результат работы предыдущей программы:

CppStudio.com
Первый массив: 5 7 4 2 2 
Второй массив: 7 7 7 7 7 
Результат:     1 0 1 1 1

Из результата видно, что второй элемент массива array1 не меньше второго элемента массива array2, поэтому в массиве res второй элемент — 0. Во всех остальных случаях результат сравнивания значений получился истинным.

Также вам полезно будет узнать о существовании таких функций как:
sum() — возвращает суму элементов одного множества;
max() — возвращает первое максимальное значение множества;
min() — возвращает первое минимальное значение множества;

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

Автор: Marienko L.
Дата: 25.01.2014
Поделиться:

Комментарии

  1. olegovich22

    Даже, если бы вместо типа данных int был тип данных double, это все равно считается несоответствием типов данных.

     

    Возможно в данной ситуации имелось в  виду не int, а float.

  2. Sergrey

    Классная статья. Все понятненко написано, не знал о таких возможностях. Обязательно буду использовать в будущем. Автору спасибо

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.