프로그래밍웹 교과서
이 페이지의 목차
2단원 · 14차시

함수 정의하고 호출하기

함수 정의호출매개변수(parameter)인수(argument)

코드 예제: Python · C · 예상 50분

학습 목표

  • 사용자 정의 함수를 정의하고 호출한다.
  • 매개변수로 값을 전달하는 프로그램을 작성한다.

관련 성취기준

  • 프그02-05

    함수의 개념과 종류, 필요성을 이해하고, 함수 정의 및 사용자 정의 함수를 호출하고 결괏값을 반환하는 프로그램을 작성할 수 있다.

생각 열기 — 도형이 여러 개면

직사각형 넓이를 구해야 한다. 가로 4, 세로 5인 것과 가로 6, 세로 6인 것 둘 다.

13차시에서 함수가 필요하다는 것은 알았다. 그런데 평균 함수는 목록 하나를 받았는데 여기서는 가로와 세로 둘을 받아야 한다.

함수를 만드는 문법

함수 정의 문법
부분PythonC
시작 표시def돌려줄 자료형을 먼저 적는다
이름def 직사각형넓이(…)int rect_area(…)
받는 것이름만 적는다 — (가로, 세로)자료형까지 — (int w, int h)
몸통 범위콜론과 들여쓰기{ }
돌려주기returnreturn
안 돌려줄 때return 을 안 쓰면 된다void 라고 적는다
Python도형의 넓이를 구하는 함수
def 직사각형넓이(가로, 세로):
    return 가로 * 세로

def 삼각형넓이(밑변, 높이):
    return 밑변 * 높이 / 2

print("직사각형:", 직사각형넓이(4, 5))
print("삼각형:", 삼각형넓이(4, 5))
print("정사각형:", 직사각형넓이(6, 6))
확인된 실행 결과
직사각형: 20
삼각형: 10.0
정사각형: 36
C도형의 넓이를 구하는 함수확인된 출력
#include <stdio.h>

int rect_area(int w, int h) { return w * h; }
double tri_area(int b, int h) { return b * h / 2.0; }

int main(void)
{
    printf("직사각형: %d\n", rect_area(4, 5));
    printf("삼각형: %.1f\n", tri_area(4, 5));
    printf("정사각형: %d\n", rect_area(6, 6));
    return 0;
}
실행 결과
직사각형: 20
삼각형: 10.0
정사각형: 36

직사각형넓이 를 두 번 불렀다. 한 번은 4와 5로, 한 번은 6과 6으로. 함수를 한 번 만들어 두면 값을 바꿔 몇 번이든 부를 수 있다.

매개변수와 인수 — 같은 값의 두 이름

매개변수(parameter) — 함수를 정의할 때 적는, 받을 값의 이름는 정의할 때 적는 이름이고, 인수(argument) — 함수를 부를 때 실제로 넘기는 값는 부를 때 넘기는 값이다.

def 직사각형넓이(가로, 세로):      ← 가로, 세로가 매개변수
    return 가로 * 세로

직사각형넓이(4, 5)                 ← 4, 5가 인수
매개변수 인수
언제 함수를 정의할 때 함수를 부를 때
무엇 받을 값에 붙인 이름 실제로 넘기는 값
위 예 가로, 세로 4, 5
몇 개 정의에서 정해진다 정의와 개수가 맞아야 한다

순서가 뜻을 정한다

직사각형넓이(4, 5) 에서 4가 가로, 5가 세로다. 순서로 정해진다. 넓이는 곱셈이라 바꿔도 결과가 같지만, 삼각형이라면 다르다.

삼각형넓이(4, 5)   → 4 × 5 ÷ 2 = 10.0   (밑변 4, 높이 5)
삼각형넓이(5, 4)   → 5 × 4 ÷ 2 = 10.0   (여기서도 같지만)

나눗셈이 들어가면 순서가 답을 바꾼다.

def 백분율(부분, 전체):
    return 부분 / 전체 * 100

백분율(30, 50)   → 60.0
백분율(50, 30)   → 166.7   ← 순서를 바꾸면 틀린다

개수가 맞아야 한다

정의에서 둘을 받게 했으면 부를 때도 둘을 넘겨야 한다.

개수가 어긋나면
PythonC
하나만 넘기면실행할 때 TypeError컴파일할 때 오류
셋을 넘기면실행할 때 TypeError컴파일할 때 오류
자료형이 안 맞으면넘어간 뒤 계산에서 드러난다컴파일할 때 걸리거나 조용히 바뀐다

1단원 2차시의 「오류를 만나는 시점」 차이가 여기서도 나타난다. C가 먼저 걸러 주고 Python은 실행해 봐야 안다.

값을 안 돌려주는 함수

모든 함수가 값을 돌려주지는 않는다. 화면에 찍는 일만 하는 함수가 그렇다.

def 표찍기(과목, 점수):
    print(f"{과목}  {점수:>6.1f}")

돌려줄 것이 없으므로 return 이 없다. C에서는 이런 함수를 void 로 적는다. 3단원 3차시 설계서에서 report 의 「돌려주는 것」 칸에 「없음 (화면 출력)」 이라고 적은 것이 이 경우다.

활동

실습

도형의 면적을 구하는 함수 만들기

약 25분

1단계 — 함수를 더 만든다 (10분)

아래 함수들을 만들어 붙이고 값을 확인한다.

함수 받는 것 확인할 값 기대 결과
원 넓이 반지름 반지름 5 78.5 (원주율 3.14)
사다리꼴 넓이 윗변, 아랫변, 높이 3, 5, 4 16.0
직육면체 부피 가로, 세로, 높이 2, 3, 4 24

기대 결과를 손으로 먼저 계산한다 (3단원 4차시).

2단계 — 순서를 바꿔 본다 (5분)

백분율 함수를 만들어 순서를 바꿔 부른다.

def 백분율(부분, 전체):
    return 부분 / 전체 * 100
부른 방식 결과 옳은가
백분율(30, 50)
백분율(50, 30)
백분율(전체=50, 부분=30)
  • 두 번째가 오류로 걸렸는가? 안 걸렸다면 왜 위험한가?
  • 세 번째 방식의 이점은 무엇인가?

3단계 — 개수를 어긋나게 해 본다 (5분)

직사각형넓이(4) 처럼 하나만 넘겨 본다.

  • Python의 오류 메시지를 그대로 적는다.
  • 메시지에 몇 개가 필요한데 몇 개를 받았는지 나오는가?
  • 같은 잘못을 C에서 하면 언제 걸리는가? (컴파일할 때인가 실행할 때인가)

4단계 — 두 갈래로 나눈다 (5분)

아래 함수는 두 가지 일을 하고 있다. 둘로 나눠 보자.

def 넓이구해찍기(가로, 세로):
    넓이 = 가로 * 세로
    print("넓이:", 넓이)
  • 나눈 뒤 계산 함수만 써야 하는 상황을 하나 들어 보자.
  • 3단원 3차시의 어느 부품들이 이렇게 나뉘어 있었는가?

개념 확인 문제

보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.

매개변수와 인수를 바르게 구분한 것은?프그02-05

백분율(부분, 전체) 를 백분율(50, 30) 으로 잘못 불렀을 때 생기는 일은?프그02-05

함수에 넘기는 인수의 개수가 정의와 다를 때, 두 언어의 차이는?프그02-05

값을 돌려주지 않는 함수를 C에서 적을 때 쓰는 것은?프그02-05

평균을 구하면서 화면에도 찍는 함수를 만들면 생기는 문제는?프그02-05

매개변수가 셋을 넘어갈 때 Python에서 이름을 붙여 넘기는 것이 나은 까닭은?프그02-05

더 알아보기

심화기본값을 정해 두기

Python에서는 매개변수에 기본값을 줄 수 있다.

def 평균(점수들, 자릿수=1):
    return round(sum(점수들) / len(점수들), 자릿수)

평균(점수)          → 자릿수는 1
평균(점수, 2)       → 자릿수는 2

자주 쓰는 값을 기본으로 두면 부르는 쪽이 짧아지고, 필요할 때만 바꿔 넘기면 된다. 기본값은 오른쪽 매개변수부터 줄 수 있다 — 앞쪽에 기본값이 있고 뒤쪽에 없으면 순서로 짝을 지을 수 없기 때문이다. C에는 이 문법이 없어, 값을 다르게 받는 함수를 따로 만들거나 늘 전부 넘긴다.

심화값을 넘긴다는 것 — 사본인가 원본인가

직사각형넓이(가로길이, 세로길이) 를 부를 때 함수 안에서 매개변수를 바꾸면 부르는 쪽의 변수도 바뀔까? 숫자라면 안 바뀐다. 값의 사본이 넘어가기 때문이다.

그런데 Python에서 리스트를 넘기면 사정이 다르다. 1차시와 4차시 「더 알아보기」에서 다룬 이름표 이야기가 여기서 문제가 된다. 함수 안에서 점수들.append(0) 을 하면 부르는 쪽의 리스트도 바뀐다. 같은 리스트에 이름표가 하나 더 붙은 것이기 때문이다.

이것이 뜻하지 않은 변화를 만들 수 있어, 받은 값을 함수 안에서 바꾸지 않는 것을 관례로 삼는다. 바꿔야 하면 사본을 만들어 쓰거나, 바꾼다는 사실을 함수 이름과 문서에 분명히 적는다.

실무매개변수가 많아지면 묶는다

매개변수가 다섯 개를 넘어가면 부르는 쪽이 읽기 어려워진다. 만들기(1, 2, 3, 0, 1, 0) 같은 코드는 무엇이 무엇인지 알 수 없다.

이럴 때 관련된 값들을 묶어 하나로 넘긴다. 3단원 3차시에서 통계 결과 다섯 항목을 묶음 하나로 돌려주기로 한 것과 같은 판단이다. Python은 사전으로, C는 구조체로 묶는다. 묶으면 항목이 늘어도 함수의 겉모습이 안 바뀌는 이점도 따라온다.

그리고 매개변수가 많다는 것 자체가 그 함수가 여러 일을 하고 있다는 신호일 때가 많다. 먼저 나눌 수 있는지 살펴보는 편이 좋다.

이어지는 학습

이 차시를 이해하려면 다음을 먼저 알아야 한다.

  • 13차시의 함수 개념 — 프로그래밍 프그02-05

교과서에서 찾기

교과서해당 위치쪽수
성림출판(Python)프로그래밍의 기초 › 05 함수156쪽
씨마스커뮤니케이션(Python)프로그래밍 기초 › 5 함수146쪽
삼양미디어(Python)프로그래밍의 기초 › 04 함수126쪽
삼양미디어(C)프로그래밍의 기초 › 04 함수130쪽
씨마스(C)C 프로그래밍의 기초 › 6 함수126쪽
웅보출판사(C)프로그래밍의 기초 › Chapter 05 함수141쪽