cpp(stl)

cpp5(stream_iterator/vector로 파일읽기/structured binding/연산자오버로딩)

yam3u 2025. 3. 27. 02:08

250320 수업 + 모르는 이것저것

 

폰트랑 글자 크기 다 설정해놓고 막상 올리면 자꾸 초기화됨..너무짜증남..왜이래요티스토리ㅡㅡ

 

메모리영역

 

메모리가 어디에 들어가야할지..->이건 os가 정함.

크게 Data, Stack, free-store 가 있다.

먼저

Data영역(Static)

프로그램이 실행될 때, 초기화된 전역변수와 정적변수가 저장되는 공간.

프로그램이 종료될 때 까지 이 데이터는 유지된다!

int a = 10;   => 전역변수

static int b = 5; => 정적변수

 

Stack영역

└ 함수 호출 시 생성되는 지역변수, 매개변수가 저장되는 공간.

LIFO구조로.. 함수 호출/리턴에 따라 자동으로 메모리 할당과 해제가 일어남.

stack은.. 메모리 한계를 초과하면 스택 오버플로우가 발생한다!!!

 

free-store영역(or... heap 영역)

└ new, malloc 등 프로그래머.. 즉 우리가 직접 데이터를 동적할당한 메모리 공간

메모리 해제가 필요하고.. 안하면 메모리 누수가 발생한다~!

 

셋중에는 freestore가 제일 많은 데이터가 들어갈 수 있다고 한다..

 

 

stream_iterator 반복자에 관해

수업했던거 복습하다가... 코드는 맞는뎀 *pos값이 안나와서 뭐지??했는데

찾아보니 istream_iterator(스트림 반복자)는... 일방통행만을 함.

파일 끝(EOF)에 도착하면 다시 처음으로 돌아가지 않는게 문제였다

이미 in>>num을 하면서.. in의 스트림 자체가 이미 파일끝에 도달해있으니

std::istream_iterator<int>{in}부터 {}까지 읽고싶어도 못읽는것임

반복자가 스트림 기반일때는.. 읽고나면 진 짜 끝. 이런 느낌이라 다시 쓰려면 초기화를 해줘야된다

 

그래서 처음으로 이동을 시켜줘야한다...

in.clear();

in.seekg(0);

을 해주면 된다네여

이렇게 해주면 다시 istream_iterator가 첨부터 돌면서 끝까지 값을 훑어볼 수 있다

 

 

컨테이너+file읽어오기

컨테이너란... 데이터를 저장하고 관리하는 클래스(자료구조)

자료를 담는 그릇! 이라고 생각하면 편하다..

내가 지금 배우는 stl에서는... 자료구조를 일반화된 형태로 템플릿 클래스로 만들어 놓음.

그래서 자료형과 상관없이 다양한 타입의 데이터를 저장할 수 있도록 해줌!!

set이나.. map을 사용할 수 있다..!

이런 컨테이너 안에서.. std::find 같은 걸 사용해서 원하는 값을 찾을 수 있음.

iota, find, max_element, minmax_element 같은 편리한 알고리즘을 이용할 수 있다!!

여기에 있는걸 내가 코딩해선 안된다... 이미 알고리즘이 있는데 내가 왜? 이런 마인드

 

또한 파일을 읽을때...

read, write -> 바이너리 전용.. 

read() => 파일-> 메모리 (바이너리로 읽어올 때)

사용법은.... a가 int배열이라면~

in.read( (char*)a.data(), a.size() * sizeof(int) )

in.read( (char*)&a, sizeof(a))

이렇게 쓰긴하지만

전자로 쓰는게 안전하다.... 

a.size() -> 요소갯수

sizeof(int) -> 한 요소가 차지하는 바이트

====> 이러면 정확한 데이터의 바이트 수를 구할 수 있음.

만약에 a가 포인터라면....? (포인터는 무조건 8바이트) 이러면 바이트 수가 잘못 계산됨

아무튼 정확한 계산을 위해서... 저렇게 쓰도록 ㅎㅏ자~

 

write() => 메모리 -> 파일 (바이너리로 저장할 때)

out.write(

텍스트 파일은 텍스트 모드에서 읽어야함. 괜히 이미 텍스트모드로 저장된걸 바이너리로 열겠다고 ios::binary 해봤자 의미 없음.

바이너리로 열때는 read()를, 저장을 시키고싶을땐 write()

 

텍스트모드일때는 copy()로....! 

근데 우리는 파일 크기를 항상 아는게 아니니... vector를 쓰는게 좋음.

vector로 파일을 받고싶으면 선언과 동시에 저장해주도록 하자..

직접 치면서.. 해봤던 것들

참고로 여기서... std::istream_iterator<std::string>는 공백단위로 단어를 읽어옴

그래서 실제로

osefef

sodfseof 

이렇게 저장이 되어있어도.. 배열에는 줄단위로 들어가지 않는다

출력을 해도 osefef sodfseof  이런식으로 나옴

만약에 줄단위로 읽고싶으면? getline 써주면됨.. (줄단위로 읽어오는애)

얘는 바로 vector 활용은 안되니 while루프 써서 고 안에 pushback 쓰면된다네요

이런식으로.. \n을 써줘야ㅠ 내가 저장했던 그대로 출력이됨

출력결과를 보자면 이렇게.. 차이를 볼 수 있다

 

 

 


아 이제 진짜 수업에서 했던거 정리해야됨.. 계속 다른길로 빠지네^^

 

std::pair과 structured binding

structured binding 이란?

c++17부터 등장한 문법으로...

pair, tuple, struct 등 여러 값을 가지는 객체를 자동으로 분해해서 변수에 할당해주는 기능이라고 함.

이런식으로.. 값을 뽑아서 (구조분해) 를 해서 std::pair로 각 각 넣어준 것.. 

따라서 std::pair는 두개의 값을 묶는 자료형

structured binding은 그걸 자동으로 [a,b]식으로 나눠주는 문법임..

 

*std::pair는 std::map과 궁합이 좋음

std::map은 하나의 key에 하나의 value가 짝인 컨테이너 

std::map은 내부적으로.. pair<const Key, Value> 구조로 동작.
또한 key값을 자동으로 정렬해준다...
=> 왜냐면 내부적으로 이진탐색트리 구조로 되어있기 때문!!
이진탐색트리는 항상 정렬된 상태로 유지하도록 구조가 설계되어있담
값을 삽입할때 마다 key를 기준으로 자동정렬됨!

또한 중복된 key의 값이 들어가지 않는다..! 

 

이렇게 예시를 들자면...

내가 아무리 banana를 첫번째로 삽입했어도 map이 알아서 알파벳 순으로 값을 정렬해줌.

또한 apple과 yaloyalo를 추가하고싶어도, apple은 이미 key값으로 들어가있으니

중복!

따라서 yaloyalo만 정렬되어 insert 된다...

 

만약.. 정렬이 싫다면?
std::unordered_map을 사용하면 됨.
정렬이 안되는 map, key순서도 랜덤, 삽입한 순서대로도 x
간단히 말해 순서 보장이 안됨!!

 

friend + 연산자 오버로딩

전부터 friend함수가 뭔지 궁금했다.. 종종 클래스에 있는 값을 출력하고 싶을때..?였나..

아무튼 왜 안되는건지 알고싶었음.. cpp할때는 이해할생각도 안하고 그냥 되니까 되겠지~하고 넘어감ㅋ

 

cpp에서 클래스의 private 멤버에 접근할 수 있도록 허용해주는 특수 키워드..란다. 

friend가 없으면 접근이 불가능함. 

friend를 선언했으니 Dog객체에 존재하는 private 멤버들에 접근이 가능한 것.. 

 

Dog 클래스 내부의 데이터를 << >>로 직접 입출력 하고 싶을 때 friend 가 필요하다~

 

*연산자 오버로딩이 뭐야.. 연산자 오버로딩이 왜 필요한데?

std::cout << 은 내가 만든 클래스는 모름. 

그러니까 operator<<를 오버로딩해서

Dog를 만나면 이렇게 출력해줘~~ 라고 알려주는 거임..

위 코드에서는 cout<< dog는.. 출력용 operator<<를 dog 클래스 안에 선언해준 것. 

그러므로 위의 함수가 불러진다..

언젠가 dog가 write..를 불러오는 저장용 operator<<를 만나면 아래 함수가 불러진다..

현재 이 코드에서는 둘다 같이 사용하지 못함..(왜냐면 매개변수가 같으니까)

 

 

ㄲㅡㅌ..

'cpp(stl)' 카테고리의 다른 글

cpp7(함수포인터/collable/람다) 4w2  (0) 2025.04.11
cpp6(RAII/throw/unique_ptr) 4w1  (0) 2025.04.08
cpp4(파일입출력/바이너리모드/저수준출력)  (0) 2025.03.19
cpp3(안전배열/file입출력)  (0) 2025.03.19
cpp2(template-1)  (0) 2025.03.12