이 페이지의 목차
결괏값을 돌려받다
코드 예제: Python · C · 예상 50분
학습 목표
- 반환값의 의미를 설명하고 결괏값을 돌려주는 함수를 작성한다.
- 변수의 유효 범위가 함수 안과 밖에서 어떻게 다른지 확인한다.
관련 성취기준
- 프그02-05
함수의 개념과 종류, 필요성을 이해하고, 함수 정의 및 사용자 정의 함수를 호출하고 결괏값을 반환하는 프로그램을 작성할 수 있다.
생각 열기 — 같은 이름이 두 곳에 있으면
함수 안에서도 개수 라는 변수를 쓰고, 함수 밖에서도 개수 를 쓰고 있다.
개수 = 0
def 세기():
개수 = 100
print("함수 안에서 개수 =", 개수)
세기()
print("함수 밖에서 개수 =", 개수)
반환 — 계산한 값을 바깥으로
반환값(return value) — 함수가 계산 결과로 바깥에 넘겨주는 값은 함수가 일을 마치고 내놓는 값이다. return 을 만나면 그 자리에서 함수가 끝나고 값이 부른 곳으로 돌아간다.
개수 = 0
def 세기():
개수 = 100
print("함수 안에서 개수 =", 개수)
세기()
print("함수 밖에서 개수 =", 개수)
def 두배(x):
결과 = x * 2
return 결과
print("두배(7) =", 두배(7))함수 안에서 개수 = 100 함수 밖에서 개수 = 0 두배(7) = 14
#include <stdio.h>
int count = 0;
void counting(void)
{
int count = 100;
printf("함수 안에서 count = %d\n", count);
}
int twice(int x)
{
int result = x * 2;
return result;
}
int main(void)
{
counting();
printf("함수 밖에서 count = %d\n", count);
printf("twice(7) = %d\n", twice(7));
return 0;
}함수 안에서 count = 100 함수 밖에서 count = 0 twice(7) = 14
답은 0 이다. 함수 안의 개수 와 밖의 개수 는 이름만 같고 서로 다른 변수다.
유효 범위 — 변수가 사는 구역
유효 범위(scope) — 변수를 볼 수 있고 쓸 수 있는 코드의 구역는 변수가 통하는 구역이다.
| 지역 변수 | 전역 변수 | |
|---|---|---|
| 어디서 만들어지나 | 함수 안 | 함수 밖 |
| 어디서 보이나 | 그 함수 안에서만 | 프로그램 어디서나 |
| 언제 사라지나 | 함수가 끝나면 | 프로그램이 끝날 때 |
| 이름이 겹치면 | 지역이 이긴다 — 함수 안에서는 지역을 본다 | 가려진다 |
| 보기 (위 코드) | 결과, 함수 안의 개수 | 함수 밖의 개수 |
전역 변수를 바꾸려면
함수 안에서 전역 변수를 읽는 것은 된다. 그런데 바꾸려면 별도 표시가 필요하다.
- Python: 함수 안에서
global 개수라고 먼저 적어야 한다. 안 적고개수 = 100을 하면 새 지역 변수가 만들어진다 — 위 예제가 그 경우다. - C: 지역에 같은 이름을 선언하지 않으면 그냥 전역이 바뀐다. 위 예제는
int count = 100;으로 지역을 새로 만들었기 때문에 전역이 안 바뀌었다.
return 은 그 자리에서 끝낸다
return 을 만나면 아래 줄은 실행되지 않는다. 이 성질을 쓰면 9차시 「더 알아보기」의 일찍 빠져나오기를 제대로 적을 수 있다.
def 평균(점수들):
if len(점수들) == 0:
return None ← 여기서 끝. 아래로 안 내려간다
return sum(점수들) / len(점수들)
3단원 5차시에서 만든 그 코드다. 잘못된 경우를 먼저 걸러 내고 빠져나오면, 아래 코드는 「여기 오는 값은 옳다」고 믿고 쓸 수 있다.
| 상황 | Python | C |
|---|---|---|
| 값이 없음을 알림 | return None | 따로 없다 — 성공 여부를 int 로 돌리고 결과는 포인터로 |
| 아무것도 안 돌려줌 | return 만 적거나 생략 | void 함수에서 return; |
| 여러 값 돌려주기 | return a, b 로 묶어서 | 구조체로 묶거나 포인터로 채운다 |
3단원 5차시에서 C의 average 가 값을 두 개 돌려주는 모양이 된 까닭이 이것이다. C에는 None 에 해당하는 값이 없어, 성공 여부를 반환값으로 하고 결과는 *out 에 넣었다.
활동
같은 이름의 변수가 함수 안팎에서 다르게 동작하는 실험
약 25분1단계 — 예상하고 확인한다 (10분)
실행기의 [고치기]로 아래를 하나씩 만들어 본다. 예상을 먼저 적는다.
| 코드 | 내 예상 | 실제 |
|---|---|---|
함수 안에서 개수 = 100 뒤 밖에서 출력 |
||
함수 안에서 global 개수 를 적고 개수 = 100 |
||
함수 안에서 print(개수) 만 (바꾸지 않고 읽기) |
||
함수 안의 지역 변수를 함수 밖에서 print |
네 번째에서 나는 오류 메시지를 그대로 적는다.
2단계 — return 뒤를 확인한다 (5분)
def 시험():
return 1
print("이 줄은 실행되는가?")
print(시험())print가 실행되는가?- 이 성질을 어디에 쓸 수 있는가? (9차시의 일찍 빠져나오기)
3단계 — 빈 목록을 막는다 (5분)
평균 함수에 빈 목록이 들어왔을 때를 처리한다.
| 넣은 값 | 막기 전 | 막은 뒤 |
|---|---|---|
[88, 92] |
||
[] |
- 막기 전에 어떤 오류가 났는가? 1단원 6차시의 어느 조건과 이어지는가?
- C에서는 「값이 없음」을 어떻게 돌려주었는가? (3단원 5차시)
4단계 — 전역 변수의 문제를 겪어 본다 (5분)
전역 변수 합계 를 두고, 두 함수가 각각 그것을 바꾸게 만든다.
합계 = 0
def 더하기(x): global 합계; 합계 += x
def 지우기(): global 합계; 합계 = 0- 두 함수를 번갈아 부르고 중간중간
합계를 찍어 본다. - 값이 예상과 다르게 나왔을 때 어느 함수 때문인지 어떻게 찾겠는가?
- 같은 일을 전역 변수 없이 만들면 어떻게 되는가? (매개변수와 반환값으로)
개념 확인 문제
보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.
함수 안에서 개수 = 100 을 했을 때 함수 밖의 개수 가 그대로인 까닭은?프그02-05
Python에서 함수 안에서 전역 변수의 값을 바꾸려면?프그02-05
return 을 만나면?프그02-05
전역 변수를 되도록 쓰지 않는 까닭으로 가장 알맞은 것은?프그02-05
C에서 「값이 없음」을 돌려주기 위해 3단원 5차시에서 쓴 방법은?프그02-05
지역 변수가 함수 밖으로 새어 나가지 않는 것이 주는 이점은?프그02-05
더 알아보기
심화여러 값을 한 번에 돌려주기
Python은 값을 여러 개 돌려줄 수 있다.
def 통계(점수들):
return len(점수들), sum(점수들) / len(점수들), max(점수들)
인원, 평균, 최고 = 통계([88, 92, 75])받는 쪽에서 이름을 나눠 받는다. 편하지만 순서를 외워야 한다는 문제가 있다 — 14차시의 순서 실수가 여기서도 생긴다. 항목이 셋을 넘으면 3단원 3차시처럼 이름으로 꺼내는 묶음으로 돌려주는 편이 안전하다.
C는 값을 하나만 돌려줄 수 있다. 그래서 구조체로 묶어 돌려주거나, 포인터로 채우는 방식을 쓴다. 3단원 6차시의 Summary 구조체가 앞의 방법이다.
심화함수가 자기를 부르면
함수 안에서 자기 자신을 부를 수도 있다. 이것을 재귀라 한다.
def 팩토리얼(n):
if n <= 1:
return 1
return n * 팩토리얼(n - 1)팩토리얼(4) 는 4 × 팩토리얼(3) 을 부르고, 그것이 다시 3 × 팩토리얼(2) 를 부른다. if n <= 1: return 1 이 없으면 끝나지 않는다 — 1단원 6차시의 유한성이 여기서도 그대로 필요하다. 이렇게 멈추는 자리를 종료 조건이라 한다.
반복으로 할 수 있는 일은 대개 재귀로도 할 수 있고 그 반대도 그렇다. 어느 쪽이 읽기 쉬운지는 문제에 따라 다르다.
실무같은 입력에 같은 출력이면 다루기 쉽다
매개변수로만 값을 받고 반환값으로만 결과를 내놓으며, 전역 변수를 건드리지 않고 화면에도 안 찍는 함수를 생각해 보자. 이런 함수는 같은 값을 넣으면 언제나 같은 값이 나온다.
이 성질이 있으면 좋은 점이 많다. 테스트가 쉽고(3단원 7차시), 순서를 바꿔 불러도 결과가 같고, 어디서 틀렸는지 좁히기 쉽다. 반대로 전역 변수를 읽거나 파일을 읽는 함수는 부르는 시점에 따라 결과가 달라져 같은 사례로 두 번 시험했을 때 다른 결과가 나올 수 있다.
프로그램에는 화면 출력이나 파일 읽기가 반드시 필요하다. 요령은 그런 일을 하는 함수와 계산만 하는 함수를 나눠 두는 것이다 — 14차시에서 계산과 출력을 섞지 않기로 한 판단이 여기까지 이어진다.
이어지는 학습
이 차시를 이해하려면 다음을 먼저 알아야 한다.
- 14차시의 함수 정의와 매개변수 — 프로그래밍 프그02-05
교과서에서 찾기
| 교과서 | 해당 위치 | 쪽수 |
|---|---|---|
| 성림출판(Python) | 프로그래밍의 기초 › 05 함수 | 156쪽 |
| 씨마스커뮤니케이션(Python) | 프로그래밍 기초 › 5 함수 | 146쪽 |
| 삼양미디어(Python) | 프로그래밍의 기초 › 04 함수 | 126쪽 |
| 삼양미디어(C) | 프로그래밍의 기초 › 04 함수 | 130쪽 |
| 씨마스(C) | C 프로그래밍의 기초 › 6 함수 | 126쪽 |
| 웅보출판사(C) | 프로그래밍의 기초 › Chapter 05 함수 | 141쪽 |