본문 바로가기
KNOU/C++

[C++ 프로그래밍] 함수

by bottlesun 2022. 12. 1.
728x90

함수란?

  • 특정 작업을 수행하는 프로그램 문장들을 하나의 단위로 모아놓고 이름을 부여한것
  • return 명령을 이용하여 결과 값을 반환함
  • 함수 원형의 사용
  • → 함수가 호출 위치에 비해 뒤에 정의되어 있거나 다른 파일에 정의되어 있을 때는 함수 원형을 선언해야 한다.
  • 인수의 전달(값 호출과 참조 호출, const 인수, 디폴트 인수)
  • → const 인수를 사용하면 참조 호출을 하거나 포인터를 인수로 전달 할 경우 이에 해당되는 데이터를 보호할 수 있다.
  • 함수 다중 정의를 할 때는 각각의 함수가 인수의 자료형이나 개수로 구분 할 수 있어야 한다.
  • →함수 다중 정의란 동일한 이름을 갖는 함수를 여러 개 정의 하는 것이다. 다중 정의된 함수의 구분은 인수의 개수 및 자료형을 가지고 판단한다.

함수 정의 방법

**ReturnType** functionName(**fParameterList**) // 머리부
{ // 몸체 블록
Type1 localVar1; // 지역변수 선언
Type2 localVar2;
······
statement1; // 처리할 작업을 수행하는 문장
statement2;
······
return **returnExpression**; // 결괏값을 반환함
}
int Add (int i, int j) // type FCname(매개변수)
{
	int result = i + j
	return result; // 값의 반환
}
  • fParameterList : 인수를 받기 위한 형식 매개변수 선언
  • ReturnType : 함수의 결과로 반환하는 값의 자료형
  • returnExpression : 함수의 결과로 반환하는 값

함수 원형의 사용

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;
}
float FahrToC(float fahr); // 함수의 원형

int main()
{
float fTemp, cTemp;
cout << "화씨온도 : ";
cin >> fTemp;
cTemp = FahrToC(fTemp); // 함수 호출
cout << "---> 섭씨온도 : " << cTemp << endl;
return 0;
}
float FahrToC(float fahr)
{
return (fahr - 32) * 5 / 9;

순환 호출

  • 함수를 정의하는 몸체 블록 안에서 직접 또는 간접적으로 그 함수를 호출하도록 코드를 작성하는 것
// 순환호출의 예시) 팩토리얼 계산 함수의 순환 호출 구현
int factorial(int n)
{
if (n <= 1)
return 1;
else
return n * factorial(n – 1);
}

인수와 매개변수

인수

  • 함수 호출 문장에서 함수에 전달하는 식
  • -여러 개의 인수가 있을 경우 컴마(,) 로 구분하여 나열

실 매개변수

  • 함수 호출 문장에서 함수의 형식, 전달 할 인수
int main()
{
······
cTemp = FahrToC(fTemp);
······
}

형식 매개변수

  • 인수를 전달 받기 위해 함수에 선언된 매개변수
  • 함수 헤더에 매개변수의 자료형과 이름을 선언함
float FahrToC(float fahr)
{
return (fahr - 32) * 5 / 9;
}

인수의 전달 방식

값 호출

  • 실 매개변수의 값을 형식 매개변수에 복사하는 방식
float FahrToC(float fahr) { 
	return (fahr - 32) * 5 / 9;
}
int main() {
	float fTemp, cTemp;
	cout << "화씨온도 : ";
	cin >> fTemp;
	cTemp = FahrToC(fTemp); // 함수 호출 fTemp의 내용을 FahrToC(fahr)의 fahr로 값 복사
	cout << "---> 섭씨온도 : " << cTemp << endl;
	return 0;
}
  • 형식 매개변수의 값을 변경해도 실 매개변수는 변함 없음
float FahrToC(float fahr) { 
	fahr -= 32 // 형식 매개변수 수정
	return fahr * 5 / 9;
}
int main() {
	float fTemp, cTemp;
	cout << "화씨온도 : ";
	cin >> fTemp;
	cTemp = FahrToC(fTemp); // 원본은 변화가 없다
	cout << "---> 섭씨온도 : " << cTemp << endl;
	return 0;
}

참조호출

  • 실 매개변수의 참조를 형식 매개변수에 전달하는 방식

참조호출의 용도

  • 함수에서 처리한 결과를 매개변수를 통해 받아 오려는 경우
  • 많은 양의 데이터로 구성되는 인수를 함수에 효율적으로 전달 하는 경우
#include <iostream>
using namespace std;
void SwapValues(int& x, int& y); // 원형
int main()
{
int a, b;
cout << "두 수를 입력하시오 : ";
cin >> a >> b;
if (a < b) SwapValues(a, b); // 순서를 바꿔 a에 큰 값을 넣음
cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
return 0;
}

[해설]

int main()
{
······ // a = 20 , b = 10 을 입력
if (a < b) SwapValues(a, b); // 순서를 바꿔 a에 큰 값을 넣음
cout << "큰 수 = " << a << " 작은 수 = " << b << endl;
return 0;
}
······
void SwapValues(int& x, int& y) // x = a의 참조 (20) , y = b의 참조 (10) 받아옴.
{
int temp = x; // temp = 20
x = y; // x = b의 참조 값 10
y = temp; // y = temp의 값 20
}

// 출력 결과 x = 10 , y = 20

const 매개변수

함수 호출의 효율성을 위해 참조 호출을 하지만 실 매개변수의 값이 변경되는 것을 원하지 않는 경우에는 형식 매개변수에 const로 한정어 지정하여 실 매개변수를 보호

값 복사

데이터를 전체적으로 복사를 해오기 때문에, 전체 byte 를 가지고 온다.

struct SalesRec { // 구조체 함수 (62 byte)
char pID[10]; // 문자형 10 byte
int dYear, dMonth, dDate; // 정수형 (4*3) = 12byte
char deliverAddr[40]; // 문자형 40byte
};

void PrSalesRec(SalesRec srec)
// SalesRec를 srec 의 인수 매개변수로 복사 -> 데이터 복사(62 byte)

cout << "품목코드 : " << srec.pID << endl;
cout << "배달일자 : " << srec.dYear << "년 ";
cout << srec.dMonth << "월 ";
cout << srec.dDate << "일" << endl;
cout << "배달주소 : " << srec.deliverAddr << endl;
}

참조 복사

주소 위치를 참조하는 값인 4byte 만 복사 해올 수 있지만, 참조해 온 값을 수정 할 수 있게 되버린다.

void PrSalesRec(SalesRec &srec)
// 참조복사(주소값 위치)를 할 경우엔 4byte만 복사한다
{
cout << "품목코드 : " << srec.pID << endl;
cout << "배달일자 : " << srec.dYear << "년 ";
cout << srec.dMonth << "월 ";
cout << srec.dDate << "일" << endl;
cout << "배달주소 : " << srec.deliverAddr << endl;
}

매개변수 보호

const 한정어를 넣어주면 매개변수 내부 값을 변경 할 수 없게 막아준다.

void PrSalesRec(const SalesRec &srec)
// const 한정어가 붙어 있어 매개변수를 보호 해준다.
{
cout << "품목코드 : " << srec.pID << endl;
cout << "배달일자 : " << srec.dYear << "년 ";
cout << srec.dMonth << "월 ";
cout << srec.dDate << "일" << endl;
cout << "배달주소 : " << srec.deliverAddr << endl;
}

디폴트 인수

디폴트 값이 있는 인수의 경우 함수를 정의할때, 디폴트 값을 지정할 수 있다.

디폴트인수정의

double Round(double x, int d = 0); // 디폴트 인수 정의
// 
int main()
{
double a;
cout << "값 = ";  // 값 = 12.3456
cin >> a;
cout << "반올림 --> " << Round(a) << endl; // 디폴트 인수 생량 출력 값 12
cout << " " << Round(a, 1) << endl; // 12.3
cout << " " << Round(a, 2) << endl; // 12.35
cout << " " << Round(a, 3) << endl; // 12.346
return 0;
}

double Round(double x, int d) // point.B
{
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 f (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); —> 오류: y 값 생략 할 수 없다.


함수의 다중 정의

  • 동일한 이름을 갖는 함수를 여러 개 정의하는 것
  • 동일한 개념의 처리를 여러가지 데이터나 객체에 대해 각각의 대상에 맞는 처리를 해야 할 경우 사용
  • 다중 정의 된 함수의 구분 - 인수의 개수 및 자료형 ( 함수의 반환 자료형으로 구분 x)
······
struct TimeRec {
int hours;
int minutes;
};
// 시간을 더하는 함수
// 인수 TimeRec &t1 : 누계할 시간
// const TimeRec &t2 : 더할 시간
// 반환값 없음

void AddTime(TimeRec &t1, const TimeRec &t2)
{
t1.minutes += t2.minutes;
t1.hours += t2.hours + t1.minutes / 60;
t1.minutes %= 60;
}

······
void AddTime(TimeRec &t, int minutes)
{
t.minutes += minutes;
t.hours += t.minutes / 60;
t.minutes %= 60;
}
······

int main()
{
TimeRec tRec1 = { 2, 30 };
TimeRec tRec2 = { 1, 45 };
cout << tRec1.hours << "시간 " << tRec1.minutes << "분 + ";
cout << tRec2.hours << "시간 " << tRec2.minutes << "분 = ";
AddTime(tRec1, tRec2); // TimeRec 의 구조체 -> 1번 void 실행
cout << tRec1.hours << "시간 " << tRec1.minutes << "분" << endl;
cout << tRec1.hours << "시간 " << tRec1.minutes << "분 + ";
cout << "135분 = ";
AddTime(tRec1, 135); // TimeRec 의 구조체 , 정수형 값 -> 2번 void 실행
cout << tRec1.hours << "시간 " << tRec1.minutes << "분" << endl;
return 0;
}
728x90

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

[C++프로그래밍] 예외처리  (0) 2022.12.01
[C++ 프로그래밍]템플릿  (0) 2022.12.01
[C++ 프로그래밍]연산자 다중정의  (0) 2022.12.01
[C++ 프로그래밍] 클래스와 객체  (0) 2022.12.01

댓글