제목: C++ 함수, 코드의 재활용과 효율성!
서론
C++의 변수와 연산자 그리고 flow control에 대해 배웠다면, 이제 코드의 재사용성과 효율성을 높이는 도구인 '함수'에 대해 알아보자. 함수는 특정 작업을 수행하는 코드 블록을 독립적으로 정의하고, 필요할 때마다 호출하여 사용할 수 있도록 한다. 이를 통해 코드의 중복을 줄이고, 프로그램의 구조를 개선하여 유지보수를 용이하게 만들 수 있다.
함수 정의와 장점
함수는 특정 작업을 수행하는 일련의 문장들을 하나의 이름으로 묶어 재사용 가능한 코드 블록으로 만드는 것이다. 함수를 사용하면 다음과 같은 장점을 얻을 수 있다.
- 가독성 향상: 복잡한 코드를 함수로 분리하여 각 함수의 역할을 명확하게 드러냄으로써 코드의 가독성을 높일 수 있다. 예를 들어, 제곱근을 계산하는 알고리즘을 함수로 정의하면,
sqrt(5)
와 같이 간결하게 표현할 수 있다. - 유지보수성 향상: 함수 내부의 코드를 수정하면 해당 함수를 호출하는 모든 곳에 변경 사항이 자동으로 적용되므로, 코드의 유지보수가 용이해진다.
- 코드 재사용: 한 번 정의한 함수는 프로그램의 여러 곳에서 호출하여 사용할 수 있으므로, 코드의 중복을 줄이고 재사용성을 높일 수 있다.
- 협업: 함수를 통해 모듈화된 코드를 작성하면, 다른 개발자들이 해당 함수를 쉽게 이해하고 사용할 수 있도록 돕는다.
함수는 다음과 같이 정의한다.
반환_타입 함수_이름(매개변수_목록) {
// 함수 몸체
[return 반환_값;] // 선택 사항
}
예를 들어, 원의 넓이를 계산하는 함수는 다음과 같이 정의할 수 있다.
double calArea(int radius) {
double dVal = radius * radius * 3.14;
return dVal;
}
함수 선언과 main()
함수
함수를 사용하기 전에 컴파일러에게 함수의 존재를 알려주는 것을 '함수 선언'이라고 한다. 함수 선언은 함수의 반환 타입, 이름, 매개변수 목록을 명시하며, 함수 몸체는 포함하지 않는다. (함수를 main() 뒤에 정의한 경우, 컴파일러가 함수의 존재를 모르기에 앞에서 알려주는 역할을 한다.)
반환_타입 함수_이름(매개변수_목록);
double calArea(int radius);
main()
함수는 프로그램 실행의 시작점이며, 프로그램이 시작될 때 운영체제에 의해 자동으로 호출된다. 따라서 모든 C++ 프로그램은 main()
함수를 반드시 포함해야 한다.
함수 호출 오버헤드와 Inline 함수
함수를 호출할 때마다 새로운 스택 프레임이 생성되어 임시 변수를 저장하고, 함수 호출 및 반환에 따른 추가적인 작업이 수행된다. 이러한 과정은 프로그램의 실행 속도를 저하시킬 수 있다. 이러한 함수 호출 오버헤드를 줄이기 위해 매크로 함수와 Inline 함수를 사용할 수 있다.
![]() |
Memory layout |
- 매크로 함수: 전처리기(preprocessor)에 의해 코드가 컴파일되기 전에 단순히 텍스트 치환을 수행한다. 함수 호출 오버헤드는 없지만, 디버깅이 어렵고 예상치 못한 부작용이 발생할 수 있다.
Macro function
- Inline 함수: 컴파일러가 함수 호출 코드를 함수 몸체 코드로 직접 대체하여 함수 호출 오버헤드를 줄인다. 하지만 프로그램의 크기가 커질 수 있으며, 모든 함수에 적용 가능한 것은 아니다.
Inline function
변수의 scope와 lifetime
변수는 선언된 위치에 따라 범위(scope)와 생존 시간(lifetime)이 결정된다.
- 지역 변수: 함수 내부에서 선언된 변수로, 함수가 호출될 때 생성되고 함수가 종료될 때 소멸된다. 함수 내부에서만 접근 가능하다.
- 전역 변수: 함수 외부에서 선언된 변수로, 프로그램 실행 시작 시 생성되고 프로그램 종료 시 소멸된다. 프로그램 전체에서 접근 가능하지만, 이름 충돌의 위험이 있고 코드의 가독성을 해칠 수 있다.
- 정적 변수:
static
키워드를 사용하여 선언된 변수로, 프로그램 실행 시작 시 생성되고 프로그램 종료 시 소멸된다. 선언된 블록 내에서만 접근 가능하지만, 함수 호출이 끝나도 값이 유지된다.
헤더 파일, 전처리기, 네임스페이스
- 헤더 파일: 함수 선언, 변수 선언, 매크로 정의 등을 포함하는 파일로,
.h
확장자를 갖는다. 여러 소스 파일에서 공통으로 사용되는 코드를 관리하는 데 유용하다.
- 전처리기: 컴파일러가 소스 코드를 컴파일하기 전에 특정 작업을 수행하는 프로그램이다. #이 들어간 (
#include
,#define
,#ifndef
,#endif
등) 지시자를 사용하여 헤더 파일 포함, 매크로 정의, 조건부 컴파일 등을 수행한다.
#ifndef MULTI_H
:MULTI_H
라는 매크로가 정의되어 있지 않은 경우에만 다음 코드 블록을 처리한다. 즉, 처음multi.h
파일이 포함될 때는MULTI_H
가 정의되어 있지 않으므로 코드 블록이 실행된다.
#define MULTI_H
:MULTI_H
매크로를 정의한다. (만약#ifndef
조건문에 의해 매크로가 정의되어있으면 해당 블록은 건너뛴다.)
int Multiply(int, int = 1);
:Multiply
함수의 선언이다. (마찬가지로 만약#ifndef
조건문에 의해 매크로가 정의되어있으면 해당 블록은 건너뛴다.)
#endif
:#ifndef
로 시작된 조건부 컴파일 블록의 끝.
- 네임스페이스: 이름 충돌을 방지하기 위해 변수, 함수, 클래스 등을 논리적으로 묶는 데 사용된다.
namespace 이름 { ... }
형태로 정의하며,이름::요소
형태로 접근하거나using
키워드를 사용하여 특정 네임스페이스를 직접 사용할 수 있다.
결론
함수는 C++ 프로그래밍에 있어 코드의 재사용성과 유지보수성을 높이는 데 중요한 역할을 한다. 함수를 효과적으로 활용하고/ 변수의 scope와 lifetime을 이해하며/ 헤더 파일, 전처리기, 네임스페이스를 적절히 사용한다면 견고하고 효율적인 C++ 프로그램을 작성할 수 있을 것이다.
다음 시간에는 또다른 C++의 핵심 개념인 Array와 pointer에 대해 자세히 알아보겠다.
추천글 :
[C++][OOP] Variables & Operators
(https://hyeonb.blogspot.com/2024/09/coop-variables-operators.html)
[C++][OOP] Flow Control - 조건문, 반복문
(https://hyeonb.blogspot.com/2024/09/coop-flow-control.html)