{ }codelper

배우기 › C

함수 · 14

함수

일을 이름 붙여 묶고, 값을 받아 결과를 돌려줘요. 재귀까지.

함수는 이름 붙인 코드 묶음이에요.
값(매개변수)을 받아 결과를 돌려줘요.
아래 예제는 제곱을 구하는 함수와, 자기 자신을 부르는 팩토리얼 함수를 만들어 써요.

#include <stdio.h> int square(int x) {    return x * x;} long long factorial(int n) {    if (n <= 1) return 1;    return n * factorial(n - 1);} int main(void) {    int n;    scanf("%d", &n);    printf("%d\n", square(n));    printf("%lld\n", factorial(n));    return 0;}
stdin
4
stdout
16
24

핵심

  • 같은 계산을 여러 곳에서 쓰거나, 긴 풀이를 작은 조각으로 나눌 때 함수로 묶어요.
  • return을 만나면 함수는 그 자리에서 끝나요.
    그 아래 줄은 실행되지 않아요.
  • 수를 넘기면 값이 복사돼요.
    함수 안에서 x = 9로 바꿔도 부른 쪽 변수는 그대로예요.
  • 목록을 넘기면 같은 목록을 함께 써요.
    함수 안에서 값을 넣으면 밖에서도 바뀌어요(C++ vector는 넘길 때 복사돼요).
  • 재귀는 함수가 자기 자신을 부르는 거예요.
    큰 문제를 같은 모양의 작은 문제로 줄이고, 반드시 멈추는 조건이 있어야 해요(n <= 1이면 1).
  • 멈추는 조건이 없거나 너무 깊으면, 언어마다 오류로 멈추거나 프로그램이 통째로 죽어요.

언어별로 쓰는 법

Pythondef square(x): + 들여쓰기.
return이 없으면 None을 돌려줘요.
def가 실행된 뒤에만 부를 수 있어요(먼저 부르면 NameError).
재귀는 기본 약 1,000단계에서 RecursionError
JavaScriptfunction square(x) { return x * x; } 또는 const square = (x) => x * x;.
return이 없으면 undefined.
function 선언은 부르는 곳보다 아래에 있어도 돼요.
너무 깊으면 RangeError: Maximum call stack size exceeded
TypeScriptJavaScript에 타입을 붙여요: function square(x: number): number.
값 개수가 틀리면 타입 검사에서 알려 줘요
Java클래스 안에 static int square(int x).
돌려줄 값이 없으면 void.
클래스 안 어디에 있어도 돼요.
너무 깊으면 StackOverflowError
C#Java처럼 클래스 안에 static int Square(int x), 없으면 void.
너무 깊은 재귀는 프로그램이 통째로 죽어요
C++int square(int x)처럼 돌려줄 타입을 앞에 적고, 없으면 void.
쓰기 전에 위에 정의하거나 int square(int x);로 선언해요.
너무 깊은 재귀는 프로그램이 죽어요
CC++와 같아요
Craykon키워드 없이 square(x) { 돌려주기 x * x; }.
부르는 곳보다 아래에 있어도 돼요.
몇천 단계 넘게 부르면 "함수를 너무 깊이 불러서 멈췄어요"

자주 하는 실수

멈추는 조건이 없어요

def factorial(n):
    return n * factorial(n - 1)

→ 끝없이 자기를 불러서 RecursionError로 멈춰요. 다른 언어도 스택이 넘쳐 멈추거나 죽어요

맨 앞에 if n <= 1: return 1처럼 멈추는 조건을 둬요.

값을 빠뜨리고 불렀어요JavaScript

function square(x) { return x * x; }
console.log(square());

→ NaN — 빠진 x가 오류 없이 undefined로 채워져요

값 개수를 맞춰요.
Python(TypeError), Java·C#·C·C++·TypeScript(컴파일 오류), 크레이콘("값이 2개 필요한데 1개를 넣었어요")은 알려 줘요.

함수 안에서 바꿨는데 원본은 그대로예요C++

void add(std::vector<int> v) { v.push_back(9); }

std::vector<int> a = {1};
add(a);

→ a는 여전히 {1} — 복사본에 넣었어요

원본을 바꾸려면 std::vector<int>& v처럼 &를 붙여요.

언어마다 다른 점
팩토리얼은 금방 커져요.
32비트 int에는 12!까지만 들어가서(Java int로 13!을 계산하면 오류 없이 1932053504), Java·C#·C·C++ 예제는 64비트 long/long long(20!까지)을 돌려주고, Python은 크기 제한이 없으며 JavaScript·크레이콘은 2^53을 넘으면 정확하지 않을 수 있어요.

연습 문제