C++. Класс vector. Методы, обеспечивающие доступ к элементам массива

Класс vector. Методы, обеспечивающие доступ к элементам массива. Методы at(), front(), back(), data(), begin(), end(), cbegin(), cend(), rbegin(), rend(), crbegin(), crend()

Перед изучением данной темы рекомендуется ознакомиться со следующей темой:


Содержание


Поиск на других ресурсах:

1. Метод at(). Получить элемент вектора по его позиции

Метод at() используется для доступа к конкретному элементу массива на основе заданного индекса. Метод имеет 2 перегруженные реализации

const T& at(const size_t _Pos) const
T& at(const size_t _Pos)

здесь T – тип элементов массива.

Первая реализация используется для чтения элемента из массива. Вторая реализация используется для изменения элемента массива.

Пример.

...

// Метод at() - получить элемент вектора по его позиции
vector<double> A(5); // Создать массив из 5 элементов типа double

// Заполнить произвольными значениями
A[0] = 2.8;
A[1] = 3.3;
A[2] = 4.5;
A[3] = 7.3;
A[4] = 8.8;

// Считать элемент по индексу 2
double x = A.at(2); // x = 4.5

// Изменить значение элемента по индексу 2
A.at(2) = 3.7;

...

 

2. Метод front(). Возвращает ссылку на первый элемент вектора

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

const T& front() const
T& front()

Первая реализация метода позволяет считывать значение первого элемента массива. Вторая реализация позволяет записывать значения в первый элемент массива.

Пример.

...

// Метод front() - получить значение первого элемента массива.
// 1. Объявить массив из 5 элементов типа float
vector<float> A(5);

// 2. Заполнить массив данными
A[0] = 2.88f;
A[1] = 3.8f;
A[2] = 4.4f; 
A[3] = 4.9f;
A[4] = 5.5f;

// 3. Считать и вывести на экран значение первого элемента вектора
float x = A.front();
cout << x << endl; // 2.88

...

 

3. Метод back(). Возвращает ссылку на последний элемент вектора

Чтобы получить доступ к последнему элементу вектора используется метод back(). Этот метод имеет 2 перегруженных реализации, синтаксис объявления которых следующий

const T& back() const
T& back()

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

Пример.

...

// Метод back() - получить значение последнего элемента массива.
// 1. Объявить массив из 5 элементов типа float
vector<float> A(5);

// 2. Заполнить массив данными
A[0] = 2.88f;
A[1] = 3.8f;
A[2] = 4.4f; 
A[3] = 4.9f;
A[4] = 5.5f;

// 3. Считать и вывести на экран значение последнего элемента массива
float x = A.back();
cout << x << endl; // 5.5

// 4. Изменить последний элемент массива
A.back() = 7.9f; // A[4] = 7.9
cout << A[4] << endl; // 7.9

...

 

4. Метод data(). Получить указатель на вектор

Метод data() позволяет получить указатель на динамический массив. С помощью этого указателя можно иметь доступ к элементам вектора как к обычному массиву.

Синтаксис объявления метода следующий:

T* vector<T>::data()

тут T – тип элементов вектора.

Пример.

...

// Метод data() - получить указатель на вектор.
// 1. Объявить вектор из 10 элементов типа short.
vector<short> A(10);

// 2. Заполнить массив данными
for (int i = 0; i < A.size(); i++)
  A.at(i) = i;

// 3. Получить указатель на вектор
short* p = A.data();

// 4. С помощью указателя p вывести элементы вектора на экран
for (int i=0; i<A.size(); i++)
  cout << *(p + i) << " ";

// 5. Вывести элемент вектора с индексом 2
cout << endl;
cout << p[2] << endl; // 2

...

 

5. Метод begin(). Вернуть итератор, указывающий на первый элемент вектора

Метод begin() возвращает итератор, указывающий на первый элемент динамического массива. Метод имеет следующую общую форму:

vector<T>::iterator vector<T>::begin()

здесь T – тип элементов массива.

Пример.

...

// Метод begin() - возвращает итератор, установленный на первый элемент вектора
// 1. Объявить вектор из 5 элементов типа char
vector<char> A(5);

// 2. Заполнить массив данными
A[0] = 'a';
A[1] = 'b';
A[2] = 'c';
A[3] = 'd';
A[4] = 'e';

// 3. Объявить итератор на массив элементов типа char
vector<char>::iterator pA;

// 4. Установить итератор на начало массива и вывести первый элемент
pA = A.begin(); // *pA = 'a'
cout << *pA << endl;

...

 

6. Метод end(). Вернуть итератор, указывающий на последний элемент массива

Метод end() устанавливает итератор на конец массива. Это означает, что итератор установлен на элемент, следующий за последним элементом массива.

C++. STL. Класс vector. Установка итераторов методами begin() и end()

Рисунок 1. Установка итераторов методами begin() и end(). Размер массива size()

Синтаксис объявления метода следующий

vector<T>::iterator vector<T>::end()

Пример.

...

// Метод end() - возвращает итератор, установленный на конец массива.
// 1. Объявить вектор из 5 элементов типа char.
vector<char> A(5);

// 2. Заполнить массив данными
A[0] = 'a';
A[1] = 'b';
A[2] = 'c';
A[3] = 'd';
A[4] = 'e';

// 3. Объявить итератор на массив элементов типа char
vector<char>::iterator pA;

// 4. Установить итератор на конец массива
pA = A.end(); // pA указывает на позицию установленную за последним элементом массива

// 5. Перейти на последний элемент массива
pA--; // *pA = 'e'
cout << *pA << endl;

...

 

7. Методы cbegin(), cend(). Установить константный итератор на начало и конец массива

При работе с итераторами, кроме обычных итераторов различают константные итераторы. В библиотеке STL стандартный итератор объявляется с использованием типа iterator

vector<T>::iterator It;

Константный итератор объявляется с использованием типа constant_iterator

vector<T>::constant_iterator ConstIt;

здесь

  • T – тип элементов массива;
  • constant_iterator – тип, определяющий константный итератор;
  • ConstIt – имя константного итератора.

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

*ConstIt = value;

вызовет ошибку компиляции.

Методы cbegin() и cend() предназначены для получения константного итератора, который указывает соответственно на начало и конец массива. Общая форма объявления методов следующая

vector<T>::const_iterator cbegin() const
vector<T>::const_iterator cend() const

здесь T – тип элементов массива.

Метод cend() возвращает итератор, указывающий на элемент, следующий за последним элементом массива.

Пример.

...

// Константный итератор const_iterator
// 1. Создать массив целых чисел на основе списка инициализации
initializer_list<int> L = { 1, 2, 3, 4, 5 };
vector<int> A1(L); // A1 = { 1, 2, 3, 4, 5 }

// 2. Объявить константный итератор it на начало вектора A1
vector<int>::const_iterator it = A1.cbegin();

// 3. С помощью константного итератора вывести элементы вектора A1
cout << "A1 = ";
while (it != A1.cend())
  cout << *it++ << " ";
cout << endl;

// 4. Попытка изменения значения по константному итератору вызовет ошибку компиляции
it = A1.cbegin();
//*it = 8; // ошибка компиляции

...

 

8. Методы rbegin(), rend(). Доступ к элементам массива с помощью реверсного итератора

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

Реверсный итератор объявляется с использованием ключевого слова reverse_iterator

vector<T>::reverse_iterator itReverse;

здесь

  • T – тип элементов вектора;
  • itReverse – имя итератора.

Методы rbegin() rend () работают с реверсными итераторами. Они позволяют получить итераторы, указывающие соответственно на начало (rbegin) и конец (rend) массива. Методы имеют следующие перегруженные реализации

reverse_iterator<vector<T>::iterator> rbegin()
reverse_iterator<vector<T>::const_iterator> rbegin() const
reverse_iterator<vector<T>::iterator> rend()
reverse_iterator<vector<T>::const_iterator> rend() const

Одна из реализаций методов rbegin() и rend() позволяет работать как обычный итератор, допускающий чтение/запись. Вторая реализация этих методов работает как константный итератор, допускающий только чтение.

Пример.

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Реверсный итератор const_iterator
  // 1. Создать массив вещественных чисел на основе списка инициализации
  initializer_list<double> L = { 1.5, 2.2, 3.4, 4.1, 5.8 };
  vector<double> A1(L); // A1 = { 1.5, 2.2, 3.4, 4.1, 5.8 };

  // 2. Объявить реверсный итератор itReverse на тип double
  vector<double>::reverse_iterator itReverse;

  // 3. Установить реверсный итератор на начало вектора A1
  itReverse = A1.rbegin();

  // 4. Вывести первый элемент массива
  cout << "begin: " << *itReverse << endl;

  // 5. С помощью реверсного итератора вывести элементы всего вектора A1.
  // Важно: элементы выводятся в обратном порядке
  cout << "A1 = ";
  while (itReverse != A1.rend())
  {
    cout << *itReverse << " ";
    itReverse++; // прирост итератора смещается от конца к началу
  }
  cout << endl;

  // 6. Изменить значение элемента с индексом 3
  itReverse = A1.rbegin() + 3; // индексация элементов идет от конца
  *itReverse = 8.5; // Ок!
  cout << "A1[3] = " << A1[3] << endl;
}

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

begin: 5.8
A1 = 5.8 4.1 3.4 2.2 1.5
A1[3] = 4.1

 

9. Методы crbegin(), crend(). Установить на начало и конец массива константный реверсный итератор

Кроме константного итератора constant_iterator, в библиотеке STL введён константный реверсный итератор, который рассматривает массив от конца до начала. Такой итератор объявляется следующим образом

vector<T>::const_reverse_iterator itConstReverse;

здесь

  • T – тип элементов массива;
  • itConstReverse – имя константного реверсного итератора.

Изменить значение элементов массива с помощью константного реверсного итератора не удастся.

Методы crbegin(), crend() предназначены для работы с типом константного реверсного итератора constant_reverse_iterator и имеют следующие объявления

Пример.

#include <iostream>
#include <vector>
using namespace std;

void main()
{
  // Константный реверсный итератор const_reverse_iterator
  // 1. Создать массив символов списка инициализации
  initializer_list<char> L = { 'a', 'b', 'c', 'd' };
  vector<char> A1(L); // A1 = { 'a', 'b', 'c', 'd' };

  // 2. Объявить константный реверсный итератор itConstReverse на тип char
  vector<char>::const_reverse_iterator itConstReverse;

  // 3. Установить константный реверсный итератор на начало вектора A1
  itConstReverse = A1.crbegin();

  // 4. Вывести первый элемент массива
  cout << "begin: " << *itConstReverse << endl;

  // 5. С помощью константного реверсного итератора вывести элементы всего вектора A1.
  // Важно: элементы выводятся в обратном порядке
  cout << "A1 = ";
  while (itConstReverse != A1.crend())
  {
    cout << *itConstReverse << " ";
    itConstReverse++;
  }
  cout << endl;

  // 6. Изменить значение элемента с индексом 3 не удастся
  itConstReverse = A1.crbegin() + 3;
  //*itConstReverse = 8.5; // ошибка компиляции
}

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

begin: d
A1 = d c b a

 


Связанные темы