-
[C++] 객체와 클래스 연습문제 (2)Programming/프로그래밍 2020. 8. 16. 23:25
10장 연습문제 5번부터 8번까지 풀이다~
5.
다음과 같은 구조체 선언이 있다고 가정하자.
struct customer { char fillname[35]; double paymer; };
고객들을 나타내는 구조체들을 스택에 추가하고 삭제하는 프로그램을, Stack 클래스 선언을 이용하여 작성하라.
고객이 삭제될 때마다, 그 고객이 지불한 금액을 총 수입에 추가해야 하고, 그 총 수입을 보고해야 한다.
Stack 클래스를 변경하지 않고 그대로 사용해야 한다.
다만 customer 형을 typedef 선언으로 Item으로 변경한다.
10_5.hpp
struct customer { char fullname[35]; double paymer; }; typedef customer Item; // 스택을 구현하는데, 스택은 FILO class Stack { private: const static int MAX = 10; Item cus[MAX]; int top = 0; public: Stack(); bool isempty(); bool isfull(); bool pop(Item &itm); bool push(Item &itm); void allShow(); };
10_5.cpp
#include "10_5.hpp" Stack::Stack() { top = 0; } bool Stack::isempty() { if ( top == 0 ) return true; else return false; } bool Stack::isfull() { if ( top == MAX ) return true; else return false; } bool Stack::pop(Item &itm) { if(top <= 0) { std::cout << "꺼낼 데이터가 없습니다." << std::endl; return false; } else { top--; itm = cus[top]; return true; } } bool Stack::push(Item &itm) { if(top > MAX) { std::cout << "더 넣을 데이터 공간이 없습니다." << std::endl; return false; } else { cus[top] = itm; top++; return true; } } void Stack::allShow() { for(int i = 0; i < top; i++) { std::cout << i + 1 << " 번째 고객을 출력합니다." << std::endl; std::cout << cus[i].fullname << std::endl; std::cout << cus[i].paymer << std::endl; } } int main() { char ctrl; double total = 0; Stack stck; Item item; std::cout << "고객들을 삽입하고 삭제하는 프로그램입니다." << std::endl; while(true) { std::cout << "( 추가하려면 a, 삭제하려면 d를 입력하세요. )" << std::endl; std::cin >>ctrl; // int ctrl_int = stoi(ctrl); switch (ctrl) { case 'a' : case 'A' : if( stck.isfull() == true ) { std::cout << "스택이 꽉 차서 더 넣을 수 없습니다." << std::endl; } else { std::cout << "고객을 추가합니다. 고객 정보를 입력하세요." << std::endl; std::cout << "고객 이름 : "; std::cin >> item.fullname; std::cout << "지불한 금액 : "; std::cin >> item.paymer; stck.push(item); stck.allShow(); } break; case 'd': case 'D': if(stck.isempty() == true ) { std::cout << "스택이 비어있어서 꺼낼 데이터가 없습니다." << std::endl; } else { std::cout << "가장 최근에 입력한 고객을 삭제합니다." << std::endl; stck.pop(item); stck.allShow(); total += item.paymer; std::cout << "총 수입은 " << total << std::endl; } break; default: std::cin.clear(); std::cout << "다시 입력하세요." << std::endl; break; } } return 0; }
어떻게 보면 이건 배열로 이미 다 할당된 상태에서 pop을 했을 때, 배열에서 카운트하는 숫자를 하나 낮추어 주고 출력해준다고 봐야한다.
더 구현하려면 원래 pop을 했을 때, 실제로 할당을 해제시켜 사라지게 되어야 한다.
6.
다음과 같은 클래스 선언이 있다고 가정하자.
10_6.hpp
class Move { private: double x; double y; public: // x, y를 a, b로 설정한다. Move(double a = 0, double b = 0); void showmove() const; // 현재 x, y 값을 출력. Move add(const Move &m); // 이 함수는 호출한 객체의 x에 m의 x를 더하여 새로운 x를 얻는다. // 그리고 호출한 객체의 y에 m의 y를 더하여 새로운 y를 얻는다. // 새로운 x, y 값으로 초기화된 새로운 move 객체를 생성하여 리턴한다. void reset(double a = 0, double b = 0); // x, y를 a, b로 재설정한다. };
이 클래스를 테스트할 수 있는 멤버 함수 정의들과 간단한 테스트 프로그램을 작성하라.
10_6.cpp
#include "10_6.hpp" Move::Move(double a, double b) { x = a; y = b; } void Move::showmove() const { std::cout << "현재 x, y 를 출력합니다." << std::endl; std::cout << x << ", " << y << std::endl; } Move Move::add(const Move &m) const { Move m_tmp; m_tmp.x = m.x + x; m_tmp.y = m.y + y; return m_tmp; } void Move::reset(double a, double b) { x = a; y = b; } int main() { // 해당 메인함수의 목록들은 답지를 참고함. Move A, B; Move C(5,7); A.showmove(); B.showmove(); C.showmove(); A.reset(3,5); B.reset(7,6); C = A.add(B); A.showmove(); B.showmove(); C.showmove(); return 0; }
7.
플로그( plorg: politically driven organization )는 다음과 같은 속성을 가지고 있다.
데이터: 플로그는 19문자보다 많지 않은 이름을 가진다. 플로그는 정수로 된 하나의 만족지수( CI, contentment index)를 가진다. 동작: 1. 새로운 플로그는 하나의 이름과 CI 값 50으로 시작한다. 2. 플로그의 CI는 변경할 수 있다. 3. 플로그는 그것의 이름과 CI를 보고할 수 있다. 4. 디폴트 플로그는 "Plorga"라는 이름을 가진다.
플로그를 나타내는 Plorg 클래스 선언을 ( 데이터 멤버들과 멤버 함수 원형들을 포함하여 ) 작성하라.
그 멤버 함수들의 함수 정의를 작성하라. Plorg 클래스의 모든 기능이 바르게 동작하는지 보여주는 간단한 프로그램을 작성하라.
코드
10_7.hpp
#include <iostream> class plorg { private: char name[19]; // 이름을 가진다. int CI = 0; // 만족 지수 public: plorg(); void changeCI(int ci); // 플로그의 CI값을 변경할 수 있다. void showPlorg(); // 플로그는 그것의 이름과 CI를 보고할 수 있다. };
10_7.cpp
#include "10_7.hpp" // 4.. 디폴트 플로그는 "Plorga"라는 이름을 가진다. plorg::plorg() { strcpy(name, "plorga"); CI = 50; // 1. 새로운 플로그는 하나의 이름과 CI 값 50으로 시작한다. } // 2. 플로그의 CI값을 변경할 수 있다. void plorg::changeCI(int ci) { CI = ci; } // 3. 플로그는 그것의 이름과 CI를 보고할 수 있다. void plorg::showPlorg() { std::cout << "플로그를 출력합니다." << std::endl; std::cout << name << std::endl; std::cout << CI << std::endl; } int main() { plorg plr; plr.showPlorg(); plr.changeCI(5); plr.showPlorg(); return 0; }
8.
간단한 리스트를 다음과 같이 서술할 수 있다.
- 리스트에 특정 데이터형의 항목을 0개 또는 그 이상을 저장할 수 있다.
- 비어있는 리스트를 생성할 수 있다.
- 리스트에 항목들을 추가할 수 있다.
- 리스트가 비어 있는지 결정할 수 있다.
- 리스트가 가득 차 있는지 결정할 수 있다.
- 리스트의 각 항목에 대해 몇 가지 원하는 동작을 수행할 수 있다.
보다시피, 이 리스트는 매우 간단하다. 이 리스트는 중간 삽입이나 중간 삭제를 허용하지 않는다.
이 추상화 데이터형을 나타내는 List 클래스를 설계하라.
클래스 선언을 가진 헤더파일과 메서드 구현을 가진 파일을 제공해야 한다. -> main 함수 파일로 뭉치도록 하겠습니다.
또한, 그 클래스 설계를 이용하는 짧은 프로그램을 작성해야 한다.
리스트 사양을 간단하게 유지하는 주된 이유는, 이 프로그래밍 연습을 단순화하기 위해서이다.
리스트를 배열을 구현할 수도 있고, 데이터형에 익숙하다면 링크드 리스트로 구현할 수도 있다.
그러나, public 인터페이스는 리스트를 무엇으로 구현하든 상관없어야 한다.
즉, public 인터페이스는 리스트를 생성하고, 리스트에 새 항목을 추가하는 등의 일반적인 개념으로 표현되어야 한다.
리스트의 각 항목들에 접근하여 원하는 동작을 수행하는 일반적인 방법은,
함수 포인터를 매개변수로 취하는 다음과 같은 함수를 사용하는 것이다.
void visit(void (*pf)(Item &));
여기서 pf는 Item 매개변수에 대한 참조를 취하는 ( 멤버 함수가 아닌 ) 어떤 함수를 지시한다.
Item은 그 리스트에 있는 항목들의 데이터형이다. 그리고 visit() 함수는 리스트에 있는 각 항목에 이 함수를 적용한다.
일반적인 지침으로 Stack 클래스를 사용할 수 있다.
10_8.h
struct Item { int data; Item *next; }; class List { private: Item *head; Item *tail; public: List(); void addNode(int ); void show(); void visit(void (*pf)(Item &)); };
10_8.cpp
#include "10_8.hpp" List::List() { head = nullptr; tail = nullptr; } void List::addNode(int n) { Item *item = new Item; item->data = n; item->next = nullptr; if( head == nullptr) { head = item; tail = item; } else { tail->next = item; tail = tail->next; } } void List::deleteList() { Item *node = head; while(node != nullptr) { head = node->next; delete node; node = head; } std::cout << std::endl; } void List::visit(void (*pf)(Item &item)) { } void List::show() { Item *node = head; while(node != nullptr) { std::cout << node->data << " "; node = node->next; } std::cout << std::endl; } int main() { List list; list.addNode(5); list.addNode(10); list.addNode(15); list.show(); list.deleteList(); return 0; }
연결리스트로 구현했는데 값을 넣는데로 출력하는 것까지 해봤다..
함수포인터는 아딕..
반응형'Programming > 프로그래밍' 카테고리의 다른 글
[PHP] 표준 권고 ( PSR ) (0) 2020.09.07 [PHP] Composer classmap 사용 (0) 2020.09.05 [C++] 객체와 클래스 연습문제 (1) (0) 2020.08.14 [C++] 함수 - C++ 의 프로그래밍 모듈 (2) (0) 2020.08.07 [C++] 함수 - C++의 프로그래밍 모듈 (1) (0) 2020.08.06