Search

STL 요약 정리

STL : Standard Template Library 의 약자로 프로그래밍적으로 자주 사용되는 기능들을 만들어둔 라이브러리 이다.

1. <vector>

역할:
크기가 동적으로 조정되는 배열입니다.
요소는 연속된 메모리 공간에 저장되어 빠른 임의 접근을 제공합니다.
삽입/삭제는 뒤에서 수행될 때 효율적(push_back, pop_back).
주요 메서드:
push_back(value): 요소를 맨 뒤
size(): 요소 개수 반환.
clear(): 모든 요소
int main() { std::vector<int> v = { 1, 2, 3, 4, 5 }; v.push_back(6); v.pop_back(); // 벡터의 크기 할당과 동시에 값 초기화 default 0 //v.reserve(10); v.resize(10); int len = v.size(); for (int num : v) { std::cout << num << std::endl; //std::cout << v[i] << std::endl; } return 0; }
C++
복사

2. <list>

역할:
이중 연결 리스트로, 임의 위치에서의 삽입/삭제가 효율적입니다.
연속된 메모리 공간이 아니므로 임의 접근이 느립니다.
주요 메서드:
push_front(value): 맨 앞에 요소 추가.
push_back(value): 맨 뒤에 요소 추가.
remove(value): 특정 값을 가진 요소 제거.
int main() { std::list<int> list; list.push_back(1); list.push_front(2); //for (std::list<int>::iterator iter = list.begin() // ; iter != list.end() // ; iter++) //{ // std::cout << *(iter) << std::endl; //} for (int v : list) { std::cout << v << std::endl; } return 0; }
C++
복사

3. <map>

역할:
키-값 쌍을 저장하며, 키는 자동으로 정렬됩니다.
이진 검색 트리를 사용하여 검색, 삽입, 삭제가 효율적(O(log n)).
키는 중복이 불가능하다.
주요 메서드:
operator[key]: 키를 사용해 값을 설정하거나 가져옴.
find(key): 키 검색.
erase(key): 키에 해당하는 값 삭제.
int main() { std::map<int, std::string> map; map.insert(std::make_pair(1, "one")); //std::pair<int, std::string> pair(3, "three"); //map.insert(pair); map.insert({ 2, "two" }); map.insert({ 5, "five" }); map.insert({ 8, "eight" }); map.insert({ 6, "six" }); map.insert({ 12, "twelve" }); std::cout << map[2]; std::map<int, std::string>::iterator iter = map.find(5); std::cout << iter->second; return 0; }
C++
복사

4. <set>

역할:
유일한 값만 저장하며 자동으로 정렬됩니다.
중복 값 삽입 시 무시됩니다.
주요 메서드:
insert(value): 값 삽입.
erase(value): 값 제거.
find(value): 값 검색.
int main() { std::set<int> s; s.insert(1); s.insert(2); s.insert(3); std::set<int>::iterator iter = s.find(2); return 0; }
C++
복사

5. <algorithm>

역할:
정렬, 검색, 수학적 계산 등 알고리즘 함수를 제공합니다.
주로 반복자와 함께 사용됩니다.
주요 함수:
sort(begin, end): 정렬.
find(begin, end, value): 값 검색.
reverse(begin, end): 순서 뒤집기.
struct Point { int x, y; Point(int x, int y) : x(x), y(y) {} }; bool compare(Point a, Point b) { return a.y > b.y; } int main() { std::vector<int> v = { 1,2,32,4,51,6,767,8,89,10 }; //std::sort(v.begin(), v.end(), [](int a, int b) {return a > b; }); std::sort(v.begin(), v.end(), std::greater<int>()); std::sort(v.begin(), v.end(), std::less<int>()); std::vector<Point> v2 = { {3,4}, {1,2}, {5,6} }; //std::sort(v2.begin(), v2.end(), [](Point a, Point b) // { // return a.x < b.x; // }); std::sort(v2.begin(), v2.end(), compare); return 0; }
C++
복사

6. <queue>

역할:
FIFO(First-In-First-Out) 큐를 구현합니다.
끝에서 삽입하고 앞에서 삭제합니다.
주요 메서드:
push(value): 요소 추가.
pop(): 요소 제거.
front(): 첫 번째 요소 반환.
int main() { std::queue<int> q; q.push(1); q.push(2); q.push(3); q.push(4); int first = q.front(); q.pop(); q.pop(); q.pop(); return 0; }
C++
복사

7. <stack>

역할:
LIFO(Last-In-First-Out) 스택을 구현합니다.
마지막으로 추가된 요소가 가장 먼저 제거됩니다.
주요 메서드:
push(value): 요소 추가.
pop(): 요소 제거.
top(): 마지막 요소 반환.
int main() { std::stack<int> st; st.push(1); st.push(2); st.push(3); st.push(4); int top = st.top(); st.pop(); st.pop(); st.pop(); return 0; }
C++
복사

8. <unordered_map>

역할:
해시 테이블 기반의 키-값 저장소로, 순서는 보장되지 않습니다.
검색, 삽입, 삭제가 평균적으로 O(1)입니다.
주요 메서드:
operator[key]: 키를 통해 값 설정/조회.
erase(key): 키에 해당하는 값 삭제.
int main() { std::unordered_map<int, std::string> map; map.insert(std::make_pair(1, "one")); //std::pair<int, std::string> pair(3, "three"); //map.insert(pair); map.insert({ 2, "two" }); map.insert({ 5, "five" }); map.insert({ 8, "eight" }); map.insert({ 6, "six" }); map.insert({ 12, "twelve" }); std::cout << map[2]; std::unordered_map<int, std::string>::iterator iter = map.find(5); std::cout << iter->second; return 0; }
C++
복사

9. <unordered_set>

역할:
해시 테이블 기반의 고유 값 저장소로, 순서는 보장되지 않습니다.
평균적으로 O(1) 복잡도로 값 검색/삽입/삭제가 가능합니다.
주요 메서드:
insert(value): 값 추가.
find(value): 값 검색.
int main() { std::unordered_set<int> s; s.insert(1); s.insert(2); s.insert(3); std::unordered_set<int>::iterator iter = s.find(2); return 0; }
C++
복사

10.std::functional

<functional> 헤더는 C++에서 함수 객체, 람다 함수, 일반 함수 포인터 등을 추상화하여 사용할 수 있는 범용 함수 래퍼std::function을 제공합니다. 이를 통해 함수 호출을 캡슐화하고, 매개변수로 전달하거나 반환값으로 사용하는 기능을 쉽게 구현할 수 있습니다.

주요 특징

1.
다형성: 함수 포인터, 람다 함수, 일반 함수, 멤버 함수 등 다양한 함수 호출 대상과 함께 사용 가능.
2.
유연성: 함수 서명을 기준으로 정의되며, 동일한 서명을 가진 함수들을 자유롭게 처리.
3.
콜백 처리: 이벤트 기반 프로그래밍이나 함수 전달 방식에서 유용.

사용법

1.
선언
cpp 코드 복사 std::function<ReturnType(ArgType1, ArgType2, ...)> func;
C++
복사
ReturnType: 함수의 반환형.
ArgType1, ArgType2, ...: 함수의 매개변수 타입.
2.
호출
함수 호출 연산자 ()로 캡슐화된 함수 실행.

예제 1: 함수 포인터와 함께 사용

cpp 코드 복사 #include <functional> #include <iostream>// 일반 함수 int add(int a, int b) { return a + b; } int main() { std::function<int(int, int)> func = add; std::cout << "Result: " << func(2, 3) << "\n"; // 출력: 5 return 0; }
C++
복사

예제 2: 람다 함수와 함께 사용

cpp 코드 복사 #include <functional> #include <iostream> int main() { // 람다 함수 정의 std::function<int(int, int)> func = [](int a, int b) { return a * b; }; std::cout << "Result: " << func(4, 5) << "\n"; // 출력: 20 return 0; }
C++
복사

예제 3: 멤버 함수와 함께 사용

cpp 코드 복사 #include <functional> #include <iostream> class Calculator { public: int subtract(int a, int b) { return a - b; } }; int main() { Calculator calc; // 멤버 함수를 std::function으로 캡슐화 std::function<int(Calculator*, int, int)> func = &Calculator::subtract; std::cout << "Result: " << func(&calc, 7, 3) << "\n"; // 출력: 4 return 0; }
C++
복사

예제 4: 콜백 함수로 사용

cpp 코드 복사 #include <functional> #include <iostream> void processTask(const std::function<void(int)>& callback) { for (int i = 1; i <= 5; ++i) { callback(i); } } int main() { processTask([](int value) { std::cout << "Processing value: " << value << "\n"; }); return 0; }
C++
복사

장점

1.
유연성: 다양한 함수 호출 대상과 호환 가능.
2.
추상화: 함수 포인터와 람다 함수 등을 통일된 방식으로 처리.
3.
콜백 처리: 이벤트 기반 프로그래밍에서 매우 유용.

주의사항

1.
오버헤드: std::function은 래퍼로서 약간의 런타임 오버헤드를 가질 수 있습니다.
2.
타입 불일치: 함수 서명이 정확히 일치해야 작동합니다.
std::function은 함수 호출을 캡슐화하고, 유연한 프로그래밍을 가능하게 하여 복잡한 함수 호출 체계를 단순화할 때 매우 유용한 도구입니다.

11. <memory.h> 헤더

<memory.h>는 C 언어의 표준 헤더 중 하나로, 메모리 조작 함수들을 제공합니다. 그러나 C++에서는 동일한 기능을 제공하는 <cstring> 헤더를 사용하는 것이 더 일반적입니다. <memory.h>는 대부분의 컴파일러에서 <cstring>과 동일한 역할을 하며, C++ 코드에서도 사용할 수 있지만, 최신 C++ 스타일에서는 <cstring>을 권장합니다.

주요 함수

<memory.h>는 메모리를 초기화하거나 복사, 비교, 이동 등의 작업을 수행하는 함수들을 제공합니다.

1. memset

역할: 메모리를 특정 값으로 초기화.
형식:
cpp 코드 복사 void* memset(void* ptr, int value, size_t num);
C++
복사
ptr: 초기화할 메모리의 시작 주소.
value: 초기화할 값 (0~255).
num: 초기화할 바이트 크기.
예시:
cpp 코드 복사 #include <memory.h> #include <iostream> int main() { char buffer[10]; memset(buffer, 'A', sizeof(buffer)); // 'A'로 초기화 for (char c : buffer) { std::cout << c << " "; // 출력: A A A A A A A A A A } return 0; }
C++
복사

2. memcpy

역할: 메모리 블록을 다른 메모리로 복사.
형식:
cpp 코드 복사 void* memcpy(void* dest, const void* src, size_t num);
C++
복사
dest: 복사될 대상 메모리의 주소.
src: 복사할 원본 메모리의 주소.
num: 복사할 바이트 크기.
예시:
cpp 코드 복사 #include <memory.h> #include <iostream> int main() { char src[] = "Hello"; char dest[10]; memcpy(dest, src, sizeof(src)); // src 내용을 dest로 복사 std::cout << dest << "\n"; // 출력: Hello return 0; }
C++
복사

3. memcmp

역할: 두 메모리 블록을 바이트 단위로 비교.
형식:
cpp 코드 복사 int memcmp(const void* ptr1, const void* ptr2, size_t num);
C++
복사
ptr1, ptr2: 비교할 두 메모리 블록의 주소.
num: 비교할 바이트 크기.
반환값:
0: 두 메모리 블록이 같음.
<0: ptr1ptr2보다 작음.
0: ptr1ptr2보다 큼.
예시:
cpp 코드 복사 #include <memory.h> #include <iostream> int main() { char a[] = "Hello"; char b[] = "World"; if (memcmp(a, b, 5) == 0) { std::cout << "Equal\n"; } else { std::cout << "Not Equal\n"; // 출력: Not Equal } return 0; }
C++
복사

4. memmove

역할: 겹치는 메모리 영역에서도 안전하게 데이터를 복사.
형식:
cpp 코드 복사 void* memmove(void* dest, const void* src, size_t num);
C++
복사
dest: 복사 대상 메모리 주소.
src: 복사 원본 메모리 주소.
num: 복사할 바이트 크기.
예시:
cpp 코드 복사 #include <memory.h> #include <iostream> int main() { char data[] = "HelloWorld"; memmove(data + 5, data, 5); // "HelloHello"로 변경 std::cout << data << "\n"; // 출력: HelloHello return 0; }
C++
복사

기능 요약

함수
역할
memset
메모리를 특정 값으로 초기화
memcpy
메모리 블록을 복사
memcmp
메모리 블록을 비교
memmove
겹치는 영역에서 메모리를 안전하게 복사

C++에서의 권장 사항

C++ 스타일에서는 <memory.h> 대신 <cstring>을 사용하는 것이 더 일반적입니다.
STL 컨테이너(std::vector, std::array 등)를 활용하면 이러한 함수 대신 고수준 메서드를 사용할 수 있어 코드가 더 안전하고 가독성이 높아집니다.

스마트 포인터 (Smart Pointer)

스마트 포인터는 C++에서 동적 메모리를 안전하고 효율적으로 관리하기 위해 사용하는 클래스입니다. 표준 라이브러리에서 제공하는 스마트 포인터는 동적 메모리의 수명 관리를 자동으로 처리하여 메모리 누수잘못된 메모리 접근을 방지합니다.
스마트 포인터는 <memory> 헤더에 포함되어 있으며, 대표적인 스마트 포인터는 다음과 같습니다:
1.
std::unique_ptr
2.
std::shared_ptr
3.
std::weak_ptr