728x90

개요

컨테이너에서 원소에 접근할 수 있게 하는 포인터같은 객체

벡터에서 []을 사용해 원소에 접근할 수 있지만, 반복자를 사용해 접근하는 것이 올바른 방법이다.

STL에 있는 컨테이너들에는 iterator 멤버 타입으로 정의되어 있다.

 

이후 내용은 벡터를 통해 반복자를 설명한다.

begin()과 end()

벡터의 반복자 구조

  • begin(): 컨테이너의 첫 번째 원소를 가리키는 반복자를 리턴
  • end(): 컨테이너의 마지막 원소 한 칸 뒤를 가리키는 반복자를 리턴
    • 빈 벡터를 begin() == end()로 표현하기 때문에 한 칸 뒤를 가리키게 함
// 반복자 사용 예시
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec;
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);
    vec.push_back(40);
    
    // 전체 벡터를 출력
    // 반복자가 end()가 아닐 때까지 반복한다.
    for (std::vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter) 
    {
    	std::cout << *iter << std::endl;
    }
    
    // 포인터처럼 + 연산자 사용 가능
    std::vector<int>::iterator iter = vec.begin() + 2;
    std::cout << "3 번째 원소 :: " << *iter << std::endl;
}

반복자와 포인터

*iter 처럼 * 연산자를 이용해 반복자가 가리키는 원소를 가져올 수 있었다.

하지만 이는 실제 포인터가 아닌, * 연산자를 오버로딩해 포인터처럼 동작하게 만든 것이다.

반복자와 포인터는 모양과 사용법만 비슷한 별개의 개념이라는 것을 꼭 기억하자.

반복자와 원소 삽입 / 제거

// vec[2] 앞에 15 삽입
vec.insert(vec.begin() + 2, 15);

// vec[3] 제거
vec.erase(vec.begin() + 3);

위의 코드와 같은 형태로 반복자를 통해 원소를 삽입하고 제거할 수 있다.

 

다만, 여기서 주의할 점이 있다. 컨테이너의 원소를 삽입하거나 제거하게 되면 기존에 사용하던 모든 반복자들은 사용할 수 없게 된다. 삭제 후 반복자를 다시 설정해주어야 한다.

std::vector<int>::iterator itr = vec.begin();

for (; itr != vec.end(); itr++) 
{
    if (*itr == 20) 
    {
        vec.erase(itr); // vec의 반복자 itr를 더 이상 사용할 수 없음
    }
}

// -------------------------

std::vector<int>::iterator itr = vec.begin();

for (; itr != vec.end(); ++itr) 
{
    if (*itr == 20) 
    {
        vec.erase(itr);
        itr = vec.begin(); // 반복자를 다시 설정
    }
}

// -------------------------

vec.erase(vec.begin() + i) // 시작 위치의 반복자 자체를 인수로 전달

// 하지만 위의 방법도 여전히 비효율적인 방법
// 이를 해결하기 위한 방법은 STL 알고리즘에서 나옴 (std::remove())

 

반복자의 종류

  • iterator
    • 위에서 설명한 반복자
    • begin(), end() 사용
  • const_iterator
    • const_iterator가 가리키는 원소는 수정할 수 없음
    • cbegin(), cend() 사용
  • reverse_iterator
    • 기존 반복자와 같지만 컨테이너의 뒤에서 앞으로 거꾸로 이동
    • rbegin(), rend() 사용
  • const_reverse_iterator
    • const_iterator와 reverse_iterator의 성질을 모두 합친 반복자
    • crbegin(), crend()를 사용

참고 및 이미지 출처

모두의 코드 - 씹어먹는 C++ PDF [https://modoocode.com/312]

728x90

'Programming > C++' 카테고리의 다른 글

C++ 입출력 속도 높이기  (0) 2024.07.31
[C++ STL] 덱 (Deque)  (0) 2024.07.27
[C++ STL] 리스트 (List)  (0) 2024.07.27
[C++ STL] 벡터 (Vector)  (0) 2024.07.27
[C++ STL] 개요  (0) 2024.07.22
snwdaaa