함수 · 14
함수
일을 이름 붙여 묶고, 값을 받아 결과를 돌려줘요. 재귀까지.
함수는 이름 붙인 코드 묶음이에요.
값(매개변수)을 받아 결과를 돌려줘요.
아래 예제는 제곱을 구하는 함수와, 자기 자신을 부르는 팩토리얼 함수를 만들어 써요.
def square(x): return x * x def factorial(n): if n <= 1: return 1 return n * factorial(n - 1) n = int(input())print(square(n))print(factorial(n))function square(x) { return x * x;} function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1);} const n = Number(require("fs").readFileSync(0, "utf8"));console.log(square(n));console.log(factorial(n));import { readFileSync } from "node:fs"; function square(x: number): number { return x * x;} function factorial(n: number): number { if (n <= 1) return 1; return n * factorial(n - 1);} const n: number = Number(readFileSync(0, "utf8"));console.log(square(n));console.log(factorial(n));import java.util.Scanner; public class Main { static int square(int x) { return x * x; } static long factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } public static void main(String[] args) { int n = new Scanner(System.in).nextInt(); System.out.println(square(n)); System.out.println(factorial(n)); }}using System; class Program{ static int Square(int x) => x * x; static long Factorial(int n) { if (n <= 1) return 1; return n * Factorial(n - 1); } static void Main() { int n = int.Parse(Console.ReadLine()); Console.WriteLine(Square(n)); Console.WriteLine(Factorial(n)); }}#include <iostream> int square(int x) { return x * x;} long long factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1);} int main() { int n; std::cin >> n; std::cout << square(n) << '\n'; std::cout << factorial(n) << '\n';}#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;}square(x){ 돌려주기 x * x;} factorial(n){ 만약 (n <= 1) { 돌려주기 1; } 돌려주기 n * factorial(n - 1);} n = 콘솔.줄읽기().수로변환();콘솔.쓰기(square(n));콘솔.쓰기(factorial(n));4
16 24
핵심
- 같은 계산을 여러 곳에서 쓰거나, 긴 풀이를 작은 조각으로 나눌 때 함수로 묶어요.
return을 만나면 함수는 그 자리에서 끝나요.
그 아래 줄은 실행되지 않아요.- 수를 넘기면 값이 복사돼요.
함수 안에서x = 9로 바꿔도 부른 쪽 변수는 그대로예요. - 목록을 넘기면 같은 목록을 함께 써요.
함수 안에서 값을 넣으면 밖에서도 바뀌어요(C++vector는 넘길 때 복사돼요). - 재귀는 함수가 자기 자신을 부르는 거예요.
큰 문제를 같은 모양의 작은 문제로 줄이고, 반드시 멈추는 조건이 있어야 해요(n <= 1이면1). - 멈추는 조건이 없거나 너무 깊으면, 언어마다 오류로 멈추거나 프로그램이 통째로 죽어요.
언어별로 쓰는 법
| Python | def square(x): + 들여쓰기.return이 없으면 None을 돌려줘요.def가 실행된 뒤에만 부를 수 있어요(먼저 부르면 NameError).재귀는 기본 약 1,000단계에서 RecursionError |
|---|---|
| JavaScript | function square(x) { return x * x; } 또는 const square = (x) => x * x;.return이 없으면 undefined.function 선언은 부르는 곳보다 아래에 있어도 돼요.너무 깊으면 RangeError: Maximum call stack size exceeded |
| TypeScript | JavaScript에 타입을 붙여요: 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);로 선언해요.너무 깊은 재귀는 프로그램이 죽어요 |
| C | C++와 같아요 |
| Craykon | 키워드 없이 square(x) { 돌려주기 x * x; }.부르는 곳보다 아래에 있어도 돼요. 몇천 단계 넘게 부르면 "함수를 너무 깊이 불러서 멈췄어요" |
자주 하는 실수
멈추는 조건이 없어요
def factorial(n):
return n * factorial(n - 1)→ 끝없이 자기를 불러서 RecursionError로 멈춰요. 다른 언어도 스택이 넘쳐 멈추거나 죽어요
맨 앞에 if n <= 1: return 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처럼 &를 붙여요.
값을 빠뜨리고 불렀어요JavaScript
function square(x) { return x * x; }
console.log(square());→ NaN — 빠진 x가 오류 없이 undefined로 채워져요
값 개수를 맞춰요.
Python(TypeError), Java·C#·C·C++·TypeScript(컴파일 오류), 크레이콘("값이 2개 필요한데 1개를 넣었어요")은 알려 줘요.
언어마다 다른 점
팩토리얼은 금방 커져요.
32비트
팩토리얼은 금방 커져요.
32비트
int에는 12!까지만 들어가서(Java int로 13!을 계산하면 오류 없이 1932053504), Java·C#·C·C++ 예제는 64비트 long/long long(20!까지)을 돌려주고, Python은 크기 제한이 없으며 JavaScript·크레이콘은 2^53을 넘으면 정확하지 않을 수 있어요.