
[01. C 스타일 배열과 std::array]
① 배열(array)이란?
✔︎ 같은 종류의 데이터가 연속적으로 저장되어 있는 자료 구조
-
다섯 학생의 점수를 저장하려면?
int score 1, score 2, score 3, score 4, score 5;
--> int scores[5];
(인덱스: 0 기반, zero-based)
(윗 배열은 한 배열당 4byte이니 4byte*5=20byte이다)

- 인덱스(index)를 사용하여 원하는 원소(element)에 곧바로 접근 가능: O(1)
- 캐시 지역성 (cache locality) ㄴ 배열의 각 원소는 서로 인접해 있기 때문에 하나의 원소에 접근할 때 그 근방에 있는 원소도 함께 캐시(cache)로 가져옴
- 반복문에서 배열을 사용하면 효율적인 프로그래밍 가능
- 상수/상수표현식으로 크기를 지정(크기 불변)
- 스택 메모리 영역에 할당 ➡︎ 보통 1MB 할당(이보다 더 큰 배열을 할당 시 오버플로우)
② C 스타일 배열
▶︎ C 스타일 배열 예제 코드
#include <iostream>
using namespace std;
int main()
{
int scores[5] = {50, 60, 70, 80, 90};
int sz = sizeof(scores) / sizeof(scores[0]); // int sz = size(scores);
int s = 0;
for (int i = 0; i < sz; i++) {
s += scores[i];
}
float m = (float)s / sz;
cout << "Mean score: " << m << endl;
}
Mean score: 70

③ std::array이란?
✔︎ C++에서 C 스타일 배열을 대체하는 고정 크기 컨테이너 (C++11)
- 원소의 타입과 배열 크기를 매개변수로 사용하는 클래스 템플릿
- <array> 헤더 파일에 정의되어 있음
- C 스타일 배열처럼 사용할 수 있는 [] 연산자 오버로딩을 제공
- 대입 연산자 지원 (깊은 복사)
- 배열 크기를 정확하게 알 수 있음, array::size()
- 반복자 지원
template<class T, std::size_t N> //T는 데이터 타입, N은 원소의 갯수
struct array;
▶︎ std::array 예제 코드
#include <array>
#include <iostream>
using namespace std;
int main()
{
array<int, 5> scores = {50, 60, 70, 80, 90};
int s = 0;
for (int i = 0; i < scores.size(); i++) {
s += scores[i];
}
float m = (float)s / scores.size(); cout << "Mean score: " << m << endl;
}
- std::array의 단점
ㄴ 배열의 크기를 명시적으로 지정해야 함
ㄴ 항상 스택 메모리를 사용
ㄴ 고정 크기 배열이 아닌 가변 크기 배열을 더 선호함
ㄴ 그러므로, std::vector라는 것이 더 많이 활용된다
[02. 동적 배열과 std::vector]
① 동적 메모리 할당(dynamic memory allocation)이란?
✔︎ 프로그램 실행 중 필요한 크기의 메모리 공간을 할당하여 사용하는 기법
(이 때 필요한 크기라는 것은 동작할 때마다 고정된 것이 아니라 실행할 때마다 가변적인 크기)
(ex. 동영상 편집 > 작은 크기 영상, 큰 크기 영상 이들은 동적으로 메모리 할당)
- 동적으로 할당한 메모리는 사용이 끝나면 명시적으로 (할당된) 메모리를 해제해야 함
- C 언어 : malloc() 또는 calloc() 함수로 메모리 할당하고, free() 함수로 메모리 해제
- C++ 언어: new 연산자로 메모리 할당하고, delete 연산자로 메모리 해제 (보통 그냥 이거 써라,, 응응,,)
② 동적 메모리 할당을 이용한 동적 배열 생성 및 해제
✔︎ new[] 연산자를 이용하여 동적 배열을 위한 메모리를 할당하고, delete[] 연산자를 이용하여 동적 배열 메모리를 해제!
- 동적 메모리 할당은 힙(heap) 메모리 영역을 사용하므로 대용량 배열도 할당 가능
int* ptr = new int[3];
// ptr을 배열처럼 사용. (e.g.) ptr[0], ptr[1], ptr[2]
delete [] ptr;

▶︎ 동적 배열 예제 코드
#include <iostream>
int main()
{
int n;
std::cin >> n;
// 동적 배열 할당 및 초기화 int* ptr = new int[n] {}; ptr[0] = 10;
ptr[1] = 20;
// ptr을 배열처럼 사용
for (int i = 0; i < n; i++) {
std::cout << ptr[i] << std::endl;
}
// 동적 배열 해제
delete [] ptr;
}
▶︎ 메모리를 자동으로 해제하는 동적 배열 클래스
class DynamicArray
{
private:
unsigned int sz;
int* arr;
public:
DynamicArray(int n) : sz(n) {
arr = new int[sz] {};
}
~DynamicArray() { delete [] arr; }
unsigned int size() { return sz; }
int& operator[] (const int i) { return arr[i]; }
const int& operator[] (const int i) const { return arr[i]; }
};
int main()
{
DynamicArray da(5);
da[0] = 10;
da[1] = 20;
da[2] = 30;
for (int i = 0; i < da.size(); i++)
cout << da[i] << ", ";
cout << endl;
}
➜ DynamicArray 생성자 앞에 있는 explicit 키워드는 묵시적 형변환(implicit type conversion)을 방지하기 위한 키워드로서 생략가능
③ std::vector이란?
✔︎ C++에서 C 스타일 배열을 대체하는 가변 크기 컨테이너
ㄴ 초기화 과정에 데이터 크기를 지정하지 않아도 됨
ㄴ 배열의 크기를 활장할 수 있음
- 원소의 타입을 매개변수로 사용하는 클래스 템플릿
- <vector>에 정의되어 있음
template<
class T,
class Allocator = std::allocator<T> //내부에서 동적 메모리 할당을 사용자가 지정할 수 있는데 이는 기본 코드
> class vector;
[03. std::vector 사용법과 동작 방식]
① std::vector 객체 생성과 원소 참조
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 벡터 생성 vector<int> vector<int> vector<int> vector<int>
vector<int> v1; // int 값을 저장할 비어 있는 벡터 생성
vector<int> v2(10); // int 값 10개를 저장할 벡터 생성하고 0으로 초기화
vector<int> v3(10, 1); // int 값 10개를 저장할 벡터 생성하고 1로 초기화
vector<int> v4 {10, 20, 30, 40, 50}; // 유니폼 초기화(uniform initialization)
vector<int> v5(v4); // v4를 복사하여 v5 생성
vector<int> v6(v4.begin(), v4.begin() + 3); // v4의 처음 3개 원소를 이용하여 v6 생성
// 벡터 원소 참조
for (int i = 0; i < v6.size(); i++)
cout << v6[i] << endl;
② std::vector를 이용한 2차원 벡터 생성과 원소 참조
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 벡터 생성 vector<int> vector<int> vector<int> vector<int>
vector<int> v1; // int 값을 저장할 비어 있는 벡터 생성
vector<int> v2(10); // int 값 10개를 저장할 벡터 생성하고 0으로 초기화
vector<int> v3(10, 1); // int 값 10개를 저장할 벡터 생성하고 1로 초기화
vector<int> v4 {10, 20, 30, 40, 50}; // 유니폼 초기화(uniform initialization)
vector<int> v5(v4); // v4를 복사하여 v5 생성
vector<int> v6(v4.begin(), v4.begin() + 3); // v4의 처음 3개 원소를 이용하여 v6 생성
// 벡터 원소 참조
for (int i = 0; i < v6.size(); i++)
cout << v6[i] << endl;
// 정수형 2차원 배열. 2행 3열. 0으로 초기화.
vector<vector<int>> mat1(2, vector<int>(3, 0));
// 유니폼 초기화
vector<vector<int>> mat2 {{1, 2, 3}, {4, 5, 6}};
// 2차원 벡터 출력
for (int r = 0; r < mat2.size(); r++) {
for (int c = 0; c < mat2[r].size(); c++) {
cout << mat2[r][c] << " "; }
cout << endl;
}
}
③ std::vector 주요 멤버 함수와 기능


✔︎ 자세한 동작 방식은 SKIP!
▶︎ std::vector 사용 예제
int main()
{
vector<int> vec1 {1, 2, 3, 4};
cout << vec1.capacity() << ":"<< vec1.size() << endl;
vec1.push_back(5);
cout << vec1.capacity() << ":"<< vec1.size() << endl;
vec1.push_back(6);
cout << vec1.capacity() << ":"<< vec1.size() << endl;
vec1.insert(vec1.begin(), 0);
cout << vec1.capacity() << ":"<< vec1.size() << endl;
vec1.erase(vec1.begin() + 1, vec1.begin() + 3);
cout << vec1.capacity() << ":"<< vec1.size() << endl;
for (int i = 0; i < vec1.size(); i++)
cout << vec1[i] << ", ";
}
출처: 어서와! 자료구조와 알고리즘은 처음이지? C++
'[C++ ] 자료구조' 카테고리의 다른 글
| Part5. 큐 (0) | 2023.05.15 |
|---|---|
| Part4. 스택 (0) | 2023.05.08 |
| Part3. 연결 리스트 (0) | 2023.04.11 |
| Part1. 자료구조와 알고리즘은 처음이지? (0) | 2023.03.28 |
댓글