-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

Итератор и указатель в чем разница

27.02.2020, 16:10. Показов 7711. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте,

Подскажите пожалуйста, вот есть такое определение:

Code
1
2
Для получения итераторов контейнеры в C++ обладают такими функциями, как begin() и end(). 
Функция begin() возвращает итератор, который указывает на первый элемент контейнера
C++
1
2
std::vector<int> v = { 1,2,3,4 };
std::vector<int>::iterator iter = v.begin();  // получаем итератор
То есть вот так сделать нельзя:
C++
1
2
std::vector<int> v = { 1,2,3,4 };
int* my_ptr = v.begin();  // получаем итератор
Что значит итератор на первый элемент, чем он отличается от указателя на первый элемент ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.02.2020, 16:10
Ответы с готовыми решениями:

Указатель или ссылка на указатель. В чем разница?
Есть вопрос про указатели и ссылки на указатели :scratch: Хочу в функциях f1() и в f2() динамически выделить память и возвратить этот...

Строковый литерал и указатель на строку. В чем разница?
Добрый день. Начал только изучать С++, не могу понять в чем разница между указателем на литерал и указателем на строку??? Заранее...

В чем разница между указателем и указателем на указатель?
int x, *p, *q; x=10; p=&amp;x; q=p; cout&lt;&lt;*q; int x, *p, **q; x=10; p=&amp;x; q=&amp;p;

9
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
27.02.2020, 16:39
В С++ итератор это по сути объект, который представляет собой один из элементов контейнера. В отличии от указателей, у итераторов есть свои дополнительные свойства. Например есть итераторы по которым можно продвигаться вперёд и назад по контейнеру, а есть итератор используя который можно продвигаться по контейнеру вперёд, но нельзя продвигаться назад (итератор односвязного списка). На указателях таких ограничений нет
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
27.02.2020, 16:44
Optimus11, итератор это обёртка вокруг указателя на элемент. Можно бы сказать, что его задача - ответ на вопрос "кто следующий?" в терминах контейнера. Вектор имеет итератор произвольного доступа и он формально отличаясь от указателя, фактически (логически) работает как указатель:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <vector>
#include <list>
using namespace std;
 
int main()
{
vector<int> v{1,2,3};
auto it_beg=v.begin();
 
int *ptrToFirstElem=&*it_beg;
cout<<*(++ptrToFirstElem)<<endl;//2
 
return 0;
}
а со списком (сами представьте) так не выйдет. Инкремент (следующий!) для итератора и для адреса элемента имеют разный смысл у списка. Итераторы не простая тема и всё написать не получится.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
27.02.2020, 16:54
И ещё следует отметить, что итератор это абстракция для доступа к элементам контейнера. Это позволяет работать с контейнерами однообразно независимо от их внутреннего устройства. Допустим первый элемент списка это head, у вектора это нулевой элемент его массива и т.д. С итератором упрощается использование и реализация алгоритмов. Можно написать один раз алгоритм который завязан на работу с итераторами и использовать его для различных контейнеров и при этом алгоритму все равно с каким именно контейнером он работает. Все что интересует алгоритм это диапазон элементов

Добавлено через 2 минуты
То есть скажем вызывая container.begin() мы не заморачиваемся как этот begin извлекается из набора данных контейнера(это head списка, нулевой элемент массива или что-то ещё). Так же и не заморачиваемя при реализации самих алгоритмов
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
27.02.2020, 16:57
Optimus11, и да. Итераторы - инструмент безопасного доступа. Они как минимум позволяют инкрементировать/декрементировать и сравнивать на равенство. Это позволяет инвалидам работать однообразно. Хотя разумные алгоритмы совершенно не одинаковы. Поиск или сортировка списка и вектора могут быть реализованы одинаково используя эти два оператора, но за такое бьют.
1
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915
27.02.2020, 17:07  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
Optimus11... Поиск или сортировка списка и вектора могут быть реализованы одинаково используя эти два оператора, но за такое бьют.
А почему бьют ? Если итераторы вроде, как я понял из Вашего описания, как раз и предназначены для удобства ?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
27.02.2020, 17:46
Цитата Сообщение от Optimus11 Посмотреть сообщение
Если итераторы вроде, как я понял из Вашего описания, как раз и предназначены для удобства ?
Удобство это такое же растяжимое понятие как и единообразие. Помните размышления проф. Преображенского о том, что скрывается за ярлыком "контрреволюция". Чистой воды марксизм.
Если иметь ввиду тот факт, что итераторы могут предоставлять общий интерфейс, то для алгоритмов не чувствительных к типу итераторов нет вреда. Для алгоритмов чувствительных к типу итераторов возможна специализация скрытая за фасадом имени алгоритма, но базирующаяся на различии итераторов. Однако, я привёл примеры. std::sort просто не будет работать с итераторами не поддерживающими произвольный доступ. Быстрый поиск на сортированном массиве или векторе нельзя реализовать на списке. Хотя внешне (синтаксически) итератор списка и вектора создаются "единообразно".
Необходимость в итераторах возникла для создания объекта доступа к структурам, в которых порядок не связан с физическим размещением. Это практически всё кроме вектора и очереди. Это просто необходимо было бы сделать даже если бы такие объекты не имели обобщающих шаблонов. Например list_iterator<> или multimap_iterator<>. Мы же не возмущаемся от того, что итераторы не могут быть cv квалифицированы так, как указатели, а константность - отдельный тип: не const iterator, а const_iterator. Но для ряда алгоритмов, которые требуют лишь последовательного доступа обобщение итераторов полезно. Это такие (не многие и не интересные) случаи как вывод диапазона или всего контейнера в поток или копирование из контейнера в контейнер. То есть, иногда единообразие (общий интерфейс) и правда помогает.
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
27.02.2020, 19:34
Цитата Сообщение от Optimus11 Посмотреть сообщение
Что значит итератор на первый элемент, чем он отличается от указателя на первый элемент ?
Для вектора - концептуально - ничем.
Указатель на элемент массива - это частный случай итератора.
Итератор - это просто более общая идея.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13202 / 6837 / 1822
Регистрация: 18.10.2014
Сообщений: 17,294
27.02.2020, 21:58
Цитата Сообщение от Optimus11 Посмотреть сообщение
Что значит итератор на первый элемент, чем он отличается от указателя на первый элемент ?
Вопрос звучит как "чем апельсин отличается от фрукта?"

Указатель на элемент массива является частным примером итератора. Это, однако, не означает, что итераторы для массива обязаны быть указателями. Итератор для массива может быть реализован множеством разных способов.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
28.02.2020, 12:20
Optimus11, итератор - объект доступа. Указатель - тоже. Они могут работать одинаково. В частности, вектор как и массив обладает тем свойством, что порядок его элементов через структуру (вектор) и порядок их размещения в памяти совпадают. Это в следствии этого итератор на элемент вектора и указатель на этот же элемент работают одинаково. Но эти звери - не одно и то же, тем не менее.
Что касается интерфейса, то он предоставлен лишь в пределах каждого класса предоставляющего последовательность. Ограниченный интерфейс предоставлен для некоторых функций библиотеки алгоритмов <algorithm>. Но это потому, что они могут взять такой интерфейс. Общего интерфейса между контейнерами нет. Итераторы разных контейнеров - разные типы. Для того чтобы работать с коллекцией разных контейнеров, нужно интерфейс выстругать самому. В C# есть интерфейс IEnumerable. Вот эскиз (грубый) как можно изголиться в плюсах:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <vector>
#include <list>
using namespace std;
template <typename T>
class IEnumerableInterface
{
    public:
    virtual bool MoveNext();
    virtual void Reset();
    virtual T &Current();
    virtual const T &Current()const;
    virtual ~IEnumerableInterface(){}
 
};
 
template <typename T>
class VectorIEnumerableInterface
    : public   vector<T>
    , public IEnumerableInterface<T>
    {
        public:
        VectorIEnumerableInterface(const vector<T> &v)
        :vector<T>(v)
        ,IEnumerableInterface<T>{}
        ,CurrentIterator(this->begin())
        {
        }
 
        ~VectorIEnumerableInterface()
        {
        }
 
        void Reset()
            {
                CurrentIterator=this->begin();
            }
 
        bool MoveNext()
        {
            if(++CurrentIterator == this->end())
            return false ;
            return true ;
        }
 
        T &Current()
        {
            return *CurrentIterator ;
        }
 
        const T &Current()const
        {
            return *CurrentIterator ;
        }
 
       typename vector<T>::iterator CurrentIterator ;
    };
 
template <typename T>
class ListIEnumerableInterface
    : public   list<T>
    , public IEnumerableInterface<T>
    {
        public:
        ListIEnumerableInterface(const list<T> &v)
        :list<T>(v)
        ,IEnumerableInterface<T>{}
        ,CurrentIterator(this->begin())
        {
        }
 
        ~ListIEnumerableInterface()
        {
        }
 
        void Reset()
            {
                CurrentIterator=this->begin();
            }
 
        bool MoveNext()
        {
            if(++CurrentIterator == this->end())
            return false ;
            return true ;
        }
 
        T &Current()
        {
            return *CurrentIterator ;
        }
 
        const T &Current()const
        {
            return *CurrentIterator ;
        }
 
       typename list<T>::iterator CurrentIterator ;
    };
 
int main()
{
    int a[]{1,2,3};
    vector<int> va(a, a+3);
    VectorIEnumerableInterface<int> vectorIEnumerableInterface (va);
    vectorIEnumerableInterface.push_back(123);
    cout<<endl ;
 
    vectorIEnumerableInterface.Reset();
    do
    {
        cout<<vectorIEnumerableInterface.Current()++<<' ';
    }while(vectorIEnumerableInterface.MoveNext());
    cout<<endl ;
 
    list<int> la(a, a+3);
 
    ListIEnumerableInterface<int> listIEnumerableInterface (la);
 
    IEnumerableInterface<int> *iEnumerableInterface[] {
    &vectorIEnumerableInterface, &listIEnumerableInterface
    };
 
for(auto &ptrIE : iEnumerableInterface)
{
    ptrIE->Reset();
    do
        {
            cout<<ptrIE->Current()<<' ';
        }while(ptrIE->MoveNext());
}
return 0;
}
Это, как подход, может пригодиться, если у вас есть очень широкое обобщение (или набор) и множество разных контейнеров. Например куча контроллов, или виджетов, разбросанных по векторам, спискам, множествам... и вы не желаете всё это копировать в какой-то общий контейнер, даже на уровне указателей на элементы. Тем более, что указатели на элементы контейнера - опасная вещь. Вектор может реалоцировать... в списке кто-то может что-то удалить ( и влюбом ином контейнере). Тогда полезно иметь возможность перечислить все элементы разных коллекций. Что бы вызвать общий метод Show() например. Это полезно для очень общих методов (Show(), Redraw(), ToString() и пр.) которые поддерживаются типом элемента контейнеров. И именно тогда, когда они нужны все и последовательный доступ вполне уместен.
Это таки интерфейс)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.02.2020, 12:20
Помогаю со студенческими работами здесь

Указатель на указатель - разница способов
int a =5; int *b = &amp;a; int **e =&amp;b; //первый способ //Нужно писать столько * скока указателей.. int *f = b; //Втрой...

Указатель на указатель, в чем смысл?
BOOL WTSEnumerateProcesses( _In_ HANDLE hServer, _In_ DWORD Reserved, _In_ DWORD Version, _Out_ PWTS_PROCESS_INFO...

разница между указатель на функцию и функция возврата указателя?
подскажите пожалуйста очень срочно надо (вопрос на зачет)

Реализовать двусвязный список (list), итератор (iterator) и константный итератор (сonst_iterator) для списка
не могу понять что должно быть результатом. может подскажете примеры? пожалуйста. Задание: Реализовать двусвязный список (list),...

Особый итератор словаря. Итератор возвращающий нужные комбинации
Немогу разобраться, как написать итератор. У меня есть словарь, ключи это координаты, а значения это либо ноль, либо единичка (True и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

Новые блоги и статьи
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут Суть: - Группа наркоманов из 10 человек. - Только один инфицирован ВИЧ. - Колются одной иглой. - Колются раз в день. - Колются последовательно через. . .
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru