C언어에서 가장 핵심적인 문법은 '포인터'를 선택할 것이다. 그리고 STL의 가장 핵심적인 요소는 바로 '반복자'이다.
반복자와 포인터의 역할은 사용 방법이 비슷하지만 훨씬 더 '일반화'되어 있어 임의의 컨테이너와 함께 사용할 수 있다.
1. 배열 순회하기
void Print(int* ar, int num)
{
for (int i = 0; i < num; i++)
std::cout << ar[i] << std::endl;
}
첨자를 증가시키면서 '[] 연산자'를 이용해 첨자 위치의 요소를 출력하는 것을 알 수 있다.
2. 연결 리스트 순회하기
void Print(Node* head)
{
for (Node* curr = head; curr != tail; curr = head->next)
std::cout << curr->value << std::endl;
}
첫 번째의 배열 같은 경우는 첨자를 증가시키면 되지만 연결 리스트는 노드들이 다음 노드의 메모리 주소를 가지고 있어 링크를 쫓아 다녀야 모든 노드를 순회할 수 있다.
위의 두 컨테이너는 유사함에도 불구하고 물리적인 자료 구조가 틀리므로 순회하는 방법이 다르다.
이 때문에 똑같은 작업을 하는 함수임에도 순회 방법이 틀려 각 자료구조에 맞는 함수가 필요하다.
이러한 순회 방법을 '일반화'하기 위해 STL에서 사용하는 개념이 바로 '반복자'이다.
우선 순회 방법을 일반화를 위해 다음과 같은 기능을 가진다.
위의 요소는 포인터는 그대로 할 수 있는 것이며 반복자는 이를 흉내낸다고 생각하면 된다.
모든 컨테이너는 시작점과 끝다음점을 조사하는 'begin', 'end' '멤버 함수'를 제공한다.
1. 포인터(반복자)를 이용하여 배열 순회하기
int main(void)
{
int arr[] = {1, 2, 3, 4, 5};
int* it;
for (it = &arr[0]; it != &arr[5]; it++)
std::cout << *it;
return 0;
}
2. 벡터 순회하기
int main(void)
{
int arr[] = {1, 2, 3, 4, 5};
std::vector<int> varr(&arr[0], &arr[5]);
std::vector<int>::iterator it;
for (it = varr.begin(); it != varr.end(); it++)
std::cout << *it;
return 0;
}
이번 예제에서는 다음과 같은 문구를 볼 수 있다.
std::vector<T>::iterator it;
'vector<T>'가 클래스 이름이고 이 클래스안에 'iterator'라는 타입으로 'typedef'로 정의되어 있으며 이 타입으로 변수를 선언하면 벡터의 한 요소를 가리키는 반복자가 된다.
3. 연결 리스트 순회 방법
int main(void)
{
int arr[] = {1, 2, 3, 4, 5};
std::list<int> larr(&arr[0], &arr[5]);
std::list<int>::iterator it;
for (it = larr.begin(); it != larr.end(); it++)
std::cout << *it;
return 0;
}
위의 예제들을 보면 모든 컨테이너들이 반복자를 통해 순회되는 것을 볼 수 있다.
즉, 다 똑같은 형태의 구문으로 이루어져있다는 것은 하나의 함수로도 구조가 다른 컨테이너들을 순회할 수 있다는 것이다.
#include <iostream>
#include <vector>
#include <list>
template <typename IT>
void Print(IT s, IT e)
{
IT it;
for (it = s; it != e; it++)
std::cout << *it;
}
int main(void)
{
int arr[] = {1, 2, 3, 4, 5};
std::vector<int> varr(&arr[0], &arr[5]);
std::list<int> larr(&arr[0], &arr[5]);
Print(&arr[0], &arr[5]);
Print(varr.begin(), varr.end());
Print(larr.begin(), larr.end());
return 0;
}
지금까지 반복자의 기본적인 기능에 대해 소개했다. 즉, 컨테이너의 한 요소를 가리키는 포인터 역할과 증감, 대입 및 비교 등을 설명했다.
이 글은 여기서 마치며 나머지 기능들은 다음 글에서 설명하도록 하겠다.
[STL] 반복자(4) - 임의 접근 반복자 (0) | 2023.08.23 |
---|---|
[STL] 반복자(3) - 순방향, 양방향 반복자 (0) | 2023.08.23 |
[STL] 반복자(2) - 입출력 반복자 (0) | 2023.08.23 |
[STL] 컨테이너 (0) | 2023.08.23 |
[STL] STL의 구조 (0) | 2023.08.23 |