재귀 함수
-> 함수 내부에서 자신을 다시 호출하는 함수.
-> 재귀 함수는 탈출 조건이 필수이다.

 

사용 예)

void Func(int _n)
{
	if (0 > _n)
		return;

	cout << "재귀 호출" << endl;

	Func(--_n);
}

void main()
{
	Func(3);
}

재귀 함수는 이름 뒤에 Recursive를 붙인다.

void ABCDRecursive();

 

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

C++ const와 포인터  (0) 2020.08.28
C++ 포인터  (0) 2020.08.26
C++ 함수 오버로딩, 디폴트 매개 변수  (0) 2020.08.25
C++ 함수의 선언부, 정의부  (0) 2020.08.25
C++ 지역 변수, 전역 변수, 정적 변수(static)  (0) 2020.08.24

함수 오버로딩

-> 함수를 재정의하는 문법.

-> 재정의 시 인자의 정보를 다르게 작성한다.

(함수의 이름을 동일하게 만들지만 인자 정보를 다르게 작성하는 방법)

-> 함수를 호출할 때 인자 정보에 따라 호출할 함수를 탐색하여 호출한다.

-> 단, 반환 타입에 따른 오버로딩은 존재하지 않는다.

 

함수의 오버로딩을 사용하지 않을 경우

int Add(int _a, int _b)
{
	return _a + _b;
}

float Add_float(float _a, float _b)
{
	return _a + _b;
}

double Add_double(double _a, double _b)
{
	return _a + _b;
}

void main()
{	
	cout << Add(10, 20) << endl;
	cout << Add_float(3.9f, 3.9f) << endl;
	cout << Add_double(3.9, 3.9) << endl;
}

 

함수의 오버로딩을 사용한 경우

int Add(int _a, int _b)
{
	cout << "int Add" << endl;
	return _a + _b;
}

float Add(float _a, float _b)
{
	cout << "float Add" << endl;
	return _a + _b;
}

double Add(double _a, double _b)
{
	cout << "double Add" << endl;
	return _a + _b;
}

void main()
{	
	cout << Add(10, 20) << endl;
	cout << Add(3.9f, 3.9f) << endl;
	cout << Add(3.9, 3.9) << endl;
}

하지만 이런 방식은 대부분 틀린 방식이라고 한다.

 

올바른 방식의 함수 오버로딩은 다음과 같다.

const File* GetFileIndex(const int index) const;
const File* GetFileName(const char* name) const;

 

const 반환을 위한 함수 오버로딩은 다음과 같다.

File* GetFileIndex(const int index);
const File* GetFileIndex(const int index) const;

const_cast의 직접적으로 사용하지 않는다.

대신 const인 개체를 수정 가능한 형태로 변환해서 반환하는 함수를 만든다.

 

main함수에서 Add의 값을 호출할 때 a, b, c, d의 값에서 a, b의 값만 호출하고 싶을 때,

다음과 같이 여러번 호출하게 되는 경우가 있다.

cout << Add(10, 20) << endl;
cout << Add(10, 20, 30) << endl;
cout << Add(10, 20, 30, 40) << endl;

이를 해결하기 위해 디폴트 매개 변수라는 것을 사용해보자.

 

디폴트 매개 변수

-> 매개변수의 값을 기본적으로 설정해 놓는 것.

int Add(int _a, int _b, int _c = 0, int _d = 0)

-> 함수 호출 시 넘겨주는 인자가 부족할 경우 기본적으로 설정한 값이 매칭된다.

다음과 같이 Add를 호출 할 경우 a + b + c + d = 30이 나오게 된다.

cout << Add(10, 20) << endl;

하지만, c의 자리에 30이란 정수 값을 넣어주게되면 0이 아닌 30이 들어가게되서

a + b + c + d = 60이 나오게 된다.

cout << Add(10, 20, 30) << endl;

-> 즉, 인자가 부족하지 않을 경우 넘겨주는 값으로 매칭된다.

 

디폴트 매개 변수 사용 시 주의사항

-> 우측 끝에서부터 순차적으로 채워나가야 한다.

 

가능

int Add(int _a, int _b, int _c = 0, int _d = 0) 

불가능

int Add(int _a, int _b = 0, int _c, int _d = 0)  

 

-> 선언부에서만 명시하고, 정의부에서는 명시할 수 없다.

 

가능

// 선언부
int Add(int _a, int _b, int _c = 0, int _d = 0) 

불가능

// 정의부
int Add(int _a, int _b, int _c = 0, int _d = 0)
{
	return _a + _b + _c + _d;
}

디폴트 매개 변수 대신 함수 오버로딩을 선호한다.

 

디폴트 매개 변수를 사용하는 경우, nullptr  false, 0 같이 비트 패턴이 0인 값을 사용한다.

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

C++ 포인터  (0) 2020.08.26
C++ 재귀 함수  (0) 2020.08.25
C++ 함수의 선언부, 정의부  (0) 2020.08.25
C++ 지역 변수, 전역 변수, 정적 변수(static)  (0) 2020.08.24
C++ 함수란?  (0) 2020.08.24

선언부와 정의부

-> 프로그램 실행 시 가장 먼저 호출되는 함수는 main함수이다.

-> 하지만, 여러가지 함수를 정의할 경우 main의 위치는 아래로 내려가게 된다.

(main함수는 프로그램 진입점을 나타내는 함수이기 때문에 상단에 배치하는 것이 좋다.)

-> 이를 해결하기 위해 선언부와 정의부를 나눠보자.

 

선언부

-> main함수에게 자신이 존재한다고 알리는 역할

-> 함수의 몸체가 없고 정보만 알려준다.

-> 반환타입이 무엇인지, 이름이 무엇인지, 매개 변수가 몇개이며 무엇인지

-> 반환 타입 + 함수이름 + 인자 정보만 알려준 후 세미콜론으로 마무리 짓는다.

 

정의부

-> 선언부에서 작성한 함수의 몸체를 구현한 부분

-> 정의부가 있어야만 정상적으로 프로그램을 실행할 수 있다.

-> 선언부에서 작성한 함수의 정의부가 없을 경우 정상적인 코드를 수행할 수 없다.

 

사용 예)

위의 코드를 보았을 때 Add 함수를 찾을 수 없어서 컴파일을 할 수 없다.

-> 이런 경우 Add함수를 main함수 위에다가 작성을 해야 하는데,

-> 그렇게 하게되면 main 함수는 Add함수의 아래로 이동하게 되고,

-> 함수가 만약 여러개가 존재 할 경우 main함수는 쭉 내려가게 되면서 한 눈에 보이지 않게 된다.

-> 이를 해결하기 위해서 선언부와 정의부가 있는 것이다.

 

다음과 같이 선언부와 정의부를 나누게 되면 main함수 위에다가 함수를 정의할 필요가 없게 된다.

 

 

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

C++ 재귀 함수  (0) 2020.08.25
C++ 함수 오버로딩, 디폴트 매개 변수  (0) 2020.08.25
C++ 지역 변수, 전역 변수, 정적 변수(static)  (0) 2020.08.24
C++ 함수란?  (0) 2020.08.24
C++ 난수(rand, srand)  (0) 2020.08.20

지역 변수와 전역 변수
-> 함수를 구현할 때 사용한 {} 를 기준으로
-> 내부에 선언되어 있으면 지역 변수
-> 외부에 선언되어 있으면 전역 변수

지역 변수와 전역 변수의 차이점
-> 메모리에 상주하는 기간의 차이
-> 변수에 접근할 수 있는 범위

#1. 지역 변수 
-> 메모리에 상주하는 기간

-> 함수가 시작되고, 종료될 때까지만 메모리에 상주한다.
-> 변수에 접근할 수 있는 범위
-> 해당 stack에 선언된 변수만 접근할 수 있다!

-> 지역 변수와 매개 변수는 함수가 시작 되었을 때 할당 시점에 들어가고, 종료 되었을 때 소멸 시점에 들어가게 되며,

-> 후입 선출형 구조(LIFO(Last-In, First-Out)로 되어있다.

 

다음과 같은 상황에 대해서 알아보자.


여기서 a와 b는 main함수의 stack 영역에 할당이 된다.

-> Result는 Add함수의 stack 영역에 할당이 된다.
-> 변수에 접근할 수 있는 범위로 인해
-> main함수에서는 Result의 존재를 모르며,
-> Add함수에서는 a와 b의 존재를 모르는 상황이다.

-> 컴퓨터는 하나의 Stack만 확인한다.

 

전역 변수

-> 어떠한 지역 내부에도 포함되어 있지 않다.

-> 어디서든 접근이 가능하다.

-> 프로그램이 시작되면 메모리에 등록, 종료되면 메모리에서 소멸된다.

-> Data 영역에 할당이 된다.

 

 

전역 변수와 지역 변수의 이름이 같을 경우
-> stack 영역을 우선적으로 확인
-> 변수가 있으면 지역 변수에 접근한다.
-> 변수가 없으면 전역 변수에 접근한다.

 

static 변수(정적 변수)

-> 자료형 앞에 static 키워드를 명시하면 정적 변수가 된다.

-> 정적 변수는 지역적인 특성과 전역적인 특성을 동시에 가진다.

-> 지역적인 특성으로는 해당 지역에서만 접근이 가능하다.

-> 전역적인 특성으로는 Data영역에 메모리가 등록되므로,

-> 프로그램 시작 시 메모리에 등록되고, 프로그램 종료 시 메모리에서 소멸한다.

 

다음과 같이 변수를 만들어서 확인 해보자.

 

지역 변수

int Func()
{
	int a = 0;

	++a;

	return a;
}

void main()
{
	for (int i = 0; i < 5; ++i)
	{
		cout << Func() << endl;
	}
}

정적 변수

int Func()
{
	static int a = 0;

	++a;

	return a;
}

void main()
{
	for (int i = 0; i < 5; ++i)
	{
		cout << Func() << endl;
	}
}

지역 변수와 정적 변수를 놓고 보았을 때 결과는 서로다르다.

지역 변수

정적 변수

결과가 다른 이유

-> static을 통해 정적 변수가 되면 초기화 구분은 프로그램 실행 시 최초 1회만 적용이 되기 때문이다.

 

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

C++ 함수 오버로딩, 디폴트 매개 변수  (0) 2020.08.25
C++ 함수의 선언부, 정의부  (0) 2020.08.25
C++ 함수란?  (0) 2020.08.24
C++ 난수(rand, srand)  (0) 2020.08.20
C++ 반복문(for, while, do ~ while), goto 문  (0) 2020.08.19

+ Recent posts