관리자 글쓰기
C++ 함수2
2022. 3. 21. 17:19 - pingu-s

반환값

 

함수에서는 인수와 역으로, 함수의 호출 장소에 함수 본체로부터 특정의 정보를 반환하는 구조도 작성할 수 있다.

함수로부터 반환되는 정보를 반환값(return value)이라고 한다. 여러 개를 지정할 수 있는 인수와 달리 반환값은 보통 1개만 호출 장소로 값을 반환할 수 있다.

반환값을 반환하려면 우선 반환값의 [형]을 함수의 정의 내에 나타낸다(①). 그리고 함수의 블록 내에 return이라는 문장을 사용해서 실제로 값을 반환하는 처리를 한다(②).

 

[구문 : 함수의 정의]

반환값의 형 함수명(인수 리스트) //① 반환값의 형을 지정한다.
{
	문장;
	...

	return 식; //② 식의 값을 호출한 곳으로 반환한다.
}

여기서는 블록의 마지막에 return문을 기술하지만, 이 문장은 블록의 중간 정도에 기술할 수도 있다. 단, 함수가 처리되었을 때, 블록의 마지막까지 수행하지 않아도 return문이 처리된 경우에 그 함수의 처리를 종료한다.

 

그러면 반환값을 가지는 함수를 살펴보도록 한다. 다음의 코드가 반환값을 가지는 함수이다.

//buy 함수의 정의
int buy(int x, int y)
{
	int z;

	cout << x << "만원과 " << y << "만원의 차를 구입하였다.\n";

	z = x + y;

	return z;
}

이 함수에서는 받은 2개 인수 x와 y를 더하는 처리를 하고 있다. 덧셈의 결과는 함수 내에서 선언한 변수 z에 저장한다.

그리고 return문에서 z의 값을 반환값으로 반환한다. z는 int형이므로 반환값의 형에는 int형으로 지정하고 있다. 실제로 코드를 기술해서 이 함수를 사용해 보도록 한다.

 

예제) 반환값

앞선 예제 buy() 함수에서 반환값을 가지는 함수를 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//buy 함수의 정의
int buy(int x, int y) //반환값을 가지는 함수를 정의한다.
{
	int z;

	cout << x << "만원과 " << y << "만원의 차를 구입하였다.\n";

	z = x + y;

	return z; //반환값 z를 반환한다.
}

//buy 함수의 이용
int main()
{
	int num1, num2, sum;

	cout << "얼마의 차를 구입하는가? ";
	cin >> num1;

	cout << "얼마의 차를 구입하는가? ";
	cin >> num2;

	sum = buy(num1, num2); //buy() 함수를 호출하고, 그 반환값을 변수 sum에 대입한다.

	cout << "합계 " << sum << "만원이다.\n"; //반환값을 출력한다.

	return 0;
}

여기서는 함수 내에 계산된 결과의 반환값을 호출 장소의 sum이란 변수에 저장하도록 한다. 반환값을 이용하려면 함수의 호출문에서 대입 연산자를 사용해서 대입하도록 한다.

//buy 함수의 호출
...
sum = buy(num1, num2);

호출 장소에서는 이 변수 sum의 내용을 출력한다. 이와 같이 함수의 반환값을 변수에 대입하여, 호출 장소에 이용할 수가 있다.

또한 반환값을 반드시 변수에 대입하여 이용하지 않아도 상관없다. 변수를 이용하지 않을 때는

buy(num1, num2);

로만 기술한다.

 

반환값이 없는 함수

 

인수가 없는 함수를 정의할 수 있었던 것처럼 반환값이 없는 함수도 정의할 수 있다. 예를 들면, 이전에서 정의한 buy() 함수는 반환값을 가지지 않는 함수이다.

//buy 함수의 정의
void buy() //반환값을 가지지 않는 경우는 void형으로 한다.
{
	cout << "차를 구입하였다.\n";
}

함수가 반환값을 가지지 않는 것을 나타내기 위해서는 반환값의 형으로 void형을 지정한다. 반환값이 없는 함수가 호출되어 처리된 경우에는 블록의 마지막의 }까지 수행하든가, 다음과 같이 아무것도 붙이지 않은 return문에 의해 함수가 종료하는 것으로 된다.

 

[구문 : return문]

return;

 

상기의 buy() 함수를 return문을 사용해서 기술해 보았다. 단, 이와 같은 단순한 함수에서는 return문을 기술하거나 하지 않아도 똑같다.

//buy 함수의 정의
void buy()
{
	cout << "차를 구입하였다.\n";
    
    return; //호출한 장소의 처리로 돌아간다.
}

 

함수의 이용

 

에제) 합계 구하기

키보드로부터 입력한 두 수의 합계를 함수로 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//sum 함수의 정의
int sum(int x, int y) //2개의 수를 받는 함수를 정의한다.
{
	return x + y; //(x + y)의 합계값을 반환하는 처리를 한다.
}

int main()
{
	int num1, num2, ans;
	
	cout << "1번째의 정수를 입력하세요=> ";
	cin >> num1;

	cout << "2번째의 정수를 입력하세요=> ";
	cin >> num2;

	ans = sum(num1, num2); //함수를 호출한다.

	cout << "합계는 " << ans << "입니다.\n"; //반환값을 출력한다.

	return 0;
}

여기서는 2개의 수치의 합계를 구하는 sum() 함수를 정의하였다. 이 함수의 처리는 앞에서 설명한 반환값을 가지는 buy() 함수와 실제로는 같다. buy() 함수에서는 알기 쉽도록 합계를 일단 변수에 저장하고 나서 그 값을 반환하도록 하였지만, sum()에서는 합계를 구하는 식을 사용해서 그대로 값을 반환한다. 보다 간단하게 코드를 기술하는 것이다.

return x + y; //합계를 반환값으로 반환한다.

 

최댓값을 구하는 함수

 

예제) 최댓값 구하기

키보드로부터 입력한 두 수에서 최댓값 구하기를 함수로 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//max 함수의 정의
int max(int x, int y) //2개의 인수를 받는 함수를 정의한다.
{
	if (x > y)
		return x; //[if (x > y)]의 조건이 참이면 x값을 반환한다.
	else
		return y; //[if (x > y)]의 조건이 거짓이면 y값을 반환한다.
}

int main()
{
	int num1, num2, ans;

	cout << "1번째의 정수를 입력하세요=> ";
	cin >> num1;

	cout << "2번째의 정수를 입력하세요=> ";
	cin >> num2;

	ans = max(num1, num2); //함수를 호출한다.

	cout << "최댓값은 " << ans << "입니다.\n"; //반환값을 출력한다.

	return 0;
}

지금은 2개의 수 중에 큰 쪽의 값을 반환하는 max() 함수를 정의하였다. 이 함수는 변수 x 또는 y 중에서 큰 쪽의 값을 호출한 장소로 반환한다. 두 개의 변수중 어느 쪽의 return문이 처리되면 그 장소에서 함수의 처리가 종료되고, 호출한 장소의 처리로 되돌아가는 것이다.

 

인라인 함수의 구조

 

그런데 함수를 사용한 코드에서는 함수를 사용하지 않는 경우에 비해 처리를 실행하는데 시간이 더 걸리는 경우가 있다. 처리를 함수로 종합하면 인수와 반환값을 주고받을 때, 시간이 걸리는 것이다. 여러 번 호출되는 작은 함수인 경우에는 이 시간을 무시할 수 없는 경우도 있다.

그와 같은 때는 인라인 함수(inline function)를 이용하면 편리하다. 인라인 함수란 다음과 같은 형식을 한 함수이다.

 

[구문 : 인라인 함수의 정의]

inline 반환값의 형 함수명(인수 리스트) { ... }

인라인 함수는 함수의 첫 부분에 inline을 붙인 함수이다.

실제로 인라인 함수를 사용한 코드를 입력해 보는 것으로 한다.

 

예제) 최댓값 구하기(인라인 함수)

키보드로부터 입력한 두 수에서 최댓값을 구하는 것을 인라인 함수로 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//max 함수의 정의
inline int max(int x, int y) //inline 함수를 정의한다.
{
	if (x > y)
		return x;
	else
		return y;
}

int main()
{
	int num1, num2, ans;

	cout << "1번째의 정수를 입력하세요=> ";
	cin >> num1;

	cout << "2번째의 정수를 입력하세요=> ";
	cin >> num2;

	ans = max(num1, num2); //인라인 함수를 호출한 부분에 최댓값을 구하는 코드가 채워진다.

	cout << "최댓값은 " << ans << "입니다.\n";

	return 0;
}

이 실행 결과는 위 예제의 max() 함수를 사용한 코드와 같다. 단, 이들의 경우는 인라인 함수를 호출한 장소에 최댓값을 구하는 코드가 컴파일러에 의해 채워지는 것으로 된다. 인라인 함수의 처리는 호출 부분에 채워지기 때문에 프로그램의 처리 속도가 향상될 수 있다.

단, 컴파일러는 긴 처리에 관해서는 인라인 함수로 처리하지 않는 경우도 있다. 컴파일러는 짧은 처리만을 인라인 함수로 채워 넣는 구조로 되어 있다.

 

함수의 선언

 

지금까지 정의한 함수는 그 함수를 호출하는 코드의 [앞부분]에 기술해왔다. 그러면 만약 함수의 정의를 호출보다 뒤에 기술하면 어떻게 되는가? 즉, main() 함수의 뒤에 기술하면 어떻게 되는가?

사실은 이와 같은 코드를 작성하면 함수가 정의되어 있지 않다는 내용의 오류가 표시되고 코드를 컴파일할 수 없다.

 

함수를 정의하는 장소

 

C++에서는 함수의 호출을 먼저 기술하는 경우에 함수의 이름과 인수의 수를 컴파일러에게 알려주는 작업이 필요하다. 이것을 함수 프로토타입 선언(함수 선언 : function declaration)이라 부른다. 즉, 함수의 호출을 함수의 정의보다도 앞에 기술할 경우에는 함수 프로토타입 선언이 필요하다.

함수 프로토타입 선언은 함수를 호출하기 전에 호출 함수의 이름, 반환값의 형 및 인수를 다음과 같이 기술한다.

 

[구문 : 함수 프로토타입 선언]

반환값의 형 함수명(인수 리스트);

함수 프로토타입 선언을 사용한 코드를 살펴보도록 한다. 함수 본체는 main() 함수의 뒤에 정의하는 것으로 한다.

 

예제) 최댓값 구하기(프로토타입 선언)

위 예제에서 최댓값 구하기를 함수의 프로토타입 선언을 사용하여 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//max 함수의 선언
int max(int x, int y); //함수 프로토타입을 선언한다.

//max 함수의 호출
int main()
{
	int num1, num2, ans;

	cout << "1번째의 정수를 입력하세요=> ";
	cin >> num1;

	cout << "2번째의 정수를 입력하세요=> ";
	cin >> num2;

	ans = max(num1, num2); //함수를 호출한다.

	cout << "최댓값은 " << ans << "입니다.\n";

	return 0;
}

//max 함수의 정의
int max(int x, int y)
{
	if (x > y)
		return x;
	else
		return y;
}

위 예제에서는 max() 함수가 2개의 인수를 가지고, int형의 반환값을 반환하는 것을 함수 프로토타입 선언에서 나타내었다. 만약 뒤에 기술한 max() 함수의 반환값과 인수가 프로토타입 선언과 다른 경우는 컴파일할 때 오류가 나오도록 되어 있다.

 

함수 프로토타입 선언

 

디폴트 인수의 사용

 

함수 프로토타입 선언에서는 디폴트 인수(default argument)를 지정해 두는 것이 자주 수행된다. 디폴트 인수를 지정해 두면 함수를 호출할 때 실인수를 생략할 수 있다. 실인수를 생략하면 지정해둔 디폴트 값이 함수에 전달된다.

디폴트 인수를 지정한 함수 프로토타입 선언은 다음과 같다.

 

[구문 : 디폴트 인수의 지정]

반환값의 형명 함수명(형명 가인수명 = 디폴트 값, ...);

 

디폴트 인수는 함수의 선언 또는 정의에 1회만 지정한다. 즉, 함수 프로토타입 선언에서 디폴트 인수를 지정한 경우는 함수 본체의 정의에서는 디폴트 인수를 지정하지 않는다.

 

다음의 함수 프로토타입 선언은 인수에 10이라는 디폴트 인수를 지정한 것이다.

void buy(int x = 10);

그러면 다음의 코드에서 디폴트 인수를 가지는 함수를 실제로 호출해 보도록 한다.

 

예제) 디폴트 인수의 사용

앞 예제에서 다룬 buy() 함수를 디폴트 인수를 가진 함수로 정의하는 코드를 작성해 보도록 한다.

#include <iostream>
using namespace std;

//buy 함수의 선언
int buy(int x = 10);

int main()
{
	cout << "1회째는 1000만원으로 구입한다.\n";
	buy(1000); //인수를 지정해서 buy 함수를 호출한다.

	cout << "2회째는 디폴트 금액으로 구입한다.\n";
	buy(); //인수를 지정하지 않고 buy 함수를 호출한다.

	return 0;
}

//buy 함수의 정의
int buy(int x)
{
	cout << x << "만원의 차를 구입하였다.\n";

	return 0;
}

이 코드에서는 2회의 buy함수를 호출하고 있다. 1회째의 호출에서는 인수로 1000을 넘기지만 2회째에는 인수를 넘기지 않는다. 이 때문에 2회째의 호출에서는 디폴트 값인 10이 사용된다. 디폴트 인수를 설정한 경우에는 실인수를 지정하지 않고 호출할 수 있다.

 

단, 인수가 여러 개인 경우에는 주의해야 한다. 디폴트 인수는 오른쪽부터 순서대로 설정해야 한다. 즉, 어떤 인수의 디폴트 값을 설정한 경우는 그 인수 이후에 있는 인수도 모두 디폴트 인수를 설정하지 않으면 안 된다.

예를 들면, 5개의 인수를 가지는 함수인 경우네는 func1() 함수와 같이 오른쪽부터 순서대로 디폴트 인수를 지정할 수 있다. 그러나 func2() 함수와 같이 2번째와 5번째의 인수에만 디폴트 값을 설정할 수는 없다.

//올바르다
void func1(int a, int b, int c, int d = 2, int e = 10)
						//오른쪽부터 순서대로 디폴트 인수를 설정할 수 있다.

//오류
void func2(int a, int b = 2, int c, int d, int e = 10)
						//이와 같은 디폴트 인수의 설정은 할 수 없다.

 

이 func1() 함수는 다음과 같이 호출할 수 있다.

func1(10, 5, 15); //①
func1(10, 5, 15, 20); //②
func1(10, 5, 15, 20, 30); //③

①은 디폴트 인수로 지정한 2개의 인수를 생략하고 호출한다. 즉, 인수 d는 2, e는 10으로 초기화된다.

②는 마지막 인수를 생략하고 호출한다. 즉, 마지막 인수 e가 10으로 초기화된다.

③은 모든 인수를 지정하고 호출한다.

 

 

출처: 박흥복서정희. 2015. C++ 프로그래밍 (초보자를 위한). 문운당

'개발 > C++' 카테고리의 다른 글

C++ 포인터  (0) 2022.03.27
C++ 함수3  (0) 2022.03.26
C++ 함수  (0) 2022.03.17
C++ 반복문2  (0) 2022.03.16
C++ 반복문  (0) 2022.03.11