Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/40: Рейтинг темы: голосов - 40, средняя оценка - 4.90
-41 / 49 / 5
Регистрация: 10.01.2017
Сообщений: 1,915

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

27.02.2020, 16:10. Показов 7672. Ответов 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,816
27.02.2020, 19:34
Цитата Сообщение от Optimus11 Посмотреть сообщение
Что значит итератор на первый элемент, чем он отличается от указателя на первый элемент ?
Для вектора - концептуально - ничем.
Указатель на элемент массива - это частный случай итератора.
Итератор - это просто более общая идея.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12942 / 6809 / 1821
Регистрация: 18.10.2014
Сообщений: 17,234
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru