[C++] STL Vector 사용법

STL vector

vector는 배열과 같이, 같은 타입의 데이터를 저장하기 위해 쓰이는 STL( Standard Template Library ) 객체입니다.

하지만, 배열과 달리 vector의 크기는 필요에 따라 조절할 수 있습니다.

 

이 vector 객체를 사용하려면 다음의 헤더를 선언해야 합니다.

#include <vector>

 

vector의 선언

vector의 선언은 다음과 같습니다.

std::vector<T> vector_name;

여기서 T는 vector의 데이터 타입을 나타냅니다.

 

vector 선언 시 주목할 점은, vector의 크기를 명시할 필요가 없다는 것입니다.

vector의 크기는 데이터를 추가하거나 삭제할 때, 동적으로 변경됩니다.

 

vector의 초기화

vector를 초기화하는 방법은 여러 가지가 있습니다.

 

1. 초기화 리스트를 사용하는 방법입니다.

#include <iostream>
#include <vector>
using namespace std;

vector<int> int_vec = { 1, 2, 3, 4, 5 };	// 초기화 리스트

for( int data : int_vec ){
    cout << data << " ";
}

 

2. 유니폼 초기화( uniform initialization )를 사용하는 방법입니다.

vector<int> int_vec { 1, 2, 3, 4, 5 };	// uniform 초기화

 

3. 직접 크기와 값을 설정할 수도 있습니다.

vector<int> int_vec (5, 10);	// 5개의 원소를 값 10으로 초기화합니다.

vector<int> int_vec = { 10, 10, 10, 10, 10 };	// 위의 줄과 동일합니다.

 

4, 다른 vector를 복사하여 초기화할 수도 있습니다.

vector<int> int_vec = { 1, 2, 3, 4, 5 };

vector<int> copy_vec(int_vec);

 

 

기본적인 Vector의 기능들

vector는 매우 많은 기능을 가진 객체입니다.

이 중에서, 공통적으로 많이 쓰이는 기능을 정리해서 설명하겠습니다.

 

 

원소의 개수 알아내기

size

vector가 저장하고 있는 개수를 반환합니다.

empty

vector가 가지고 있는 원소의 개수가 0이면 true, 아니면 false를 반환합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    cout << int_vec.size() << endl;

    cout << "is empty: " << int_vec.empty();

    return 0;
}

▼출력

5
is empty: 0

capacity

원소를 저장할 수 있는 크기를 반환합니다.

예를 들어, 3개의 원소를 갖고 있고, capacity 함수가 5를 반환했다면

vector는 재할당 없이 2개의 원소를 추가로 저장할 수 있습니다.

 

원소를 저장할 수 있는 공간이 모두 차면 재할당 자동으로 일어나는데, 재할당이 일어나면 기존의 데이터를 복사하는 과정이 필요합니다.

따라서, 너무 많은 재할당 일어나는 상황에서는 성능이 떨어지게 됩니다.

reserve

원소를 저장할 수 있는 크기를 예약합니다.

너무 큰 공간을 예약하면, 재할당 과정은 없겠지만, 메모리 낭비가 심할 수 있습니다.

그러나, 필요한 메모리의 양을 추정할 수 있다면 최상의 성능을 낼 수 있는 기능이기도 합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.push_back(6);

    cout << "size: " << int_vec.size() << endl;

    cout << "capacity: " << int_vec.capacity() << endl;

    int_vec.reserve(20);
    cout << "after reserve, capacity: " << int_vec.capacity() << endl;

    return 0;
}

▼출력

size: 6
capacity: 10
after reserve, capacity: 20

 

이 함수가 벡터의 용량을 조정하는 것이라면, 이와 달리 벡터의 원소 개수를 조정하는 함수인 resize도 있습니다.

reserveresize 함수의 차이점에 대한 내용은 여기에서 볼 수 있습니다.

 

[C++] std::vector의 resize와 reserve의 차이점

size와 capacity의 차이점vector의 멤버 함수인 size는 vector의 원소 개수를 반환하는 함수입니다.또한, 이 함수는 모든 컨테이너의 기본 인터페이스이기도 합니다. 그렇지만, capacity는 vector 컨테이너

codingembers.tistory.com

 

원소 추가하기

push_back

push_back 함수는 새로운 원소를 vector의 뒤 쪽에 추가합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.push_back(6);
    int_vec.push_back(7);
    
    for( int data : int_vec ){
        cout << data << " ";
    }

    return 0;
}

▼출력

1 2 3 4 5 6 7

 

insert

insert 함수는 원하는 위치에 새로운 원소를 추가합니다.

추가하려는 위치를 가리키기 위해서 iterator를 사용해야 되고, 성공적으로 추가하게 되면 추가된 원소의 위치를 나타내는 iterator를 반환합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.insert( int_vec.begin(), 6);	// 첫 번째 위치에 추가
    
    int_vec.insert( int_vec.end(), 7 ); 	// 맨 마지막에 추가
        
    for( int data : int_vec ){
        cout << data << " ";
    }

    return 0;
}

▼출력

6 1 2 3 4 5 7

 

emplace_back

emplace_back 함수는 새로운 원소를 vector 내에서 직접 생성하고, 원소 배열의 뒤 쪽에 추가합니다.

int main(){

    using point = pair<int, int>;
    vector<point> point_vec;

    point_vec.emplace_back( 1, 1);  // 벡터 내부에 point 직접 생성
    
    point pt2 = make_pair( 2, 2);
    point_vec.emplace_back( pt2);

    for( auto& x : point_vec){
        cout << x.first << ", " << x.second << endl; 
    }
}

▼출력

1, 1
2, 2

이 함수에 관해선 여기에서 좀 더 자세히 볼 수 있습니다.

 

[C++] STL emplace 함수 설명 및 사용법

emplace 함수std::emplace 함수는 STL 컨테이너( vector, list, set, map, deque 등 )에서 사용가능한, 새로운 원소를 삽입하는 함수입니다. 이와 비슷한 함수로  vector의 emplace_back, list의 emplace_front, emplace_back, m

codingembers.tistory.com

 

원소에 접근하기

at

at 함수는 vector의 원소를 index를 사용해 접근할 수 있도록 합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int val = int_vec.at(2);    // 세 번째 원소에 접근

    int val2 = int_vec[2];  	// 연산자를 통해 접근

    return 0;
}

at 함수 대신 연산자 [ ]를 통해서 원소에 접근하는 방법도 있습니다.

그러나, index가 잘못되는 경우 연산자 [ ]는 잘못된 값을 반환하지만, at 함수는 예외(exception)를 발생시킵니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int val = int_vec.at(7);    // 존재하지 않는 원소에 접근. 예외 발생

    int val2 = int_vec[7];  	// 연산자를 통해 접근. 잘못된 값을 반환

    return 0;
}

 

원소 변경하기

at

원소의 값을 바꾸는 데도, at 함수를 사용할 수 있습니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.at(2) = 6;    // at 함수를 통한 변경
    
    int& ref = int_vec.at(3);	
    ref = 7;
    
    int_vec[4] = 7;	// 연산자를 통한 변경

    for( int val : int_vec){
        cout << val << " ";
    }

    return 0;
}

▼출력

1 2 6 7 7

at 함수는 보관하고 있는 데이터의 참조(reference)를 반환하기 때문에, 위와 같은 대입 방식이 가능합니다.

그리고, [ ] 연산자를 통해서도 값을 변경할 수 있습니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.at(7) = 6;  // 존재하지 않는 원소의 값 변경. 예외 발생
         
    int_vec[7] = 100;  // 연산자를 통해 접근. 경고를 줄 수 없습니다.

    return 0;
}

그러나, at 함수는 존재하지 않는 원소의 값을 변경하면, 예외를 발생시켜 경고를 받을 수 있지만,

연산자 [ ]를 통한 변경의 경우 오류를 찾기 힘들 수도 있습니다.

 

원소 삭제하기

pop_back

vector에서 마지막 원소를 삭제합니다.

int main(){

    vector<int> int_vec;

    int_vec.push_back(3);   // 마지막에 원소 추가
         
    int_vec.pop_back();     // 마지막의 원소 삭제

    return 0;
}

 

clear

vector에 있는 모든 원소를 삭제합니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };

    int_vec.clear();    // 모든 데이터 삭제
         
    cout << int_vec.size();	// 0이 반환됩니다.

    return 0;
}

 

Vector의 반복자( Iterator )

vector 반복자는 vector 내의 원소들에 접근하고, 원소들 간의 이동을 위해서 사용됩니다.

vector의 반복자는 임의 접근 반복자( random access iterator )입니다.

 

반복자( iterator )의 전반적인 내용은 여기에 정리해 두었습니다.

 

[C++] 반복자( Iterator )에 대한 설명과 종류

반복자( Iterator )란 무엇인가?Iterator는 컨테이너에서 원소의 위치를 표현하는, 포인터와 같은 객체입니다. 여기서, 컨테이너란 다른 객체들을 담는 집합 객체라고 할 수 있습니다. 컨테이너의

codingembers.tistory.com

 

vector 반복자는 다음과 같이 선언합니다.

vector<T>::iterator iter_name;

여기서 T는 vector의 데이터 타입입니다.

 

vector의 반복자 초기화

vector의 초기화는 다음의 함수들로 수행할 수 있습니다.

begin

이 함수는 vector의 첫 번째 원소를 가리키는 iterator를 반환합니다.

vector<int> int_vec = { 1, 2, 3, 4, 5 };
vector<int>::iterator iter;	// int타입 vector의 반복자 선언

iter = int_vec.begin();

end

이 함수는 vector의 마지막 원소 다음을 가리키는 iterator를 반환합니다.

마지막 원소를 가리키는 iterator는 다음과 같이 구할 수 있습니다.

vector<int> int_vec = { 1, 2, 3, 4, 5 };
vector<int>::iterator iter;

iter = int_vec.end() - 1;

int val = *iter;	// 마지막 원소 5

 

만일, vector의 원소가 하나도 없다면 beginend가 같은 값을 반환합니다.

#include <iostream>
#include <vector>
using namespace std;

int main(){

    vector<int> int_vec;
    if ( int_vec.begin() == int_vec.end()){
        cout << "vector size is zero\n";
    }
    
    return 0;
}

▼출력

vector size is zero

 

vector의 모든 원소를 순환하고자 하면 다음과 같이 할 수 있습니다.

int main(){

    vector<int> int_vec = { 1, 2, 3, 4, 5 };
    vector<int>::iterator iter;

    for(iter = int_vec.begin(); iter != int_vec.end(); iter++){
        cout << *iter << " ";
    }

    return 0;
}

▼출력

1 2 3 4 5

 

 

이 글과 관련있는 글들

함수에서 std::vector와 같은 객체를 반환하는 방법

 

 

 

 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유