본문 바로가기
프로그래밍

[C++] 명품 c++ 프로그래밍 실습 5장 8번

by 엽기토기 2020. 12. 23.
반응형

문제 5번의 MyIntStack를 수정하여 다음과 같이 선언하였다 스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다. MyIntStack 클래스를 작성하라.

2번째 레포트였습니다. 처음 레포트에서 설명을 자세히 안써서 감점이 됐길래, 이번 꺼는 매우 열심히 설명을 썼던 기억이 납니다 ㅠㅠ 그리고 여기에 교수님께서 stack full과 stack empty인 사례도 추가하라고 하셔서 그것도 함께 코딩했습니다.
----------------------------------------------------------------------------------------------------------------------

<8_class.h>

#pragma once
class MyIntStack {
	int *p; //스택 메모리로 사용할 포인터
	int size; //스택의 최대 크기
	int tos; //스택의 탑을 가리키는 인덱스
public:
	MyIntStack() {};
	MyIntStack(int size);
	MyIntStack(MyIntStack& s); //복사 생성자
	~MyIntStack() { delete[] p; }; //소멸자
	bool push(int n);//정수 n을 스택에 푸시한다.
			 //스택이 꽉 차 있으면 false를, 아니면 true 리턴
	bool pop(int &n);//스택의 탑에 있는 값을 n에 팝한다.
		      //만일 스택이 비어 있으면 false를, 아니면 true 리턴
};

 

<8_imp.cpp>

#include <iostream>
#include "8_class.h"
using namespace std;

MyIntStack::MyIntStack(int size) {
	tos = 0; //스택의 탑을 0으로 초기화
	this->size = size; //10들어올 예정
	p = new int[size]; //동적 메모리 할당
}
MyIntStack::MyIntStack(MyIntStack& s) { //복사 생성자 구현
	this->tos = s.tos;
	this->size = s.size;
	this->p = new int[size];
	for (int i = 0; i < size; i++) {
		p[i] = s.p[i];
	}
}

bool MyIntStack::push(int n) {
	if (tos == size) //tos가 size (10)와 같으면 false 리턴
		return false;
	else
		p[tos] = n; 
//a, p[0],p[1] 에 10과 20 들어갈 예정 / b, p[2] 에 30 들어갈 예정
	tos++; 
//a.push(20) 호출 후 tos 2 (a.pop(n)) / b.push(30) 호출 후 tos 3 (b.pop(n))
	return true;
}
bool MyIntStack::pop(int &n) { //call by reference
	if (tos == 0) //tos가 0 이면 false 리턴
		return false;
	else
		n = p[tos - 1]; // a.pop(n) n= p[1] , b.pop(n) n=p[2]
	tos--;
	return true;
}

 

<8_main.cpp>

#include <iostream>
#include "8_class.h"
using namespace std;
//문제5 번의 MyIntStack를 수정하여 다음과 같이 선언하였다. 스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다. MyIntStack 클래스를 작성하라.

int main() {
	MyIntStack a(10); //size 10
	a.push(10);
	a.push(20);
	MyIntStack b = a;//복사 생성
	b.push(30);

	int n;
	a.pop(n); //스택 a 팝  
	cout << "스택 a에서 팝한 값 " << n << endl;
	b.pop(n); //스택 b 팝  
	cout << "스택 b에서 팝한 값 " << n << endl;

	cout << endl;
	/*
	-stack empty 인 경우의 사례를 만들어 출력할 것
	- stack full 인 경우의 사례를 만들어 출력할 것
	*/
	MyIntStack stack(10);
	for (int i = 0; i < 11; i++) {
//11개를 푸시하면,마지막에는 stack full이 된다.
		if (stack.push(i)) cout << i << ' '; //푸시된 값 에코
		else cout << endl << i + 1 << " 번째 stack full" << endl;
	}
	int j;
	for (int i = 0; i < 11; i++) { 
//11개를 팝하면, 마지막에는 stack empty가 된다.
		if (stack.pop(j)) cout << j << ' '; //팝 한 값 출력
		else cout << endl << i + 1 << " 번째 stack empty";
	}
	cout << endl;
}

 

<설명>

객체 a를 생성하여 tos 0으로 초기화 시켜주고 size 10을 집어넣음. 그리고 push 함수에 n 10을 전달. tos 10이 아니기 때문에 else로 이동. p[0]=10 후에 tos++ (객체 a, tos 1). 그리고 push 함수에 n 20을 전달.  p[1]=20 후에 tos++ (객체 a, tos 2). b객체를 복사 생성. (tos, size 복사, p 배열 인자 복사, 동적메모리할당) push 함수에 n 30을 전달. p[2]=30 후에 tos++ (객체 b, tos 3).
다시 main으로 와서 변수 n을 선언. 참조에 의한 호출. 스택 a를 팝하는데, 아까 객체 a에서 tos 2, n=p[1] (20) ,tos--. 따라서 20이 출력. 그리고 스택 b를 팝하는데, 아까 객체 b에서 tos 3, n=p[2] (30), tos--. 따라서 30이 출력.
그리고 stack empty인 경우와 full인 경우의 사례를 만들었는데, 실습문제 7번과 유사하였음. 먼저 stack이라는 객체를 생성하고 size 10을 집어넣음. for문에서 p배열에 0부터 9까지 차곡차곡 쌓여서 스택이 꽉 차게 됨. 따라서 11번째 stack full 출력.
다음 for문에서 p배열에 들어가 있던 9부터 0까지 하나씩 팝하고, 스택이 비게 됨. 따라서 11번째 stack empty 출력.

<실행화면>

반응형