일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- virtual function
- vector capacity
- C++
- constructor
- std::cout
- new&delete
- virtual destructor
- return by reference
- c++ multi chatting room
- diamond inheritance
- suffix return type
- increment operator
- delete function
- placement new
- dynamic_cast
- member function pointer
- discord bot
- c++ basic practice
- std::ostream
- pointer to member data
- virtual function table
- operator overloading
- this call
- virtual inheritance
- vector size
- conversion constructor
- base from member
- std::endl
- 더 지니어스 양면포커
- std::vector
- Today
- Total
I'm FanJae.
[C++ 기본 연습 문제] Chapter 02. 연습문제 정답 본문
열혈 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 = #
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;
}
}
'C++ > Basic Practice' 카테고리의 다른 글
[C++ 기본 연습 문제] Chapter 07. 상속(Inheritance)의 이해 (1) | 2024.09.06 |
---|---|
[C++ 기본 연습 문제] Chapter 05. 복사 생성자(Copy Constructor) (0) | 2024.09.05 |
[C++ 기본 연습 문제] Chapter 04. 클래스의 완성 (0) | 2024.09.04 |
[C++ 기본 연습 문제] Chapter 03. 클래스의 기본 (1) | 2024.09.03 |
[C++ 기본 연습 문제] Chapter 01. 연습문제 정답 (0) | 2024.08.31 |