소년코딩

01.04 - 함수와 반환 값 (functions and return values)

함수(Function)

함수(function)는 특정 작업을 수행하도록 만든 설계된 재사용 가능한 명령문이다.

모든 프로그램에는 main() 이라는 함수가 있어야 한다. main() 함수는 프로그램이 시작하는 곳을 의미하며, 대부분 프로그램에는 main() 함수를 제외하고도 많은 함수를 정의하여 사용한다.

프로그램은 함수 호출을 만나면 함수 내에서 순차적으로 명령문을 실행한다. 함수 호출은 현재 실행하고 있는 함수를 인터럽트(interrupt) 하고 호출한 함수를 실행하도록 CPU에 지시하는 식이다. 호출된 함수가 종료되면 CPU는 함수 호출 지점으로 돌아가서 이전 함수를 다시 실행한다.

함수 호출을 하는 함수를 호출자(caller)라고 하며, 호출되는 함수를 수신자(callee) 또는 called function이라고 한다.

#include <iostream> // for std::cout and std::endl

// doPrint() 함수의 정의
void doPrint() // doPrint 함수는 이 예제에서 호출된 함수(called function) 
{
    std::cout << "In doPrint()" << std::endl;
}

// main() 함수의 정의
int main()
{
    std::cout << "Starting main()" << std::endl;
    // doPrint() 함수를 호출함으로써 main() 함수를 인터럽트 한다. 여기서 main() 함수는 호출자(caller)
    doPrint();
    std::cout << "Ending main()" << std::endl;

    return 0;
}

// Starting main()
// In doPrint()
// Ending main()

위 프로그램은 main() 함수의 맨 윗줄에서 실행을 시작하고, 실행되는 첫 번째 줄은 "Starting main()"을 출력한다. main() 함수의 두 번째 줄은 doPrint() 함수를 호출한다. 이 시점에서 main() 함수의 실행은 일시 중단되고 CPU가 doPrint() 함수로 점프한다. doPrint() 함수의 유일한 행은 "In doPrint()"를 출력한다. 이후 doPrint() 함수가 종료되면 호출자(main() 함수)는 중단된 지점에서 실행을 다시 시작한다. 결과적으로 "Ending main()"을 출력한다.


반환 값(Return value)

main() 함수는 실행이 끝나면 return 명령문을 통해 정수 값(일반적으로 0)을 caller(여기서는 운영체제)에게 반환한다.

함수를 작성할 때, 함수가 호출자(caller)에게 값을 반환(return)할지 말지 결정하게 된다. 함수 정의에 함수 반환 형식을 설정하면 된다. 반환 유형(return type)은 함수 이름 앞에 선언된 유형이다. 반환 유형은 특정 값을 나타내지 않는다. 반환되는 값 유형을 나타낸다.

그런 다음 호출된 함수 내부에서 return 을 사용해서 호출자(caller)에게 반환되는 특정 값을 나타낸다. 함수에서 반환된 실제 값을 반환 값(return value)이라고 한다.

// int 는 함수가 호출자에게 정수 값을 반환한다는 것을 의미한다.
int return5()
{
    // 이 함수는 정수 값을 반환한다. 그러므로 return 문이 필요하다.
    return 5; // 호출자에게 정수 값 5를 반환한다.
}

int main()
{
    std::cout << return5() << std::endl;     // prints 5
    std::cout << return5() + 2 << std::endl; // prints 7

    return5(); // 정수 값 5를 반환받는다. 그러나 main() 함수는 이 값으로 아무것도 하지 않으므로 무시된다.

    return 0;
}

void 형의 반환 값(Return values of type void)

함수는 무조건 값을 반환할 필요는 없다. 함수가 값을 반환하지 않는다는 것을 컴파일러에 알리려면 반환 유형으로 void를 사용한다.

예제 1
void doPrint() // void는 반환 유형(return type)이다.
{
    std::cout << "In doPrint()" << std::endl;
    // 이 함수는 값을 반환하지 않으므로 return 문이 필요하지 않다.
}
예제 2
// void 는 함수가 호출자에게 값을 반환하지 않는다는 것을 의미한다.
void returnNothing()
{
    std::cout << "Hi" << std::endl;
    // 이 함수는 값을 반환하지 않으므로 return 문이 필요하지 않다.
}

int main()
{
    returnNothing(); // returnNothing() 함수를 호출한다. 값이 반환되지 않는다.

    std::cout << returnNothing(); // error: 컴파일되지 않는다.

    return 0;
}

반환 형식 void는 호출자에게 아무것도 반환하지 않는 함수가 필요할 때 사용한다.

메인으로 돌아 가기(Returning to main)

프로그램이 실행되면 운영 체제는 main() 함수 호출을 수행한다. main의 맨 위로 이동한 뒤 순차적으로 실행한다. 마지막으로 main() 함수는 정수(int) 값(일반적으로 0)을 운영체제에 반환한다. 이것이 main이 int main()으로 정의된 이유다.

왜 운영체제에 값을 반환할까? 이 값을 상태 코드(status code)라고 하며, 프로그램이 성공적으로 실행되었는지를 알려준다. 규칙에 따라 반환 값 0은 성공을 의미하고 양수 값은 실패를 의미한다.

C++ 표준에서는 main() 함수가 정수 값을 반환해야 한다고 말한다. 만약 main() 함수에 return 문이 없다면 컴파일러가 사용자를 대신해서 0을 반환한다. 그러나 명시적으로 main() 함수에서 값을 반환하는 게 좋다. 이는 의도를 보여주기 위해 그리고 반환 값을 생략 할 수 없는 다른 함수와의 일관성을 유지하는 것이다.


정리

  • 함수가 void 형이 아닌 반환 유형이 있으면 return 문을 이용해서 해당 유형의 값을 반환해야 한다.
  • 함수에서 return 문에 도달하면 해당 지점에서 호출자에게 즉시 반환된다. 함수의 추가 코드는 무시된다.
  • 함수는 호출자에게 하나의 값만 반환할 수 있다.

함수 재사용(Reusing functions)

한 번 이상 뭔가를 해야 할 경우 같은 함수를 여러 번 호출하는 것은 유용하다.

// getValueFromUser() 함수는 사용자로부터 정수 값을 읽고 반환한다.
int getValueFromUser()
{
    std::cout << "Enter an integer: ";
    int a;
    std::cin >> a; // 콘솔에서 숫자를 입력받고 변수 a에 할당한다.
    return a;      // 변수 a의 값을 호출자에게 반환한다. (main)
}

int main()
{
    int x = getValueFromUser(); // first call 
    int y = getValueFromUser(); // second call

    std::cout << x << " + " << y << " = " << x + y << std::endl;

    return 0;
}

// Enter an integer: 5
// Enter an integer: 7
// 5 + 7 = 12

cpp 번역: 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/14-a-first-look-at-functions/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기