안녕하세요. 여러분 어제에 이어 오늘도 글을 쓰게 되네요. 이번에 다룰 내용은 01-2부터 01-3까지의 문제와 그 속에 담겨져 있는 개념에 대해서 글을 써볼까 합니다. 그럼 시작해 볼게요.
Chapter1 01-2: 함수 오버로딩
먼저 문제를 풀기 위해서는 "함수 오버로딩"에 대하여 알아야 해요. C언어에서 동일한 이름을 가진 함수가 정의 될 수 있다 생각하나요? 한번 생각해 볼만한 질문이라고 생각해요.
C언어 에서는 불가능 해요. 왜냐하면 C언어 에서는 함수의 이름만 이용하여 호출 대상을 찾기 때문에요. 하지만 C++에서는 가능합니다.
예를 보시죠 :)
int func(int num)
{
num++;
return num;
}
int func(int a, int b)
{
return a+b;
}
위 두 함수는 C++에서는 다른 함수로 인식됩니다. 왜그럴까요? 위 두 함수의 정의에 있어서 무슨 차이점이 있을까요? 그것을 바로 "매개변수"입니다. 위의 함수는 매개변수가 1개 이지만 아래의 함수는 매개변수가 2개죠. C++의 compiler는 함수를 찾을 때 두가지 정보를 활용합니다. 첫번째는 '함수의 이름' 두번째는 '매개변수의 선언' 죠. 즉 함수의 이름이 같더라도 매개수의 자료형 또는 개수가 다르면 다른 함수라는 것입니다. 이제 소개할 문제가 바로 이 '오버로딩'의 개념을 연습하는 문제 입니다.
그럼 문제를 소개 할게요.
문제 1
다음 main 함수에서 필요로 하는 swap 함수를 오버로딩 해서 구현해보자.
int main(void)
{
int num1 = 20, num2 = 30;
swap(&num1, &num2);
std::cout << num1 << ' ' << num2 << std::endl;
char ch1 = 'A', ch2 = 'Z';
swap(&ch1, &ch2);
std::cout << ch1 << ' ' << ch2 << std::endl;
double dbl1 = 1.111, dbl2 = 5.555;
swap(&dbl1, &dbl2);
std::cout << dbl1 << ' ' << dbl2 << std::endl;
return 0;
}
[실행의 예]
30 20
Z A
5.555 1.111
만약 swap 이라는 함수가 없다면 위 프로그램의 출력은 각각 다음과 같이 나올거에요.
[실행의 예]
20 30
A Z
1.111 5.555
하지만 swap 함수에 의해 두 변수에 담겨져 있는 데이터 값이 서로 바뀌었죠. 그럼 swap 함수는 바로 이 두 데이터 값으 바꾸는 함수가 되어야 겠죠.
코드는 다음과 같아요.
#include<iostream>
//문제 01-2[함수 오버로딩]
//해당 변수에 담겨저 있는 값을 서로 바꿔주는 함수를 만들어야됨
//함수 이름이 같아도 매개변수의 선언이 다르므로 다른 함수로 인식이 됨
void swap(int *a, int *b)
{
int swi1 = *a;
*a = *b ;
*b = swi1;
}
void swap(char* c, char* d)
{
char swi2 = *c;
*c = *d;
*d = swi2;
}
void swap(double* e, double* f)
{
double swi3 = *e;
*e = *f;
*f = swi3;
}
int main(void)
{
int num1 = 20, num2 = 30;
swap(&num1, &num2);
std::cout << num1 << ' ' << num2 << std::endl;
char ch1 = 'A', ch2 = 'Z';
swap(&ch1, &ch2);
std::cout << ch1 << ' ' << ch2 << std::endl;
double dbl1 = 1.111, dbl2 = 5.555;
swap(&dbl1, &dbl2);
std::cout << dbl1 << ' ' << dbl2 << std::endl;
return 0;
}
각각의 변수의 주소값을 포인터 변수를 통해 받고 그 포인터가 가리키는 값을 함수내에 설정한 변수를 매개체 삼아 값을 바꿔주도록 해봤습니다. 위 3개의 함수의 이름 모두 'swap'이죠. 하지만 매개변수가 각기 다르기 때문에 위 3개 모두 다른 함수로 인식이 되죠. 이러한 함수 구현이 '함수 오버로딩'이에요.
Chapter1 01-3: 매개변수의 디폴트 값
'C++에서 디폴트 값'이란 '기본적으로 설정되어 있는 값'을 의미하는데요. 다음과 같은 함수가 가능해요.
int default(int num=10)
{
return num+1;
}
위 함수가 의미하는 바는 다음과 같아요. "정수를 인자로 받으면 num에 해당 인자의 값이 할당되고 그 이외에는 10이 전달된 걸로 간주하겠다". 참 이렇게 보면 여러모로 많은 부분이 C와 C++에서 차이가 있네요...
기본적인 설명은 여기까지하고 문제를 풀어보죠. 밑은 제가 따로 참고하고자 써놓은 겁니다.
- 매개변수에 디폴트 값이 설정되어 있으면, 선언된 매개변수의 수보다 적은 수의 인자전달이 가능하다. 그리고 전달되는 인자는 왼쪽에서부터 채워져 나가고, 부족분은 디폴트 값으로 채워진다.(함수에 전달되는 인자가 왼쪽에서 오른쪽으로 채워지기 때문에 매개변수의 디폴트 값은 오른쪽부터 채우는 형태로 정의해야한다).
- 디폴트 값은 함수의 선언 부분에만 표현하면 된다.
문제 1
예제 3에 정의된 함수 BoxVolume를 '매개변수의 디폴트 값 지정' 형태가 아닌, '함수의 오버로딩'의 형태로 재 구현해 보자.
먼저 예제의 코드는 다음과 같아요.
#include<iostream>
int BoxVolume(int length, int width = 1, int height = 1);
//함수에 전달되는 인자는 왼쪽에서 오른쪽으로 채워진다
int main(void)
{
std::cout << "[3, 3, 3] : " << BoxVolume(3, 3, 3) << std::endl;
std::cout << "[5, 5, D] : " << BoxVolume(5, 5) << std::endl;
std::cout << "[7, D, D] : " << BoxVolume(7) << std::endl;
}
int BoxVolume(int length, int width, int height) {
return length * width * height;
}
이를 함수의 오버로딩의 형태로 바꿔야 합니다. 첫번쨰 cout에서 Boxvolume은 인자를 3개를 받습니다. 내려갈수록 하나씩 적은 인자를 받죠. '함수 오버로딩'에서 "함수를 구분함에 있어 '매개변수가 다르면 다른 함수로 인식 된다"라는 부분은 기억 하실 겁니다. 따라서 매개변수의 수를 조절하여 구현하면 될거 같네요.
코드는 다음과 같아요.
#include<iostream>
int BoxVolume(int length1, int width1, int height1)
{
return length1 * width1 * height1;
}
int BoxVolume(int length2, int width2)
{
return length2 * width2 * 1;
}
int BoxVolume(int length3)
{
return length3 * 1 * 1;
}
//함수에 전달되는 인자는 왼쪽에서 오른쪽으로 채워진다
int main(void)
{
std::cout << "[3, 3, 3] : " << BoxVolume(3, 3, 3) << std::endl;
std::cout << "[5, 5, D] : " << BoxVolume(5, 5) << std::endl;
std::cout << "[7, D, D] : " << BoxVolume(7) << std::endl;
}
출력
[3, 3, 3] : 27
[5, 5, D] : 25
[7, D, D] : 7
간단한 문제이니 다음 문제로 넘어갈게요.
문제 2
다음과 같은 형태로의 함수 오버로딩은 문제가 있다. 어떠한 문제가 있는지 설명해보자.
int SimPleFunc(int a=10)
{
return a+1;
}
int SimpleFunc(void)
{
return 10;
}
일단 두 함수는 '오버로딩'이 가능한 함수 인것처럼 보여요. 하지만 오버로딩에 문제가 있다는 말은 어딘가 오류가 있다는 말이죠. 저는 여러 경우의 수를 생각해 봤어요. 10이 아닌 다른 정수를 넣었을 때, 10을 입력했을 때, 다른 실수나 문자, 문자열을 입려했을 때 그러다 문득 아무것도 입력하지 않았을 때 문제가 있다는 걸 깨달았어요. 아무것도 입력하지 않았을때 int SimpleFunc(void)가 실행되는 건 당연하죠. 하지만 int SimpleFunc(int a=10) 또한 실행이 됩니다. 바로 디폴트 값으로 10이 정해져 있기 때문이죠.
오늘 글은 여기서 마칩니다. 찾아와 주신 분들 감사드리고 혹여나 잘못된 부분이 있다면 따끔한 피드백 부탁드립니다. 그럼 좋은 하루 되세요 :)
책: 열혈 C++ 프로그래밍(저자: 윤성우)
'C++ 공부(윤성우 열혈 C++ 프로그래밍)' 카테고리의 다른 글
윤성우 열혈 C++ 프로그래밍[Chapter 1 01-1 문제] (0) | 2022.02.02 |
---|