이번 Step에서 잡아야 할 것

  • 함수 = 기능 단위로 묶은 코드 (재사용/가독성/디버깅 단위)
  • 호출 흐름: 호출(점프) → 실행 → return(복귀)
  • 선언 vs 정의: “나중에 나온다”를 미리 알리는 것 vs 실제 구현
  • 스코프/스택: 지역 변수는 함수가 끝나면 사라진다

수학 vs 프로그래밍의 함수

구분수학프로그래밍
입력/출력필수 (x → y)있어도 되고 없어도 됨
동일 입력항상 동일 출력동일 출력 보장 없음 (예: rand)
용도연산·그래프코드 모음, 기능 재사용
  • 수학의 함수: 밀가루 넣으면 빵 나오는 기계처럼 입력→출력이 고정.
  • 프로그래밍의 함수: 코드를 모아놓는 공간이자, 입력·출력이 있는 기계 역할.
  • 코드(Text) 영역에 올라가며, 필요한 순간에 호출해서 사용합니다.

함수 문법 구조

리턴타입 함수이름(매개변수1, 매개변수2, ...) {
    // 구현부
}
요소설명
리턴타입반환값 자료형. 없으면 void (비어두는 게 아님)
함수이름변수와 동일한 명명 규칙. 프로젝트 스타일에 따라 PascalCase/camelCase 등 사용
매개변수입력 없으면 () 비움
구현부{} 안에 실제 동작 코드

함수 정의와 인자 사용

void TestFunction(int a, float b)
{
    cout << "Test " << a << endl;
}
  • void: 반환값이 없음을 의미.
  • (int a, float b): 매개변수. 변수 선언처럼 타입+이름이지만 세미콜론 없음.
  • 매개변수(parameter)는 함수 “안”에서 쓰는 이름이고, 인자(argument)는 호출할 때 넘기는 실제 값입니다.
  • 함수 호출 시 인자 개수/타입이 맞지 않으면 컴파일 에러가 납니다.
int hp = 100;
TestFunction(hp, 3.14f);  // hp 값(100)과 3.14f가 a, b로 복사되어 전달

함수 호출과 실행 흐름

함수 호출은 “점프”에 가깝습니다.

main()
  ├─ Foo() 호출 ──────┐
  │                   │ (Foo 실행)
  └─ Foo() return  ◄──┘  → main()의 '다음 줄'로 복귀
  • main(): 프로그램 시작점. 가장 먼저 실행되는 함수.
  • 호출 시: 해당 함수로 점프 → 구현부 실행 → return 시 호출 지점 다음 줄로 복귀.
  • 비유: 꿈을 꾸다가 깨어나면 이전 상태로 돌아가는 것. 함수 안에서 또 다른 함수 호출 가능 (인셉션처럼).
  • 디버깅으로 F11로 들어가면: 함수 진입 → 실행 완료 → 호출한 다음 줄로 복귀하는 것을 확인 가능.

return 문

  • 역할: 함수 즉시 종료 + (선택) 값 반환.
  • 리턴타입이 void가 아닌 경우: 반드시 return 값; 필요.
  • return 이후 코드: 실행되지 않음 (Unreachable code 경고 가능).
int Add(int a, int b) {
    return a + b;
}

int ClampHp(int hp, int maxHp) {
    if (hp < 0) return 0;        // early return
    if (hp > maxHp) return maxHp;
    return hp;
}

breakreturn의 차이도 같이 잡아둡니다.

  • break: 가장 가까운 반복문/switch만 탈출
  • return: 함수 전체를 즉시 종료(반환)
int FindFirstPositive(const int* arr, int n) {
    for (int i = 0; i < n; i++) {
        if (arr[i] > 0) return i; // 루프 + 함수 동시에 종료
    }
    return -1;
}

함수 선언 vs 정의

구분선언 (Declaration)정의 (Definition)
역할"이런 함수가 나중에 나온다"고 알림실제 구현
형태시그니처만 (세미콜론){} 안에 구현부
위치보통 .h 또는 상단.cpp 또는 하단
  • C++는 위에서 아래로 분석 → 호출 전에 선언이 먼저 있어야 함.
  • 나중에 헤더/CPP 분리 시: 선언은 .h, 정의는 .cpp.
int Add(int a, int b);  // 선언

int main() {
    Add(10, 20);  // 호출
}

int Add(int a, int b) {  // 정의
    cout << a + b << endl;
    return a + b;
}
  • 선언이 없으면 main()에서 Add 호출 시 컴파일러가 "Add가 뭔지 모르겠다"고 에러.

함수 오버로딩 (Overloading)

  • 동일 이름의 함수를 매개변수 개수·타입이 다르면 서로 다른 함수로 인식.
  • 반환 타입만 다르게 해서 오버로딩할 수는 없습니다. (시그니처는 매개변수로 결정)
  • 인자 개수 차이:
    void Test(int a) { cout << "하나만 받음" << endl; }
    void Test(int a, int b) { cout << "두 개 받음" << endl; }
    • Test(1); → 첫 번째, Test(1, 2); → 두 번째
  • 인자 타입 차이:
    void Test(int a) { cout << "int 버전" << endl; }
    void Test(float a) { cout << "float 버전" << endl; }
    • Test(10); → int 버전, Test(10.0f); → float 버전

지역 변수 vs 전역 변수

메모리 관점에서 “어디에 저장되고 언제까지 살아있는지”가 다릅니다.

[Data 영역]   : 전역/정적 변수 (프로그램 끝날 때까지 유지)
[Stack 영역]  : 지역 변수/매개변수 (함수 끝나면 사라짐)
구분전역 변수지역 변수
선언 위치함수 밖함수 안
유효 범위프로그램 전체해당 함수(또는 블록) 내
메모리 영역Data 영역Stack 영역
생명 주기프로그램 종료까지함수 종료 시 소멸
int globalVar = 100;

void TestFunction() {
    int localVar = 10;
    globalVar += 10;
    cout << "지역: " << localVar << ", 전역: " << globalVar << endl;
}
  • localVar: TestFunction() 내에서만 유효. 함수 종료 시 소멸.
  • globalVar: 프로그램 전체에서 사용 가능. 값 유지.
  • 전역 변수 단점: 여러 함수가 동시에 접근 → 누가 수정했는지 추적 어려움 (공공 로비에 물건 두는 것과 비유). 규모가 커지면 난장판.
  • 지역 변수: 해당 함수 스택 프레임 안에서만 유효. 종료 시 자동 해제. 지향할 방식.

변수 유효 범위 (스코프)

  • {} 블록 안에서 선언한 변수는 그 블록 안에서만 유효.
  • 동일 블록 내 같은 이름 재선언 → 에러 (int 재정의).
  • 다른 블록이면 같은 이름 사용 가능(블록이 다르면 스코프가 다름):
    {
        int hp = 10;
        // hp 사용
    }
    {
        int hp = 20;  // 다른 블록이므로 OK
    }

중첩 블록에서는 “바깥 이름을 가리는(shadowing)” 것도 가능합니다(추천하진 않음).

int hp = 100;
{
    int hp = 10;   // 바깥 hp를 가림
    cout << hp;    // 10
}
cout << hp;        // 100

함수 호출 시 스택 구조

  • 각 함수 호출 시 스택 프레임이 쌓이며, 매개변수와 지역 변수가 포함됨.
  • 가장 나중에 호출된 함수가 먼저 종료되는 LIFO 구조.
  • 함수가 끝나면 스택에서 해당 프레임이 제거됨.
  • 무한 재귀나 과도한 깊이의 호출은 스택 오버플로우 발생 가능.

호출 흐름을 스택 관점에서 보면 이런 느낌입니다.

main()
  -> A()
      -> B()
      <- B() 종료
  <- A() 종료

체크 질문 (스스로 답해보기)

  • 프로그래밍 함수가 “동일 입력 → 동일 출력”을 보장하지 못하는 이유는?
  • breakreturn의 차이를 한 문장으로 설명할 수 있을까?
  • 지역 변수는 왜 함수가 끝나면 사라질까? (스택/스코프 관점)

profile
李家네_공부방

0개의 댓글