▣ 함수의 정의와 호출
● 함수(function)란?
▷ 필요한 작업을 수행하는 프로그램 문장들을 하나의 단위로 모아 놓고 이름을 부여한 것을 말한다
● 함수 정의 형식
ReturnType functionName(fParameterList) // 머리부
{ // 몸체 블록
Type localVar1; // 지역변수 선언
Type localVar2;
...
statement1; // 처리할 작업을 수행하는 문장
statement2;
...
return returnExpression; // 결과값을 반환
● return 명령?
▷ 함수를 마치고 함수를 호출한 곳으로 복귀하는 명령
▶ 함수 안의 어느 곳이든 복귀를 위해 사용 가능
▷ 반환값이 없는 함수의 ReturnType은 void로 선언
▶ main 함수에서는 return 명령을 만나지 않은 상태로 함수의 끝에 도달하면 'return 0;'를 실행한 것과 같다.
● 함수 호출 형식
▷ functionName ( aParameterList );
반환값 유무에 관계없이 사용 가능하다.
▶ varName = functionName ( aParameterList );
ReturnType이 void가 아닌 함수에 사용할 수 있다.
● 함수 사용 예시 - ConvFtoC.cpp
#include <iostream>
using namespace std;
//화씨온도를 섭씨온도로 변환하는 함수
//매개변수 float fahr : 화씨온도
//반환값 섭씨온도(float)
float FahrToC(float fahr)
{
return (fahr - 32) * 5 / 9;
}
int main()
{
float fTemp, cTemp;
cout << "화씨온도 : ";
cin >> fTemp;
cTemp = FahrToC(fTemp); //함수 호출
cout << "---> 섭씨온도 : " << cTemp << endl;
return 0;
}
● 함수 사용에 따른 장점 & 단점
▷ 장점
- 의미 있는 작업 단위로 모듈화 -> 간결하고 이해하기 쉬운 프로그램 생성 가능
- 반복 사용되는 코드의 중복 방지
- 잘 설계된 함수는 다른 응용에서 재사용 가능
▶ 단점
- 함수 호출과 복귀 과정에서 처리 시간이 추가된다
- 매우 효율적으로 동작해야 하는 함수면 inline 함수로 선언하는 게 좋다
▣ 인수와 매개변수
● 인수란?
▷ 함수 호출 문장에서 함수에 전달하는 값
▶ 매개변수를 통해 인수를 전달한다
● 매개변수
▷ 실 매개변수(actual parameter)
함수 호출 문장에서 함수의 형식 매개변수에 전달할 값
▶ 형식 매개변수(formal parameter)
인수를 전달받기 위해 함수에 선언된 매개변수로 함수 헤더에 매개변수의 자료형과 이름을 선언한다.
● 인수 전달 방식 - 값 호출 (call-by-value)
▷ 실 매개변수의 값을 형식 매개변수에 복사한다.
▶ 장점
실 매개변수와 형식 매개변수는 별개의 데이터라서 불필요한 부작용이 안 생긴다.
▷ 단점
구조체와 같이 많은 양의 데이터로 구성된 인수 전달하게 되면 데이터 복사량이 많아진다.
● 인수 전달 방식 - 참조 호출 (call-by-reference)
▷ 실 매개변수의 참조를 형식 매개변수에 복사한다.
▶ 함수에서 형식 매개변수의 값을 변경하는 것은 실 매개변수의 값을 변경하는 것과 같다.
▷ 형식 매개변수에 복사되는 데이터 양은 실 매개변수의 크기와 관계없이 일정하다. (구조체 인수에 효율적)
▶ 함수 호출의 효율성을 위해서 참조 호출 하지만 실 매개변수 값이 변경되길 원하지 않는 형식 매개변수에는 const 한정어를 지정하여 실 매개변수를 보호한다.
▷ 참조 호출 예시 (+const 한정어로 실 매개변수 보호)
struct SalesRec {
char pID[10];
int dYear, dMonth, dDate;
char deliverAddr[40];
};
void PrSalesRec(SalesRec srec) //64바이트 복사
void PrSalesRec(SalesRec &srec) //4바이트 복사 // 구조체의 값을 변경할 수 있다.
void PrSalesRec(const SalesRec &srec)
//4바이트 복사 // 함수 내에서 구조체의 값을 변경할 수 없다.
// 함수 내에서 구조체 값을 변경하는 문장이 있으면 컴파일 에러가 발생한다.
// 함수 내의 문장들은 모두 읽기 전용이라고 생각하면 된다.
{
cout << "품목코드 : " << srec.pID << endl;
cout << "배달일자 : " << srec.dYear << "년";
cout << srec.dMonth << "월";
cout << srec.dDate << "일" << endl;
cout << "배달주소 : " << srec.deliverAddr << endl;
구조체가 10 + 3*4 + 40 = 62바이트인데 데이터를 보통 4바이트씩 끊어서 전달하기 때문에 char pID에 12바이트를 할당해서 총 64바이트로 만들어서 메모리 효율을 높여준다. --> 정렬(Alignment)
● 디폴트(default) 인수
▷ 인수의 디폴트 값을 지정하는 방법
일반적으로 사용되는 디폴트 값이 있는 인수는 함수 정의할 때 그 값을 미리 지정할 수 있다.
▶ 예시 - 반올림 함수 Round.cpp
#include <iostream>
#include <cmath>
using namespace std;
//함수 선언만 먼저해서 main함수에서 사용할 수 있게 해주자.
double Round(double x, int d = 0); //d: 소수점 아래 자리수
int main()
{
double a;
cout << "값 = ";
cin >> a;
cout << "반올림 --> " << Round(a) << endl;
cout << " " << Round(a, 1) << endl;
cout << " " << Round(a, 2) << endl;
cout << " " << Round(a, 3) << endl;
return 0;
}
double Round(double x, int d)
// 인수에 int d = 0이라고 다시 지정해주면 안된다. 이미 위에서 했기 때문에
{
double a = x >= 0 ? 0.5 : -0.5;
double pow10 = pow(10, d);
return trunc(x * pow10 + a) / pow10;
}
▷ 디폴트 인수는 인수 중 끝에만 위치할 수 있다.
void f(int x, int y=10, int z=20); // OK!
void g(int x, int y=10, int z); // 오류!!!!!!!
f(5); // x = 5, y = 10, z = 20 전달
f(5,100); // x = 5, y = 100, z = 20 전달
f(5,100,200); // x = 5, y = 100, z = 200 전달
f(5, , 300); // 오류!!!! f(5, 10, 300); 으로 작성해야 함.
▣ 함수 다중정의
● 다중정의(overloading)란?
▷ 동일한 이름에 대하여 여러 가지 의미를 부여하는 것
● 함수 다중정의
▷ 동일한 이름을 갖는 함수를 여러 개 정의하는 것
▷ 동일한 개념의 처리를 여러 데이터나 객체에 대해 각각 대상에 맞게 처리해야 할 경우 사용
▷ 다중정의된 함수 구분은 인수의 개수와 자료형으로 한다.
▷ 함수의 반환 자료형으로 함수를 구분할 수 없다!!!!!!
● 모호한 함수 다중정의 경우들
▷
void f(int a){
cout << a * a;
}
void f(int a, int b){
cout << a * b;
}
void f(int a, int b){ //에러!!! 바로 위 함수와 반환 자료형만 다르기 때문에 구분될 수 없음!! 에러!!
cout << a * b;
}
int main(){
f(10);
f(10, 20);
}
▷
void g(int a)
{
cout << a * a;
}
void g(int a, int b = 100)
{
cout << a * b;
}
int main()
{
g(10, 20);
g(10); //에러!!!!!!!! 선택 기준이 모호하다.
...
}
▷
void h(int a)
{
cout << a * a;
}
void h(float a)
{
cout << a * b;
}
int main()
{
h(10);
h(10.0f);
h(10.0); // 에러!! 형 변환 대상이 모호하다
//10.0은 double 형이기 때문에 int나 float형으로
// 형변환이 일어나야 하는데 둘 중 무슨 함수를 써야하는 지 모호해서 오류남.
...
}
▣ inline 함수
● inline 함수 개념
▷ 함수 호출 절차를 따르지 않고 함수 호출 위치에 함수의 처리 문장이 삽입되게 번역하도록 선언된 함수
▷ 함수의 모듈화 장점을 살리면서 함수 호출에 따른 부수적인 처리 시간이 생략된다.
▷ 코드 최적화가 가능해진다.
▷ 아주 빈번히 호출되는 함수에 사용하면 좋다.
● inline 함수 주의사항
▷ inline 함수로 선언하더라도 반드시 inline으로 컴파일러가 번역하는 건 아니다
▷ 다음의 경우에는 inline 선언을 무시하고 일반 함수로 번역한다.
- 함수가 너무 큰 경우
- 순환 호출(recursive call)을 하는 경우
- 프로그램 내에서 그 함수에 대한 포인터를 사용하는 경우
▷ inline 함수의 예
inline void SwapValues(int &x, int &y)
{
int temp = x;
x = y;
y = temp;
}
int main()
{
int a, b;
cout << "두 수를 입력하세요 : ";
cin >> a >> b;
if(a < b) SwapValues(a, b); //순서를 바꿔서 a에 큰 값 대입
cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
return 0;
}
'Programming > C++' 카테고리의 다른 글
[C++] 헤더파일(.h) 내용 중복 include 방지 방법 (0) | 2020.08.27 |
---|---|
C++ 언어 기초 (6) - 클래스와 객체 (0) | 2020.08.27 |
C++ 언어 기초 (4) - 포인터, 동적 메모리 할당, 참조 (0) | 2020.08.26 |
C++ 언어 기초 (3) - 구조체와 클래스 (0) | 2020.08.26 |
C++ 언어 기초 (2) - 키워드,식별자,자료형,변수,연산자,형변환 (0) | 2020.08.26 |