본문 바로가기
CS/Data Structure&Algorithm

std::array, std::vector

by TSpoons 2024. 10. 26.

기본 build & run 명령어

g++ -o ex ex.cpp && ./ex

std::array

https://cpp-lang.net/docs/std/containers/arrays/array/

- std::array는 메모리를 자동으로 할당하고 해제한다.

- C 스타일 배열과 같이 [ ] 연산자를 제공

- at() : [ ] 연산자보다 느리지만 예외처리용으로 쓸 수 있다.

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


std::array<int, 4> arr3 ={1, 2, 3, 4};


int main(){
    try{
    cout << arr3.at(3) << "\n"; //
    cout << arr3.at(4) << endl; // std::out_of_range 예외 발생
    }
    catch(const out_of_range& ex){ // 예외처리 
        cerr << ex.what() << endl;
    }
}

함수 인자 전달

- 함수에 array 객체가 전달되면 새로운 배열에 모든 원소가 복사된다. (const를 사용하면 메모리와 시간이 절약)

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


template <size_t N>
void print(array<int, N> arr){
    for(auto ele : arr)
        cout << ele << " ";

    cout << endl;
}

// const를 사용하여 복사 없이 array 객체를 함수에 전달
template <size_t N>
void printArray(const array<int, N>& arr) {
    for (const int& ele : arr) {
        cout << ele << " ";
    }
    cout << endl;
}

int main(){
    array<int, 10> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    print(arr);
    printArray(arr);
}

반복자(iterator) 사용

array<int, 10> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (auto it =arr.begin(); it != arr.end()-2; it++){
    auto ele = (*it);
    std::cout << ele << ' ';
}

// reverse iterator
for (auto rit = arr.rbegin(); rit != arr.rend() - 2; ++rit) {
    std::cout << *rit << ' ';
}

원소 접근을 위한 방법

함수 설명 예외 처리 반환형
operator[ ] 주어진 인덱스의 원소에 접근 (범위 초과 확인 없음) 없음 참조(&) 또는 값
at() 주어진 인덱스의 원소에 접근 (범위 초과 시 std::out_of_range 예외 발생) std::out_of_range 참조(&) 또는 값
front() 첫 번째 원소에 접근 빈 배열일 경우 정의되지 않음 참조(&) 또는 값
back() 마지막 원소에 접근 빈 배열일 경우 정의되지 않음 참조(&) 또는 값
data() 배열의 첫 원소를 가리키는 포인터 반환 (T* 타입) 없음 포인터(T*)

사용 예제

array<int, 5> arr = {1, 2, 3, 4, 5}


cout << arr[2] << endl; // 2
cout << arr.at(6) << endl; // terminate called after throwing an instance of 'std::out_of_range'
cout << arr.front() << endl; // 1
cout << arr.back() << endl;    // 5
cout << *(arr.data() + 1 << endl; // 2

std::array의 한계

- array의 크기는 컴파일 시간에 결정되는 상수 -> 프로그램 실행 중 변경 불가

- 크기가 고정되어 원소 추가 및 삭제 불가

- 항상 스택 메모리를 활용

std::vector - 가변 크기 배열

- 컴파일러가 벡터의 크기를 유추하여 생성된다.

- push_back() --> 맨 마지막에 원소를 추가

원소 변경을 위한 방법

함수 설명 사용 예
push_back() 벡터의 끝에 원소를 추가 vec.push_back(10);
insert() 지정된 위치에 원소를 추가 vec.insert(vec.begin() + 2, 20);
emplace_back() 벡터의 끝에 원소를 추가, 인자를 직접 사용하여 원소를 생성 vec.emplace_back(30);
emplace() 지정된 위치에 원소를 추가, 인자를 직접 사용하여 원소를 생성 vec.emplace(vec.begin() + 1, 40);
pop_back() 벡터의 마지막 원소를 제거 vec.pop_back();
erase() 지정된 위치의 원소를 제거 vec.erase(vec.begin() + 1,
vec.begin()+ 4);

 

사용 예제

template <typename T>
void print(const vector<T>& vec) {
    for (const auto& ele : vec) {
        cout << ele << " ";
    }
    cout << endl;
}

int main() {
    // vector 예제
    vector<int> vec = {6, 7, 8, 9, 10};

    vec.pop_back();
    print(vec); 
    
    vec.erase(vec.begin());
    print(vec);

    vec.erase(vec.begin()+1, vec.begin()+4);
    print(vec); // free(): invalid size
   
}

 

 

유용한 멤버 함수

함수 설명 사용 예
clear() 벡터의 모든 원소를 제거하여 벡터를 비웁니다. vec.clear();
reserve(capacity) 벡터의 용량을 지정된 크기로 설정하여 메모리를 미리 할당합니다. 기존 원소는 유지됩니다. vec.reserve(100);
shrink_to_fit()
(>= C++ 11)
현재 사용 중인 원소 수에 맞게 벡터의 용량을 줄입니다. vec.shrink_to_fit();

 

사용 예제

#include <iomanip>
#include <iostream>
#include <vector>
 
int main()
{
    int sz = 100;
    std::vector<int> v;
 
    auto cap = v.capacity();
    std::cout << "Initial size: " << v.size() << ", capacity: " << cap << '\n';
 
    std::cout << "\nDemonstrate the capacity's growth policy."
                 "\nSize:  Capacity:  Ratio:\n" << std::left;
    while (sz-- > 0) {
        v.push_back(sz);
        if (cap != v.capacity()) {
            std::cout << std::setw( 7) << v.size()
                      << std::setw(11) << v.capacity()
                      << std::setw(10) << v.capacity() / static_cast<float>(cap) << '\n';
            cap = v.capacity();
        }
    }
 
    std::cout << "\nFinal size: " << v.size() << ", capacity: " << v.capacity() << '\n';
}

 

std::vector의 유연성

- 배열과 벡터에서 제공하는 기능은 같은 점근적 시간 복잡도를 가진다.

- 백터의 성능은 배열에 비해 나쁘지 않다.

'CS > Data Structure&Algorithm' 카테고리의 다른 글

std::deque, std::stack, std::queue, std::priority_queue  (2) 2024.10.27
std:forward_list, std:list  (0) 2024.10.26