[C++] 명품C++ Programming 5장 : 실습문제

녹차·2024년 6월 20일

C++

목록 보기
6/11

Chapter5 문제 [10/12]

5-1

두 개의 Circle 객체를 교환하는 swap() 함수를 '참조에 의한 호출'이 되도록 작성하고 호출하는 프로그램을 작성하라.

#include<iostream>

using namespace std;

class Circle
{
	int rad;
public:
	Circle(int r = 1) { this->rad = r; }
	int getR() { return rad; }
};


int main()
{
	Circle r1(5);
	Circle r2(4);
	
	cout << r1.getR() << " " << r2.getR() << endl;

	swap(r1, r2);

	cout << r1.getR() << " " << r2.getR();
}

5-2

다음 main() 함수와 실행 결과를 참고하여 half() 함수를 작성하라.

int main() {
    double n = 20;
    half(n); // n의 반값을 구해 n을 바꾼다. 
    cout << n; // 10이 출력된다. 
}
10
#include<iostream>

using namespace std;

void half(double &number)
{
	number = number / 2;
}

int main()
{
	double n = 20;
	half(n); 
	cout << n;
}

5-3

다음과 같이 작동하도록 combine() 함수를 작성하라.

int main() {
    string text1("I love you"), text2("very much");
    string text3; // 비어있는 문자열 
    combine(text1, text2, text3); // text1과 " ", 그리고 text2를 덧붙여 text3 만들기 
    cout << text3; // "I love you very much" 출력
}
I love you very much
#include<iostream>
#include<string>

using namespace std;

void combine(string text1, string text2, string& text3)
{
	text3 = text1 + " " + text2;
} 

int main()
{
	string text1("I love you"), text2("very much");
	string text3;

	combine(text1, text2, text3);

	cout << text3;
}

5-4

아래와 같이 원형이 주어진 bigger()를 작성하고 사용자로부터 2개의 정수를 입력받아 큰 값을 출력하는 main()을 작성하라.

bigger()는 인자로 주어진 a, b가 같으면 true, 아니면 false를 리턴하고 큰 수는 big에 전달한다.

bool bigger(int a, int b, int& big);
#include<iostream>
#include<string>

using namespace std;

bool bigger(int a, int b, int& big)
{
	if (a == b)
		return true;

	if (a > b)
	{
		big = a;
		return false;
	}
	else
	{
		big = b;
		return false;
	}
}

int main()
{
	int a, b;
	int bigNum;

	cin >> a >> b;

	bigger(a, b, bigNum);

	cout << a << "와 " << b << " 중 큰 수는>> " << bigNum;
}

5-5

다음 Circle 클래스가 있다.

class Circle{
    int radius;
public:
    Circle(int r) {radius =r;}
    int getRadius() {return radius;}
    void setRadius(int r) {radius = r;}
    void show() {cout << "반지름이 " << radius << "인 원" << endl;} 
};

Circle 객체 b를 a에 더하여 a를 키우고자 다음 함수를 작성하였다.

int main() {
    Circle x(10), y(5);
    increaseBy(x, y); // x의 반지름이 15인 원을 만들고자 한다. 
    x.show(); // "반지름이 15인 원"을 출력한다. 
}
#include<iostream>

using namespace std;

class Circle
{
	int r;
public:
	Circle(int r) { this->r = r; };
	int getR() { return r; }
	void setR(int r) { this->r = r; }
	void show() { cout << "반지름이 " << r << "인 원" << endl; }
	~Circle();
};

Circle::~Circle()
{
}

void incressBy(Circle &a, Circle b)
{
	int r = a.getR() + b.getR();
	a.setR(r);
}

int main()
{
	Circle c1(10), c2(5);

	incressBy(c1, c2);

	c1.show();
}

5-6

find() 함수의 원형은 다음과 같다. 문자열 a에서 문자 c를 찾아, 문자 c가 있는 공간에 대한 참조를 리턴한다.

만일 문자 c를 찾을 수 없다면 success 참조 매개 변수에 false를 설정한다.

물론 찾게 되면 success에 true를 설정한다.

char& find(char a[], char c, bool& success);

다음 main()이 잘 실행되도록 find()를 작성하라.

int main() {
    char s[] = "Mike";
    bool b = false;
    char& loc = find(s, 'M', b);
    if(b == false) {
        cout << "M을 발견할 수 없다" << endl;
        return 0; 
    }
    loc = 'm'; // 'M' 위치에 'm' 기록 
    cout << s << endl; // "mike"가 출력됨 
}

5-7

다음과 같이 선언된 정수를 저장하는 스택 클래스 MyIntStack을 구현하라.

MyIntStack 스택에 저장할 수 있는 정수의 최대 개수는 10이다.

class MyIntStack{
    int p[10]; // 최대 10개의 정수 저장 
    int tos; // 스택의 꼭대기를 가리키는 인덱스 
public:
    MyIntStack();
    bool push(int n); // 정수 n 푸시. 꽉 차 있으면 false, 아니면 true 리턴 
    bool pop(int &n); // 팝하여 n에 저장. 스택이 비어 있으면 false, 아니면 true 리턴 
};

MyIntStack 클래스를 활용하는 코드와 실행 결과는 다음과 같다.

int main() {
    MyIntStack a;
    for(int i=0; i<11; i++) { // 11개를 푸시하면, 마지막에는 stack full이 된다. 
        if(a.push(i)) cout << i << ' '; // 푸시된 값 에코 
        else cout << endl << i+1 << " 번째 stack full" << endl;
    }
    int n;
    for(int i=0; i<11; i++) { // 11개를 팝하면, 마지막에는 stack empty가 된다. 
        if(a.pop(n)) cout << n << ' '; // 팝 한 값 출력 
        else cout << endl << i+1 << " 번째 stack empty";
    }
    cout << endl;
}
0 1 2 3 4 5 6 7 8 9
11 번째 stack full
9 8 7 6 5 4 3 2 1 0
11 번째 stack empty
#include<iostream>

using namespace std;

class  MyInStack
{
	int p[10];
	int tos; //스택의 꼭대기를 가리키는 인덱스
public:
	 MyInStack();
	 bool push(int n); //정수 n 푸시, 꽉 차 있으면 fa, 아니면 true
	 bool pop(int& n);
};

MyInStack:: MyInStack()
{
	for (int i = 0; i < 10; i++)
		p[i] = 0;

	tos = 0;
}

bool MyInStack::push(int n)
{
	if (tos < 10) {
		p[tos] = n;
		tos++;
		return true;
	}
	else
		return false;
}

bool MyInStack::pop(int& n)
{
	n = p[--tos];

	if (tos >= 0) 
	{
		p[tos] = 0;
		return true;
	}
	else
		return false;
}

int main()
{
	MyInStack a;

	for (int i = 0; i < 11; i++)
	{
		if (a.push(i) == true) cout << "p[" << i << "] = " << i << ' ';
		else cout << endl << i + 1 << " 번째 stack full" << endl;
	}

	int n;

	for (int i = 0; i < 11; i++)
	{
		if (a.pop(n) == true) cout << n << ' ';
		else cout << endl << i + 1 << " 번 째 stack empty";
	}

	cout << endl;
}

풀지 못한 이유

int tos을 조금 더 의식해서 조금 더 활용해봤어야 했는데 pop을 하는 과정에서 계속 막혀 결국 솔루션을 보고 이해하였다.

5-8

문제 7번의 MyIntStack을 수정하여 다음과 같이 선언하였다.

스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다.

MyIntStack 클래스를 작성하라.

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

MyIntStack 클래스를 활용하는 코드와 실행 결과는 다음과 같다.

int main () {
    MyIntStack a(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; 
}
스택 a에서 팝한 값 20
스택 b에서 팝한 값 30
#include<iostream>

using namespace std;

class  MyInStack
{
	int* p; //스택 메모리로 사용할 포인터
	int tos; //스택의 꼭대기를 가리키는 인덱스
	int size; //스택의 최대 크기
public:
	MyInStack();
	MyInStack(int size);
	MyInStack(const MyInStack& s); //복사 생성자
	~MyInStack();
	bool push(int n);
	bool pop(int& n);
};

MyInStack::MyInStack()
{
	*p = 0;
	tos = 0;
	size = 0;
}

MyInStack::MyInStack(int size)
{
	this->size = size;
	p = new int[size];
	tos = 0;
}

MyInStack::MyInStack(const MyInStack& s)
{
	this->size = s.size;
	this->tos = s.tos;
	p = new int[s.size];
}

MyInStack::~MyInStack()
{

}

bool MyInStack::push(int n)
{
	if (tos < 10) {
		p[tos] = n;
		tos++;
		return true;
	}
	else
		return false;
}

bool MyInStack::pop(int& n)
{
	n = p[--tos];

	if (tos >= 0)
	{
		p[tos] = 0;
		return true;
	}
	else
		return false;
}

int main()
{
	MyInStack a(10);
	a.push(10);
	a.push(20);

	MyInStack b = a; //복사 생성
	b.push(30);

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

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

5-9

클래스 Accumulator는 add() 함수를 통해 계속 값을 누적하는 클래스로서, 다음과 같이 선언된다.

Accumulator 클래스를 구현하라.

class Accumulator{
    int value;
public:
    Accumulator(int value); // 매개 변수 value로 멤버 value를 초기화한다. 
    Accumulator& add(int n); // value에 n을 더해 값을 누적한다. 
    int get(); // 누적된 값 value를 리턴한다. 
};

Accumulator는 다음과 같이 main() 함수에 의해 활용된다.

int main() {
    Accumulator acc(10);
    acc.add(5).add(6).add(7); // acc의 value 멤버가 28이 된다. 
    cout << acc.get(); // 28 출력 
}
28
#include<iostream>

using namespace std;

class Accumulator
{
	int value;
public:
	Accumulator(int value) { this->value = value; };
	Accumulator& add(int n);
	int get() { return value; };
};

Accumulator& Accumulator::add(int n)
{
	value += n;

	return *this;
}

int main()
{
	Accumulator acc(10);
	acc.add(5).add(6).add(7);

	cout << acc.get();
}

풀지 못한 이유

return 값이 *this 으로 사용 가능하다는 것을 알았다.

5-10

참조를 리턴하는 코드를 작성해보자. 다음 코드와 실행 결과를 참고하여 append() 함수를 작성하고 전체 프로그램을 완성하라.

append()는 Buffer 객체에 문자열을 추가하고 Buffer 객체에 대한 참조를 반환하는 함수이다.

class Buffer{
    string text;
public:
    Buffer(string text) { this->text = text; }
    void add(string next) { text += next; } // text에 next 문자열 덧붙이기 
    void print() { cout << text << endl; }
};
 
int main() {
    Buffer buf("Hello");
    Buffer& temp = append(buf, "Guys"); // buf의 문자열에 "Guys" 덧붙임 
    temp.print(); // "HelloGuys" 출력
    buf.print(); // "HelloGuys" 출력
}
#include<iostream>
#include<string>

using namespace std;

class Buffer
{
	string text;
public:
	Buffer(string text) { this->text = text; };
	void add(string next) { text += next; }
	void print() { cout << text << endl; }
};

Buffer& append(Buffer& buf, string text) 
//버퍼클래스 객체의 참조를 리턴하는 함수이기 때문에 자료형을 Buffer형으로 해줘야함
{
	buf.add(text);

	return buf;
}

int main()
{
	Buffer buf("Hello");

	Buffer& temp = append(buf, "Guys");

	temp.print();
	buf.print();
}

풀지 못한 이유

5-9의 add()의 경우 Accumulator class의 reference return이다. 하지만 5-10의 append()는 Buffer class 객체의 참조를 리턴하는 함수이기 때문에 유의하여 봐야한다.

profile
CK23 Game programmer

0개의 댓글