[c++] 함수

c와 c++ 차이
c언어

  • 반환형이 명시되어 있지 않으면 int형으로 가정 아래 코드는 컴파일러가 int foo()로 명시한다.
foo() {
    return 42;
}

c++

  • 반황형이 반드시 명시되어 있어야한다. 위 코드를 실행하면 컴파일 오류 발생 아래 코드처럼 없을시 void를 붙여야 한다.
void foo() {
    // do something
}

매개변수(parameter): 함수 정의 시 함수가 받아들이는 값을 나타낸다.

  • int add(int x, int y)에서 x와 y가 매개변수

인수(argument): 함수를 호출할 때 함수에 전달되는 값들을 말한다.

  • add(3, 5)에서 3과 5가 인수

중복 함수(Overloading Funtions)

  • 중복 함수는 C++에서 동일한 이름을 가진 함수를 여러 개 정의하는 것을 의미.
  • 이들 함수는 서로 다른 매개변수 리스트를 가져야 한다.
  • 이렇게 하면 같은 이름의 함수를 사용하여 다양한 매개변수 유형으로 작업할 수 있다.
#include <iostream>

// 정수형 매개변수를 가진 add 함수
int add(int a, int b) {
    return a + b;
}

// 실수형 매개변수를 가진 add 함수
double add(double a, double b) {
    return a + b;
}

int main() {
    std::cout << "Addition of integers: " << add(3, 5) << std::endl;
    std::cout << "Addition of doubles: " << add(3.5, 2.5) << std::endl;
    
    return 0;
}

디폴트 매개 변수(Default Parameter)

  • 원형에서만 정의한다.
  • 매개변수 리스트의 오른쪽에만 있어야 한다.
  • 한번 선언된 디폴트 값은 오버로딩 등을 통해 수정할 수 없다.
  • 함수 오버로딩 시 생각하고 주의하여야 한다.

인라인 함수(Inline Function)

함수 호출 오버헤드를 줄이기 위해 사용되는 C++의 기능

일반적인 함수는 호출시 호출지점을 기억해놓고 함수로 직접 이동한 후 실행한다.
-> 함수 호출, 함수 내용 실행, 다시 리턴의 동작

인라인 함수는 컴파일러에 의해 호출 지점에서 직접 삽입되어 실행. -> 곧바로 함수 내용이 삽입되어 실행됨

  • 간단하고 짧은 코드의 함수에 적합
  • 크다면 오히려 비효율성을 야기. 캐시효율성을 저하
  1. 호출 오버헤드 감소
  2. 컴파일러 최적화
  3. 가독성 유지
inline int add(int a, int b) {
    return a + b;
}

이를 실제로 인라인화 할지는 컴파일러 내부에서 결정된다.

함수 매크로와의 차이점

함수 매크로는 단순 치환으로 동작한다. 즉 버그를 유발할 가능성 존재.

#define SQUARE(x) (x*x)
SQUARE(y++); // y++*y++로 확장되어서 y의 값이 2번 증가된다. 

함수 매크로는 타입 검사를 할 수 없다. 즉 디버깅에 불리하다.

#define SQUARE(x) ( ( x ) * ( x ) )
SQUARE(2); // 정수
SQUARE(2.0); // 실수

그럼에도 사용하는 이유

  • 간단한 작업이나 특정한 목적을 위해서 대체할 수있는 함수 매크로를 사용함으로서 편의성과 유연성이 올라감.

하지만, 인라인 함수를 사용하는 것이 코드의 안전성과 가독성을 높이는데 효과적이다.

변수

지역 변수(Local Variable)

  • 어느 위치에서나 지역 변수의 선언이 가능
  • 매개변수 또한 지역변수의 일종

전역 변수(Global Variable)

  • 함수의 외부에 선언되는 변수

정적 지역 변수

  • 지역변수에 static을 붙여, 블록 외부에서도 자동으로 제거되지 않게 하는게 가능
  • 전역 변수와 같이 프로그램 실행과 함께 메모리에 적재
  • 종료시 메모리에서 삭제

순환(Recursive)

알고리즘이나 함수에서 자기 자신을 재호출하는 기법

  • 재귀 함수

예) 팩토리얼 alt text

unsigned long long factorial(unsigned int n) {
    // 재귀 호출: 1
    if (n <= 1) {
        return 1;
    }
    // 재귀 호출: n! = n * (n-1)!
    return n * factorial(n - 1);
}

재귀 함수의 구조

  • 순환 호출을 하는 부분
  • 순환 호출을 멈추는 부분 : 이 조건이 없으면 무한 루프에 빠지게 된다.