728x90

STL (Standard Template Library)의 첫 번째 Sequence Container (연속적인 컨테이너)인 std::vector에 대해서 공부를 한다. 

 

 

std::vector

 

Vector는 Dynamic Size Array (동적 배열)의 Sequence Constainer (연속적인 컨테이너)이다. 그 뜻은 우리가 일반적으로 특정 Type에 대해서 포인터를 만들고 동적으로 메모리를 할당하는 것과 동일하게 Heap영역에 동적으로 Type에 대한 메모리를 Dynamic 하게 생성해준다. 

 

아래는 일반적으로 포인터를 이용해서 Dynamic Array를 생성한 코드이다. 

 

int main()
{
    int* arrayPtr = new int[10];
    
    for(int i = 0; i < 10; ++i)
    {
        arrayPtr[i] = i;
    }
    
    delete[] arrayPtr;
    
    return 0;
}

 

위 코드와 같이 new키워드를 통해서 integer type의 크기 10자리 메모리 공간을 동적으로 할당하여 그 공간을 arrayPtr이 가리키는 코드이다. 위 코드의 단점은 꼭 해당 메모리 공간을 개발자가 delete를 시켜줘야 한다. 하지만 std::vector는 이러한 공간을 관리를 해준다. 

 

std::vector의 선언은 아래 코드와 같다. 

 

#include <vector>

int main()
{
    std::vector<int> v(10);
    for(int i = 0; i < 10; ++i)
    {
        v[i] = i;
    }
    
    return 0;
}

 

std::vector를 이용해서 포인터로 동적 할당한 코드와 동일한 코드를 짜보았다. 먼저 std:vector를 사용하기 위해서는 vector헤더를 포함시켜주어야 한다. 그리고 Angle Bracket ('<', '>') 안에 생성하고자 하는 메모리의 타입을 지정을 해주어야 한다 그리고 괄호 안에 크기를 입력해주면 된다. 위 코드에서는 크기를 주었지만 크기를 따로 주지 않고 메모리를 초기화하는 방법이 존재한다. 

 

#include <vector>

int main()
{
    std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    return 0;
}

 

선언과 동시에 원소를 초기화 하는 방법은 위와 같다. 

 

이제 생성된 std::vector의 원소 값을 출력을 해보자 std::vector의 원소 출력은 다양한 방식으로 할 수 있는데 크게 3가지를 소개한다. 

 

#include <vector>
#include <iostream>

int main()
{
	std::vector<int> nums(10);

	//[] indexing
	for (std::size_t idx = 0; idx < nums.size(); ++idx)
	{
		std::cout << nums[idx] << std::endl;
	}

	//iterator
	for (auto itr = nums.begin(); itr != nums.end(); ++itr)
	{
		std::cout << (*itr) << std::endl;
	}

	//ranged for (most optimized)
	for (const int& num : nums)
	{
		std::cout << num << std::endl;
	}
}

 

위 세개의 방법은 모두 동일한 출력을 만들어 낸다. 

 

먼더 [] iundecing은 우리가 평소에 배열의 모든 원소를 출력하고자 할 때 자주 쓰는 방법이다. 두 번째는 vector의 iterator를 사용하는 방법이다. itr의 형은 auto로 자동적으로 위 코드에서는 vector <int>::iterator가 된다. 초기값은 nums의 begin() 메서드를 통해서 nums의 시작점을 가리키고 nums가 마지막일 때까지 출력을 하게 된다. 마지막은 ranged for loop (범위 기반 루프)이다. 쉽게 생각해서 num이라는 레퍼런스에 nums 주고 값을 저장하고 배열 출력에 흑화 된 for loop이라고 생각하면 된다. 레퍼런스가 없어도 무방하지만 레퍼런스가 없다면 nums에 대한 복사가 일어나기 때문에 레퍼런스를 붙여주되 배열의 원소의 조작이 없다면 const를 붙여주는 것이 이상적이다. 또한 auto를 이용하여 Type의 추론을 넣어 작성하는 것이 이상적이다. 해당 방법이 가장 Optimized 된 방법이라 해당 방법을 추천한다. 

 

위 코드에서 사용된 begin(), size(), end()메소드는 vector의 메소드이다. 이외에도 수 많은 메소드들이 있기 때문에 다 설명을 하지않고 cppreference를 참고하기 바란다. 

 

 

Ref.

https://nocodeprogram.com/lecture/1/83003/

https://en.cppreference.com/w/cpp/container/vector

+ Recent posts