기본 build & run 명령어
g++ -o ex ex.cpp && ./ex
std::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, |
사용 예제
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() |
현재 사용 중인 원소 수에 맞게 벡터의 용량을 줄입니다. | 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 |