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

녹차·2024년 6월 21일
0

C++

목록 보기
7/11
post-thumbnail

Chapter6 문제 [7/9]

6-1

add() 함수를 호출하는 main() 함수는 다음과 같다.

int main() {
    int a[] = {1,2,3,4,5};
    int b[] = {6,7,8,9,10};
    int c = add(a, 5); // 배열 a의 정수를 모두 더한 값 리턴 
    int d = add(a, 5, b); // 배열 a와 b의 정수를 모두 더한 값 리턴 
    cout << c << endl; // 15 출력 
    cout << d << endl; // 55 출력 
}
[오답]
#include<iostream>

using namespace std;

int add(int a[], int b, int c[] = 0)
{
	int sum = 0;

	for (int i = 0; i < b; i++)
	{
		sum += a[i] + c[i];
	}

	return sum;  
}

int main()
{
	int a[] = { 1, 2, 3, 4, 5 };
	int b[] = { 6, 7, 8, 9, 10 };

	int c = add(a, 5); //15
	int d = add(a, 5, b); //55

	cout << "10";

	cout << c << endl;
	cout << d << endl;
}

해결하지 못한 이유

이와 같이 6-1 (2)을 풀려했으나 실행에는 문제가 없지만 segmentation fault로 인해 결과값이 출력되지 않았다. 결국 Monica에게 물어본 결과 원인은, int c[] = 0;에서 c 배열이 초기화되지 않았기 때문이었다. 이 경우 c[i]에 접근할 때segmentation fault가 발생할 수 있다. c 배열이 NULL인 경우 (add(a, 5))에 대한 처리가 없기 때문에 문제가 발생한 것이었다.

[정답]
#include<iostream>

using namespace std;

int add(int a[], int b, int c[] = nullptr)
{
	int sum = 0;


	for (int i = 0; i < b; i++)
	{
		if (c == nullptr)
		{
			sum += a[i];
		}
		else
		{
			sum += a[i] + c[i];
		}
	}

	return sum;  
}

int main()
{
	int a[] = { 1, 2, 3, 4, 5 };
	int b[] = { 6, 7, 8, 9, 10 };

	int c = add(a, 5); //15
	int d = add(a, 5, b); //55

	cout << c << endl;
	cout << d << endl;
}

6-2

Person 클래스의 객체를 생성하는 main() 함수는 다음과 같다.

class Person {
    int id;
    double weight;
    string name;
public:
    void show() { cout << id << ' ' << weight << ' ' << name << endl; }
};
 
int main() {
    Person grace, ashley(2, "Ashley"), helen(3, "Helen", 32.5);
    grace.show();
    ashley.show();
    helen.show();
}
1 20.5 Grace
2 20.5 Ashley
3 32.5 Helen 

(1) 생성자를 중복 작성하고 프로그램을 완성하라.
(2) 디폴트 매개 변수를 가진 하나의 생성자를 작성하고 프로그램을 완성하라.

#include<iostream>
#include<string>

using namespace std;

class Person 
{
    int id;
    double weight;
    string name;
public:
    Person(int id = 1, string name = "Grace", double weight = 20.5) {
        this->id = id;
        this->name = name;
        this->weight = weight;
    };
    void show() { cout << id << ' ' << weight << ' ' << name << endl; }
};

int main() {
    Person grace; 
    Person ashley(2, "Ashley"); 
    Person helen(3, "Helen", 32.5);
    
    grace.show();
    ashley.show();
    helen.show();
}

6-3

함수 big()을 호출하는 경우는 다음과 같다.

int main() {
    int x = big(3, 5); // 3과 5중 큰 값은 5는 최대값 100보다 작으므로, 5 리턴 
    int y = big(300, 60); // 300과 60 중 큰 값 300이 최대값 100보다 크므로, 100리턴 
    int z = big(30, 60, 50); // 30과 60 중 큰 값 60이 최대값 50보다 크므로, 50리턴 
    cout << x << ' ' << y << ' ' << z << endl;
}
5 100 50

(2) 디폴트 매개 변수를 가진 하나의 함수로 big()을 작성하고 프로그램을 완성하라.

#include<iostream>

using namespace std;

int big(int x, int y, int z = 0)
{
	int bigNum = 0;

	//x가 클 때
	if (x > y)
		bigNum = x;
	else
		bigNum = y;

	if (z == 0)
	{
		if (bigNum < 100)
			return bigNum;
		else
			return 100;
	}
	else
	{
		if (bigNum > z)
			return z;
		else
			return bigNum;
	}

}

int main()
{
	int x = big(3, 5);
	int y = big(300, 60);
	int z = big(30, 60, 50);

	cout << x << ' ' << y << ' ' << z << endl;
}

6-4

다음 클래스에 중복된 생성자를 디폴트 매개 변수를 가진 하나의 생성자로 작성하고 테스트 프로그램을 작성하라.

class MyVector{
    int *mem;
    int size;
public:
    MyVector();
    MyVector(int n, int val);
    ~MyVector() { delete [] mem; }
};
 
MyVector::MyVector() {
    mem = new int [100];
    size = 100;
    for(int i=0; i<size; i++) mem[i] = 0;
}
 
MyVector::MyVector(int n, int val) {
    mem = new int [n];
    size = n;
    for(int i=0; i<size; i++) mem[i] = val;
}
class MyVector {
    int* mem;
    int size;
public:
    MyVector(int n = 100, int val = 0)
    {
        mem = new int[n];
        size = n;
        for (int i = 0; i < size; i++)
            mem[i] = val;
    }
    ~MyVector() { delete[] mem; }
};

6-5

동일한 크기로 배열을 변환하는 다음 2개의 static 멤버 함수를 가진 ArrayUtility 클래스를 만들어라.

static void intToDouble(int source[], double dest[], int size);
                                                     // int[]을 double[]로 변환
static void doubleToInt(double source[], int dest[], int size);
                                                     // double[]을 int[]로 변환

ArrayUtility를 활용하는 main()은 다음과 같다.

int main() {
    int x[] = {1,2,3,4,5};
    double y[5];
    double z[] = {9.9,8.8,7.7,6.6,5.6};
    
    ArrayUtility::intToDouble(x, y, 5); // x[] -> y[]
    for(int i=0; i<5; i++) cout << y[i] << ' ';
    cout << endl;
    
    ArrayUtility::doubleToInt(z, x, 5); // z[] -> x[]
    for(int i=0; i<5; i++) cout << x[i] << ' ';
    cout << endl;
}
1 2 3 4 5
9 8 7 6 5
#include<iostream>

using namespace std;

class ArrayUtility
{
public:
    static void intToDouble(int source[], double dest[], int size)
    {
        for (int i = 0; i < size; i++)
        {
            dest[i] = source[i];
        }
    };
    static void doubleToInt(double source[], int dest[], int size)
    {
        for (int i = 0; i < size; i++)
        {
            dest[i] = source[i];
        }
    };

};

int main() {
    int x[] = { 1,2,3,4,5 };
    double y[5];
    double z[] = { 9.9,8.8,7.7,6.6,5.6 };

    ArrayUtility::intToDouble(x, y, 5); // x[] -> y[]
    for (int i = 0; i < 5; i++) cout << y[i] << ' ';
    cout << endl;

    ArrayUtility::doubleToInt(z, x, 5); // z[] -> x[]
    for (int i = 0; i < 5; i++) cout << x[i] << ' ';
    cout << endl;
}

6-7

다음과 같은 static 멤버를 가진 Random 클래스를 완성하라(Open Challenge 힌트 참고).

그리고 Random 클래스를 이용하여 다음과 같이 랜덤한 값을 출력하는 main() 함수도 작성하라.

main()에서 Random 클래스의 seed() 함수를 활용하라.

class Random{
public:
    static void seed() { srand((unsigned)time(0)); }
    static int nextInt(int min=0, int max=32767);
    static char nextAlphabet();
    static double nextDouble();
};
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;

class Random {
public:
    static void seed() { srand((unsigned)time(0)); }
    static int nextInt(int min = 0, int max = 32767) 
    {
        int Random = rand() % (max - min + 1) + min;

        return Random;
    }
    static char nextAlphabet()
    {
        char RandomChar = (char)(nextInt(1, 27) + 'a');

        return RandomChar;
    };
    static double nextDouble()
    {
        double c = 0;
        double max = 32767;
        c = rand() / max;
        return c;
    };
};

int main()
{
    Random::seed();

    cout << "1에서 100까지 랜덤한 정수 10개를 출력합니다" << endl;;
    
    for (int i = 0; i < 10; i++)
    {
        cout << Random::nextInt(1, 100) << ' ';
    }

    cout << endl;

    cout << "알파벳을 랜덤하게 10개를 출력합니다." << endl;

    for (int i = 0; i < 10; i++)
    {
        cout << Random::nextAlphabet() << ' ';
    }

    cout << endl;

    cout << "랜덤한 실수를 10개 출력합니다." << endl;

    for (int i = 0; i < 10; i++)
    {
        cout << Random::nextDouble() << ' ';
    }
}

왜 풀지 못했을까?

nextDouble() 함수를 생각하는 과정에서 정수로 밖에 출력되지 않아 솔루션을 보고 이해하였다.
랜덤 범위 지정으로만 사용해서 응용 능력이 많이 부족해 응용 능력을 키울 필요성을 느꼈다.

다른 사람이 푼 과정을 보니 nextAlphabet() 함수를 대소문자 또한 랜덤 구현하였지만 나는 간단하게 구현하고 끝냈다.

profile
CK23 Game programmer

0개의 댓글