오븐 노트

[C++] vector #3 본문

Develop/C++

[C++] vector #3

오 븐 2023. 5. 29. 23:13
#include <iostream>
using namespace std;
#include <vector>

// 매우 중요!!!!!!!

int main()
{
    // 컨테이너(Container): 데이터를 저장하는 객체

    // vector (동적 배열)
    // - vector의 동작 원리 (size/capacity)
    // - 중간 삽입/삭제
    // - 처음/끝 삽입/삭제
    // - 임의 접근

    // 반복자(Iterator) : 포인터와 유사한 개념. 컨테이너의 원소(데이터)를 가리키고, 다음/이전 원소로 이동 가능
    vector<int> v(10);

    v.reserve(1000); // 공간 확보

    for (vector<int>::size_type i = 0; i < v.size(); i++) // 벡터 한정으로는 iterator 포문과 큰 차이 없음
        v[i] = i;

    //vector<int>::iterator it;
    //int* ptr;

    //it = v.begin();
    //ptr = &v[0];

    //cout << (*it) << endl;
    //cout << (*ptr) << endl;

    //int a = 1;
    //int b = a++; // (b = 1, a = 2)
    //int c = ++a; // (a = 2, a = 2)

    //it++;
    //++it;
    //ptr++;
    //++ptr;

    //it--;
    //--it;
    //ptr--;
    //--ptr;

    //it += 2;
    //it = it - 2;
    //ptr += 2;
    //ptr = ptr - 2;

    vector<int>::iterator itBegin = v.begin();
    vector<int>::iterator itEnd = v.end(); // 데이터의 끝을 가리키기 때문에 데이터를 조작하면 절대 안되고 끝을 판별할 때 사용됨

    // 더 복잡해보이는데 사용하는 이유
    // 다른 컨테이너는 v[i]와 같은 인덱스 접근이 안 될 수도 있음
    // iterator는 vector 뿐 아니라, 다른 컨테이너에도 공통적으로 있는 개념
    // 때문에 다른 컨테이너. 자료구조로 이동하기 수월함
    for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) // iterator를 사용 할 때는 it++이 아닌 ++it가 아주 약간 성능에 도움이 된다.
    {
        cout << (*it) << endl;
    }

    int* ptrBegin = &v[0]; // v.begin._Ptr;
    int* ptrEnd = ptrBegin + 10; // v.end()._Ptr;
    for (int* ptr = ptrBegin; ptr != ptrEnd; ++ptr)
    {
        cout << (*ptr) << endl;
    }

    // const int*;
    // vector<int>::const_iterator cit1 = v.cbegin();
    // *cit1 = 100; // const 형태이기 때문에 수정 불가

    // 면접 단골 질문일 정도로 기본기 중 기본기
    // - 중간 삽입/삭제 // 효율 매우 나쁨. 중간의 값만 건들 수 없으니 결국 모두를 복사해야함
    // - 처음/끝 삽입/삭제 // 처음: 마찬가지로 매우 나쁨. 끝: 마지막 데이터만 날리면 되므로 효율 좋음
    // - 임의 접근 (Random Access)

    // vector = 동적 배열 = 동적으로 커지는 배열 = 배열
    // 원소가 하나의 메모리 블록에 연속하게 저장된다

    //v.push_back(1); // back은 있지만 front는 없다.
    //v.pop_back();

    // 2번째 데이터는 어디에 있는가 (임의 접근)
    // v[2] = 3;

    // 중간 삽입 문법
    // 메모리 주소는 삽입, 삭제 한 위치를 가리킴
    vector<int>::iterator insertIt = v.insert(v.begin() + 2, 5); // 2번째 데이터를 5로 교체하라
    vector<int>::iterator eraseIt1 = v.erase(v.begin() + 2); // 2번째 데이터를 제거하라
    vector<int>::iterator eraseIt2 = v.erase(v.begin() + 2, v.begin() + 4); // 2번째에서 (4 - 1)번째 데이터를 제거하라

    // 쭉 스캔을 하면서 3이라는 데이터가 있으면 일괄 삭제
    for (vector<int>::iterator it = v.begin(); it != v.end();)
    { // iterator는 포인터 뿐 아니라 모든 컨테이너의 정보를 들고있음.
        // for문을 이용하여 iterator를 스캔하는 중에 데이터를 clear하거나 push하게 될 경우 매우 조심해야함.
        int data = *it;
        if (data == 3)
        {
            it = v.erase(it); // 해당 iterator의 proxy가 null. 즉, 이미 삭제되어 해당 컨테이너 소속이 아니게 된 것이므로 더 이상 사용하면 안됨.
            // iterator를 삭제 한 순간 iterator를 갱신하여 유효한 주소로 다시 들게 됨.
            // 여기에서 주소를 재설정 해주기 때문에 for문에 증감연산자를 넣게 되면 현재 주소는 건너뛰게 됨. 때문에 아래 else에 추가
        }
        else
        {
            ++it;
        }

        // v.clear(); // for문에서 clear 하는 것 자체가 이상하지만 예시로 들기 위함.
        // break; // iterator가 소멸되었기에 꼭 중단해야함.
    }

    return 0;
}

[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 - 인프런 | 강의
 
C++ 카테고리의 글은 인프런 Rookiss님의 강의를 공부하며 정리하는 내용입니다.
이미 알고 있는 내용도 다시 정리 되어있을 수 있습니다.

 

모든 글은 제가 공부하기 위해 작성합니다.

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

[C++] list #1  (0) 2023.06.08
[C++] vector #4  (0) 2023.05.31
[C++] vector #2  (0) 2023.05.29
[C++] vector #1  (0) 2023.05.18
[C++] 콜백 함수  (0) 2023.05.18