cpp module00

jw kim·2022년 3월 10일
1

cpp

목록 보기
1/5

module00

1. ex00
2. ex01
3. ex02

ex00

Megaphone

  1. 구현해야될것
    1. 들어오는 모든입력을 대문자로 바꿔서 출력

공부내용 : transform함수, string 클래스
//transform 은 금지된 헤더 algorithm 에 정의되어있으므로 사용하면안됨;;

std::transform

OutputIt transform( InputIt first1,
                    InputIt last1,
                    OutputIt d_first,
                    UnaryOperation unary_op );

인자값은 차례대로 first1, last1, d_first, unary_op 가 있으며 string str = “abcd” 를 처음부터 끝까지 변경하고자 한다면

c

transform(str.begin(), str.end(), str.begin(), 변경에 사용할 함수(ex. toupper)) 
위와 같이 사용할 수 있음 

세번째 인자(d_first)가 str의 특정 위치를 가리킨 포인터로 unary_op 의 연산결과가 적용되기 시작할 주소이다.

transform(str.begin(), str.end(), &str.at(2), toupper)
//string str = "abcd" 일때 결과값은 "abCD"

여러가지 호기심들이 막 고개를 드는데..

궁금한점 1 str[2]

string str = "abcd"
transform(str.begin(), str.end(), str[2], toupper)
//왜 동작안함..
/*Ans. 
In file included from test.cpp:1:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/iostream:37:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/ios:215:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__locale:15:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/string:511:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/string_view:179:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__string:57:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/algorithm:1982:9: error: indirection requires pointer operand ('int' invalid)
        *__result = __op(*__first);
  1 #include <iostream>
  2 #include <cctype>
  1 #include <iostream>
        ^~~~~~~~~
test.cpp:9:7: note: in instantiation of function template specialization 'std::transform<std::__wrap_iter<char *>, char, int (*)(int)>' requested here
        std::transform(str.begin(), str.end(), str[2], toupper);
             ^
1 error generated.
  1 #include <iostream>
*/
//네번째인자인 op에서 int 받는다고 에러뜸...  

아차차.. 값이 아니라 포인터...를 넣어야된다.

string str = "abcd"
transform(str.begin(), str.end(), &str[2], toupper)
//혹은
transform(str.begin(), str.end(), &str.at(2), toupper)
//작동잘함.. 오류상황은 어떨까 살펴봤다..
transform(str.begin(), str.end(), &str.at(10), toupper) 
// 위 코드는 작동안됨.. 
/* 결과값
libc++abi: terminating with uncaught exception of type std::out_of_range: basic_string
[1]    39424 abort      ./a.out
*/
transform(str.begin(), str.end(), &str[10], toupper) // 작동 잘함..
/* 결과값
"ABCD"
*/

transform

transform 레퍼런스 참고자료

[C++] string 클래스, 문자열에 대해서 (총정리)

string 클래스 관련 멤버함수 정리, 전부는아님! 대충 필요한것들

ex01

  1. 구현해야될것
    1. EXIT
      1. 프로그램이 종료되는기능
    2. ADD
      1. first name ~ darkest secret 까지 입력받는 기능
    3. SEARCH
      1. 4개 컬럼에 index, first name, last name, nickname 보여줘야함
      2. 각 컬럼은 10chars wide 를 가지고 오른쪽정렬되어야함, 컬럼들은 ‘|’ 로 분리, 컬럼공간을 넘는 내용은 ‘.’으로 대체되서 보여줘야함.
      3. 인덱스를 입력 받으면 해당 컬럼 내용을 보여주고 존재하지않는 인덱스면 관련 루틴 따로 구현해야함.
    4. 제대로된 명령어를 수행하고나면 다음 명령을 대기하지만 이상한 input 이 들어오면 버림.
  2. 설계
    1. 반복문으로 터미널에서 계속 입력받는다.
    2. 해당입력문자열 명령문에 맞는지 확인하는 분기문
    3. 각 문자열에 맞는 행동 구현.

ex01은 ex00 에서 배운 지식들 활용해서 구현만 하면 될듯..

ex02

Account.hpp

tests.cpp

ex02 는 재밌는 프로젝트인것 같다.

미리 헤더 파일과 test.cpp 파일을 주고 요구사항에 맞게 코딩하는 문제.

[19920104_091532] index:0;amount:42;created
[19920104_091532] index:1;amount:54;created
[19920104_091532] index:2;amount:957;created
[19920104_091532] index:3;amount:432;created
[19920104_091532] index:4;amount:1234;created
[19920104_091532] index:5;amount:0;created
[19920104_091532] index:6;amount:754;created
[19920104_091532] index:7;amount:16576;created
[19920104_091532] accounts:8;total:20049;deposits:0;withdrawals:0
[19920104_091532] index:0;amount:42;deposits:0;withdrawals:0
[19920104_091532] index:1;amount:54;deposits:0;withdrawals:0
[19920104_091532] index:2;amount:957;deposits:0;withdrawals:0
[19920104_091532] index:3;amount:432;deposits:0;withdrawals:0
[19920104_091532] index:4;amount:1234;deposits:0;withdrawals:0
[19920104_091532] index:5;amount:0;deposits:0;withdrawals:0
[19920104_091532] index:6;amount:754;deposits:0;withdrawals:0
[19920104_091532] index:7;amount:16576;deposits:0;withdrawals:0
[19920104_091532] index:0;p_amount:42;deposit:5;amount:47;nb_deposits:1
[19920104_091532] index:1;p_amount:54;deposit:765;amount:819;nb_deposits:1
[19920104_091532] index:2;p_amount:957;deposit:564;amount:1521;nb_deposits:1
[19920104_091532] index:3;p_amount:432;deposit:2;amount:434;nb_deposits:1
[19920104_091532] index:4;p_amount:1234;deposit:87;amount:1321;nb_deposits:1
[19920104_091532] index:5;p_amount:0;deposit:23;amount:23;nb_deposits:1
[19920104_091532] index:6;p_amount:754;deposit:9;amount:763;nb_deposits:1
[19920104_091532] index:7;p_amount:16576;deposit:20;amount:16596;nb_deposits:1
[19920104_091532] accounts:8;total:21524;deposits:8;withdrawals:0
[19920104_091532] index:0;amount:47;deposits:1;withdrawals:0
[19920104_091532] index:1;amount:819;deposits:1;withdrawals:0
[19920104_091532] index:2;amount:1521;deposits:1;withdrawals:0
[19920104_091532] index:3;amount:434;deposits:1;withdrawals:0
[19920104_091532] index:4;amount:1321;deposits:1;withdrawals:0
[19920104_091532] index:5;amount:23;deposits:1;withdrawals:0
[19920104_091532] index:6;amount:763;deposits:1;withdrawals:0
[19920104_091532] index:7;amount:16596;deposits:1;withdrawals:0
[19920104_091532] index:0;p_amount:47;withdrawal:refused
[19920104_091532] index:1;p_amount:819;withdrawal:34;amount:785;nb_withdrawals:1
[19920104_091532] index:2;p_amount:1521;withdrawal:657;amount:864;nb_withdrawals:1
[19920104_091532] index:3;p_amount:434;withdrawal:4;amount:430;nb_withdrawals:1
[19920104_091532] index:4;p_amount:1321;withdrawal:76;amount:1245;nb_withdrawals:1
[19920104_091532] index:5;p_amount:23;withdrawal:refused
[19920104_091532] index:6;p_amount:763;withdrawal:657;amount:106;nb_withdrawals:1
[19920104_091532] index:7;p_amount:16596;withdrawal:7654;amount:8942;nb_withdrawals:1
[19920104_091532] accounts:8;total:12442;deposits:8;withdrawals:6
[19920104_091532] index:0;amount:47;deposits:1;withdrawals:0
[19920104_091532] index:1;amount:785;deposits:1;withdrawals:1
[19920104_091532] index:2;amount:864;deposits:1;withdrawals:1
[19920104_091532] index:3;amount:430;deposits:1;withdrawals:1
[19920104_091532] index:4;amount:1245;deposits:1;withdrawals:1
[19920104_091532] index:5;amount:23;deposits:1;withdrawals:0
[19920104_091532] index:6;amount:106;deposits:1;withdrawals:1
[19920104_091532] index:7;amount:8942;deposits:1;withdrawals:1
[19920104_091532] index:0;amount:47;closed
[19920104_091532] index:1;amount:785;closed
[19920104_091532] index:2;amount:864;closed
[19920104_091532] index:3;amount:430;closed
[19920104_091532] index:4;amount:1245;closed
[19920104_091532] index:5;amount:23;closed
[19920104_091532] index:6;amount:106;closed
[19920104_091532] index:7;amount:8942;closed

프로젝트에서 제시하는 log data 를 살펴보면 [ 날자 data ] , index, amount , deposits, withdrawals 등의 데이터가 보이고 중간중간 accounts 의 총 수, total 금액, deposits 수, withdrawals 수 등등이 있다.

이를 보고 유추하기로 계좌를 만들고 각 계좌들에 입, 출금을 관리하는 프로그램을 작성하면 되는것으로 보인다.

현재 해당 프로젝트에서 모르는것(처음보는것)

  1. mem_fun_ref
  2. iterator
  3. vector
  4. pair

iterator(반복자)

module00-ex02 를 보다가 반복자에 관한 자료를 찾던중 이런 문구를 발견했다.

“iterator 를 이해하는 것이 STL을 이해하는 열쇠이다. 템플릿이 알고리즘을, 저장할 데이터 형과 무관하게 만드는 것 처럼, iterator는 알고리즘을, 사용할 컨테이너형(vector, list 등등등...)과 무관하게 만든다. iterator는 STL의 일반화 접근에 필수 구성 요소이다.”

이번 프로젝트의 의도가 사실 일반화프로그래밍의 핵심적인 개념을 배우는것이 아닐까 하는 생각이 문득 들었다.

관련 자료를 찾다가 좋은 예시를 발견했다.

ex01

double * find_ar(double *ar, int n, const double & val)
{
		for (int i = 0; i < n; i++)
				if (ar[i] == val)
						return &ar[i];
		return 0; //c++11 에서는 return nullptr; 어쨋든 널포인터 반환
}

ex02

struct Node
{
		double item;
		Node   *p_next;
};

Node *find_ll(Node *head, const double &val)
{
		Node *start;
		for (start = head; start != 0; start = start->p_next)
		if (start->item == val)
				return start;
		return 0;
}

상기 ex1,ex2 는 형태는 다르지만 특정값을 가진 컨테이너(ex1는 특정배열 요소, ex2는 특정 데이터를 가진 노드구조체)를 반환하는 공통점이 있다.

위 예시에서의 일반화 프로그래밍 목적은 다양한 컨테이너형 데이터 구조에 두루 사용할 수 있는 하나의 find 함수를 확보하는것이며, 컨테이너에 저장되어있는 데이터형에 얽매이지 않을 뿐만 아니라, 컨테이너의 구조 자체에도 얽매이지 않아야 한다.

그리고 iterator 가 바로 그러한 일반화 표현이다.

배열과 리스트 형식 모두를 만족하기위한 하나의 find 함수를 위해서 iterator 가 가져야 하는 특성은 다음과 같다.

  1. iterator가 참조하는 값에 접근하기 위한 내용참조. 즉, p 가 iterator 라면 *p 가 구현되어야 한다.
  2. 한 iterator를 다른 iterator에 대입할 수 있어야 한다. 즉, p 와 q 가 iterator라면 p = q 라는 표현이 정의되어야 한다.
  3. 한 iterator가 다른 iterator와 같은것인 비교하는 p == q, p ! = q 라는 표현이 정의되어야한다.
  4. iterator가 컨테이너에 들어있는 모든 원소들을 훑고 지나갈 수 있어야 하니 ++p, p++ 가 정의되어야 한다.

실제 iterator로 할 수 있는것은 그밖에도 많다.

struct Node
{
		double item;
		Node *p_next;
};

class iterator
{
		Node *pt;
public;
		iterator() : pt(0) { }
		iterator (Node *pn) : pt(pn) { }
		double operator *() { return pt->item; }
		iterator &operator++            // ++it 를 위해
		{
				pt = pt->p_next;
				return *this;
		}
		iterator operator++(int)
		{
				iterator tmp = *this;
				pt = pt->p_next;
				return tmp;
		}
// ... operator==(), operator!=() 등등 구현
};

위와 같이 iterator 를 정의했고,

ex01 예시에 iterator를 활용해서 리팩토링 해보자면..

//ex01.iterator ver
vector<double>::iterator pr;
for (pr = scores.begin(); pr != scores.end(); pr++)
		cout << *pr << endl;

그리고 ex02 역시 리팩토링 해보자면..

//ex02.iterator ver
list<double>::iterator pr;
for (pr = scores.begin(); pr != scores.end(); pr++)
		cout << *pr << endl;

pr의 데이터형만 유일하게 바뀌었다.

심지어 c++ 의 자동 타입추론을 통해 더욱 간단명료하게 만들 수 있다.

//더 간단한버전..
for (auto pr = scores.begin(); pr ! = scores.end(); pr++)
		cout << *pr << endl;

STL은 다섯 가지 iterator를 정의하며 다섯가지는 입력(input iterator), 출력(ouput iterator), 전방(foward iterator), 전후방(bidirectional iterator), 임의 접근(random access iterator) 등이 있다.

상기 iterator 자료는 c++ 기초플러스 라는 책 16.4 챕터 일반화 프로그래밍(1258p ~1265p) 의 내용이다.

여기서 구매가능<교보문고>

더 자세한 내용은 책에서 찾아볼 수 있지만 이번 프로젝트에서는 이정도 지식으로 통과 가능.

profile
Hitchhiker

0개의 댓글