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: ptr1이 ptr2보다 작음.
▪
0: ptr1이 ptr2보다 큼.
•
예시:
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