본문 바로가기

C++

[C++] 벡터(vector)와 메소드들(push_back, front, back, begin, end)

표준 템플릿 라이브러리(STL : Standard Template Library) 안에 컨테이너(container), 이터레이터(iterator), 알고리즘(algorithm)템플릿 등을 제공한다. 컨테이너는 배열과 같이 여러 개의 값을 저장할 수 있는 구성단위이다.

 

vector 템플릿 객체를 생성하려면 사용할 데이터형을 나타내기 위해 <자료형 타입> 표기를 사용한다.

 

vector 생성 간단 예)

vector <int> a(10);	//int형 벡터 10개 생성
vector <double> b(100);	//double형 벡터 100개 생성

 

vector 생성 방법은 여러 가지가 있다.

#include <iostream>
#include <vector>	//vector 사용
using namespace std;

int main()
{
	//비어있는 vector 생성
	vector <int> a;

	//0으로 초기화된 vector 3개 생성
	vector <int> b(3);

	//10으로 초기화된 vector 3개 생성
	vector <int> c(3, 10);

	//vector c를 복사하여 d생성
	vector <int> d(c);
    
	//0, 1, 2로 초기화된 vector e생성, C++11 부터 지원
	vector <int> e = { 0, 1, 2 };

	return 0;
}

 

비어있는 vector 생성을 보면 배열과 비교하면 어색하다. 크기의 지정이 없기 때문이다. vector는 메모리를 할당하여 사용한다. 즉, 0으로 초기화된 3개의 vector를 생성했어도 원소의 추가가 가능하다. 메모리 동적 할당은 delete로 메모리를 해제하여 메모리 누수(leak)를 예방해야 하지만, vector는 블록 밖으로 나가거나 return을 만나면 자동으로 delete 되어 메모리를 해제해준다.

 

vector는 배열처럼 개별 요소에 접근할 때는 a [i]처럼 사용할 수 있다. 단, 원소를 생성하면서 write는 불가능하다. 즉, 이미 존재하는 값에서만 write가 가능하다. 새로운 원소를 추가할 때는 push_back(값); 메소드를 활용하면 된다.

 

#include <iostream>
#include <vector>	//vector 사용
using namespace std;

int main()
{
	//0으로 초기화된 vcetor 2개 생성
	vector <int> a(2);

	a[1] = 1;	//1번요소 1로 변경;
	//a[2] = 2;	//2번요소는 없으므로 에러
	a.push_back(2);	//2번요소 값을 생성하고 2로 초기화

	for (int i = 0; i < a.size(); ++i)
	{
		cout << a[i] << endl;
	}
	cout << "*****" << endl;

	a[2] = 100;	//2번요소가 생겻으므로 write가능

	for (int i = 0; i < a.size(); ++i)
	{
		cout << a[i] << endl;
	}

	return 0;
}

 

결과값:

0
1
2
*****
0
1
100

 

배열과 비교하여 vector 템플릿은 무슨 이점이 있을까?

vector 템플릿은 컨테이너를 활용할 수 있는 다양한 메소드를 제공한다.

 

size() - 벡터의 요소의 개수를 반환한다.

swap(vector객체) - 두 벡터의 내용을 교환(교체)한다.

empty() - 벡터가 비었는지 여부를 반환한다.

at(index) - index번째 요소에 접근한다.

front() - 벡터의 첫 번째 요소를 반환한다.

back() - 벡터의 마지막 요소를 반환한다.

begin() - 벡터의 첫 번째 요소를 가리킨다.

end() - 벡터의 마지막 요소를 가리킨다.

 

#include <iostream>
#include <vector>	//vector 사용
using namespace std;

int main()
{
	//0으로 초기화된 vcetor 10개 생성
	vector <int> a(10);
	vector <int> b(10);

	//{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 로 초기화
	for (int i = 0; i < 10; ++i) { a[i] = i; }

	cout << a.at(5) << endl;
	cout << a.front() << endl;
	cout << a.back() << endl;

	//0으로 초기화된 b와 a 교체
	a.swap(b);

	//a 전체 출력 
	for (int i = 0; i < a.size(); ++i)
	{
		cout << a[i] << " ";
	}

	return 0;
}

 

결과값:

5	//5번째 요소
0	//첫 번째 요소
9	//마지막 요소
0 0 0 0 0 0 0 0 0 0

 

다음 예제를 보면서 front(), back()과 begin(), end()의 차이점을 알 수 있다.

 

*이터레이터(Iterator) 컨테이너에 접근하는 객체로 포인터의 일반화(?)라고 생각하면 된다.

 

#include <iostream>
#include <vector>	//vector 사용
using namespace std;

int main()
{
	//vector a생성
	vector <int> a;

	a.push_back(10);
	a.push_back(20);
	a.push_back(30);
	a.push_back(40);
	a.push_back(50);

	//a 전체 출력 
	for (vector<int>::iterator iter = a.begin(); iter != a.end() ; ++iter)
	{
		cout << *iter << " ";
	}

	return 0;
}

 

결과값:

10 20 30 40 50 

 

vector<int>::iterator는 vector내에 정의되어있는 반복자 클래스이다.

begin()과 end()는 원소의 첫 번째와 끝을 가리킨다.(포인터 개념)