I'm FanJae.

[C++ 기본 연습 문제] Chapter 02. 연습문제 정답 본문

C++/Basic Practice

[C++ 기본 연습 문제] Chapter 02. 연습문제 정답

FanJae 2024. 9. 1. 21:31
열혈 C++ 프로그래밍(윤성우 저)의 연습문제를 다뤘습니다.개인의 연습을 위해 다룬 것이며, 예제에 실제 공개된 코드는 첨부하지 않았습니다. 

1. Chapter 02. C언어 기반의 C++ 2

1-1. 참조자 기반의 Call-by-reference 구현

① 참조자를 이용해서 다음 요구사항에 부합하는 함수를 각각 정의하여라.

아래 각 함수를 호출하여 그 결과를 확인하는 main 함수 까지 작성하여라.

 

- 인자로 전달된 int형 변수의 값을 1씩 증가시키는 함수

- 인자로 전달된 int형 변수의 부호를 바꾸는 함수

#include <iostream>
void func1(int &n)
{
	n++;
}
void func2(int& n)
{
	n *= -1;
}
int main()
{
	int n = 3;
	func1(n);
	std::cout << n << std::endl;

	func2(n);
	std::cout << n << std::endl;
}

 

② 앞서 소개한 예제 RefSwap.cpp의 SwapByRef2 함수를 다음의 형태로 호출하면 컴파일 에러가 발생한다. 컴파일 에러가 발생하는 이유가 무엇인지 설명해보자.

SwapByRef2(23, 45);

- 참조자는 상수 리터럴 값을 직접 참조할 수 없다. 참조에 들어가는 값은 반드시 수정이 가능한 상태여야 한다. 만약 이들을 담으려면 상수 참조로 담는것은 가능하다.

 

③ 문제의 제시에 앞서 먼저 다음 코드를 보자.

int main(void)
{
    int num1 = 5;
    int *ptr1 = &num1;
    int num2 = 10;
    int *ptr2 = &num2;
    ...
}

- 위의 코드를 보면 ptr1과 ptr2가 각각 num1과 num2를 가리키고 있다.

- 이때 ptr1과 ptr2를 대상으로 아래와 같이 함수를 호출한다고 생각해보자.

SwapPointer(ptr1, ptr2);

- ptr1과 ptr2가 가리키는 대상이 서로 바뀌도록 SwapPointer 함수를 정의해 보자.

 

#include <iostream>
void SwapPointer(int*& ptr1, int*& ptr2)
{
    int* temp = ptr1;
    ptr1 = ptr2;
    ptr2 = temp;
}

int main(void)
{
    int num1 = 5;
    int* ptr1 = &num1;
    int num2 = 10;
    int* ptr2 = &num2;

    SwapPointer(ptr1, ptr2);
    std::cout << *ptr1 << " " << *ptr2 << std::endl;
}

- int*&는 포인터가 아닌 참조자인 것에 유의하라.

 

1-2. const 포인터와 const 참조자

① const 포인터에 대한 복습을 겸할 수 있는 문제이다. 다음의 상수 선언을 보자.

const int num=12;

- 포인터 변수를 선언해서 위 변수를 가리키게 해보자. 그리고 이 포인터 변수를 참조하는 참조자를 하나 선언하자. 마지막으로 이렇게 선언된 포인터 변수와 참조자를 이용해서 num에 저장된 값을 출력하는 예제를 완성해보자.

#include <iostream>
int main(void)
{
	const int num = 15;
	const int* ptr = &num;
	const int* (&ref) = ptr; // 포인터를 참조하는 참조자 
    // int*& ref; 와 동일

	std::cout << *ptr << std::endl;
	std::cout << ref << std::endl;
}

 

1-3. 구조체에 대한 new & delete 연산 [ 정답 참고 비추천]

① 구조체에 대한 복습을 겸할 수 있는 문제를 제시하겠다. 2차원 평면상에서의 좌표를 표현할 수 있는 구조체를 다음과 같이 정의하였다.

typedef struct __Point
{
   int xpos;
   int ypos;
} Point;

- 위의 구조체를 기반으로 두 점의 합을 계산하는 함수를 다음의 형태로 정의한다.

- 덧셈결과는 함수의 반환을 통해서 얻게 한다.

Point& PntAdder(const Point &p1, const Point &p2);

- 임의의 두 점을 선언하여, 위 함수를 이용한 덧셈연산을 진행하는 main 함수를 정의해보자.

- 단, 구조체 Point 관련 변수의 선언은 무조건 new 연산자를 이용해서 진행해야 한다.

- 할당된 메모리 공간의 소멸도 철저해야 한다. 

 

참고로 이 문제의 해결을 위해서는 다음 두 질문에 답을 할 수 있어야 한다.

1) 동적할당 한 변수를 함수의 참조형 매개변수의 인자로 어떻게 전달해야 하는가?

2) 함수 내에 선언된 변수를 참조형으로 반환하려면 해당 변수는 어떻게 선언 해야 하는가?

 

1) 동적할당 한 변수를 함수의 참조형 매개변수의 인자로 어떻게 전달해야 하는가?

PntAdder(*p1, *p2);

이와 같이 전달한다.

 

2) 함수 내에 선언된 변수를 참조형으로 반환하려면 해당 변수는 어떻게 선언 해야 하는가?

Point& p3 = PntAdder(*p1, *p2); // 참조형 변수로 리턴받는다.
#include <iostream>

typedef struct __Point
{
	int xpos;
	int ypos;
} Point;

Point& PntAdder(const Point& p1, const Point& p2)
{
	Point *pptr = new Point;

	pptr->xpos = p1.xpos + p2.xpos;
	pptr->ypos = p1.ypos + p2.ypos;

	return *pptr;
}


int main(void)
{
	Point *p1 = new Point;
	Point *p2 = new Point;
	

	p1->xpos = 5;
	p1->ypos = 10;

	p2->xpos = 10;
	p2->ypos = 15;

	Point& p3 = PntAdder(*p1, *p2);
	std::cout << p3.xpos << " " << p3.ypos << std::endl;

	delete p1;
	delete p2;
	delete &p3;
}

- 사실 이 예제의 경우 참고하지 않는 것을 추천한다.

- 참조자를 반환하고 있어서, 참조자로 받아왔고, 이를 delete 하고 있다.

- 실제로 동적 할당된 메모리가 반환 될 것을 기대하겠지만, 이는 그렇지 않다.

 

1-4. C++의 표준함수 호출

① 다음 표준 함수를 호출하는 예제를 만들되, C++ 헤더를 선언해서 만들어보자. 그리고, 예제의 내용은 상관이 없지만, 아래의 함수들을 최소 1회 이상 호출해야 한다. 참고로 다음 함수들은 C언어의 경우 <string.h>에 선언되어 있다.

#include <cstring>
#include <iostream>
int main(void)
{
	char str[100] = "FanJae";
	char str2[100] = "FF";
	char temp_str[100];

	std::cout << "strlen : " << strlen(str) << std::endl;
	std::cout << "strcat : " << strcat(str, str2) << std::endl;
	std::cout << "strcpy : " << strcpy(temp_str, str) << std::endl;
	std::cout << "strcmp : " << strcmp(temp_str, str) << std::endl;
}

② 다음 세 함수를 이용해서 0이상 100미만의 난수를 총 5개 생성하는 예제를 만들되, C++의 헤더를 선언해서 작성해보자. 참고로 C언어의 경우 time 함수 <time.h>에 선언되어 있고, rand와 srand 함수는 <stdlib.h>에 선언되어 있다.

#include <iostream>
#include <cstdlib>
#include <ctime>

int main(void)
{
	int n;
	srand(time(NULL));

	for (int i = 0; i < 5; i++)
	{
		std::cout << "i : " << i + 1 << " Value : " << rand() % 100 << std::endl;
	}
}

 

Comments