part 08 함수 - gwnucadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수...

56
1 Part 08 함수

Upload: others

Post on 24-Feb-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

1

Part 08 함수

Page 2: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

2

이 장의 내용

함수 개요

프로시저

함수호출 메커니즘

함수 밖에 있는 변수

재귀함수

매크로 함수

Page 3: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

3

8.1 함수 개요

Page 4: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

4

함수 개요

함수란?

함수(function; 函數): 상자 수; 상자에 수를 넣으면 수가 나옴

자동판매기와 유사함

수학에서 함수는 대응관계(mapping)를 의미함

함수 주변 상황

인수: 함수에 들어가는 값 정의구역(domain)의 원소

리턴값: 함수가 되돌려주는 값 공변역(co-domain)의 원소

Page 5: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

5

C 언어에서 함수

프로그래밍 분야에서 함수란?

작은 프로그램(subprogram)

인수를 받아서 리턴값을 내는 모듈

수학 함수와 다른 점

프로그래밍에서 함수는 부수효과(side-effects)를 낼 수 있다.

심지어 리턴값이 아예 없을 수도 있다.

리턴값이 없는 함수를 프로시저(procedure)라고 부른다.

printf의 부수효과 예:

Page 6: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

6

함수 정의 방법

C 함수 정의 형태 리턴타입 함수이름(매개변수목록)

{

문장들

}

C 함수 정의 예 int add1( int x )

{ return x + 1 ; }

예쁘게 들여 씁시다. int add1(int x)

{

return (x + 1);

}

함수 헤더(function header)

함수 본체(function body)

add1

x

x+1

리턴타입

리턴값

매개변수

매개변수 타입

Page 7: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

7

return 문과 리턴타입

return 문 형식: return 수식;

함수가 어떤 값을 돌려주는지 명시함

리턴값(return value)은 수식으로 주어지는데 수식에 괄호를 사용하면 이해하기 쉽다.

리턴값은 리턴타입(return type)과 일치해야 한다.

수학함수와 비교

인수 자료형: 정의구역

리턴타입: 공변역

double half(int x) { return (x / 2.0); }

half: int double where half(x) = x / 2.0

Page 8: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

8

add1half.c

실행결과: 정수를 하나 입력하세요. 123 123 의 바로 다음 정수는 124 이고 123 의 반은 61.5 입니다. 제가 맞게 계산했나요 ?

인수 값의 반을 구하는 함수

인수보다 하나 큰 값을 구하는 함수

Page 9: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

9

함수 프로토타입

함수 프로토타입(prototype)이란?

함수 사용방법만 명시한 것

어떤 자료형의 인수를 몇 개 받고

어떤 자료형의 리턴값을 내는지 명시함

함수의 정의구역과 공변역을 명시함

왜 함수 프로토타입이 중요한가?

함수를 사용(호출)하기 전에 함수 정의나 함수 프로토타입 선언 중 최소한 하나는 나타나야 함

프로토타입 작성 예

매개변수 이름 생략 가능

int add1(int x); double half(int x);

int add1(int); double half(int);

Page 10: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

10

prototype.c

실행결과: 정수를 하나 입력하세요. 123 123 의 바로 다음 정수는 124 이고 123 의 반은 61.5 입니다. 제가 맞게 계산했나요 ?

add1과 half의

prototype

add1과 half 정의

프로토타입 선언 후에는 선언한 함수를 사용할 수 있다.

Page 11: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

11

8.2 프로시저

Page 12: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

12

프로시저

C 함수 분류

값 리턴 함수(value-returning function): 값을 리턴하는 함수, 수학적 함수와 유사함

void 함수(void functions): 값을 리턴하지 않는 함수, 부수효과만을 이용하여 어떤 작업을 수행

void 함수를 "프로시저(procedure)"라고 부르기도 한다.

연산자, 명령어와 함수의 유사성

값 리턴 함수: 연산자와 유사 사용자 정의 연산자(user-defined operator)

void 함수: 명령어와 유사 사용자 정의 명령어(user-defined commands)

프로그래밍이란 해법을 연산자와 명령어를 이용하여 작성하는 것. 프로그래밍 언어에서 제공하는 연산자와 명령어가 충분하지 않다면 나름대로 연산자와 명령어를 정의하여 사용한다!

Page 13: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

13

void.c

실행결과: 정수를 하나 입력하세요. 123 123 의 바로 다음 정수는 124 이고 123 의 반은 61.5 입니다. 제가 맞게 계산했나요 ?

함수 add1과 half를

이용하는 void 함수. 이 함수 때문에 main이

간단해졌다.

Page 14: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

14

작명법에 관한 도움말

이름은 구체적으로 작성한다 적절하지 못한 이름: process(); test(); control();

적절한 이름:

dot_product(); 두 벡터의 내적을 구하는 함수

all_positive(); 컨테이너 원소가 모두 양수인가 검사

rotate_right(); 순차 컨테이너 고리형태로 간주하고 원소를 우측으로 이동시킴

여러 단어로 이루어진 이름은…

밑줄을 이용하는 방식: 전통적인 C 프로그래밍 방식

낙타체: 대소문자를 번갈아 사용해가며 단어를 구별하는 방식

Java에서 사용하는 방식

dotProduct(); allPositive(); rotateRight();

Page 15: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

15

하향식 프로그래밍

Top-Down Programming

바로 구현할 수 있을 단계까지 문제를 점진적으로 세분화하여 내려가는 방식(stepwise refinement)

한 문장으로 나타낸 문장을 "전체문제(top)"라고 한다.

그림 8.1) 하향식 프로그래밍에서의 단계별 세분화

Page 16: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

16

topdown2.c (1/2)

함수 main에는 '전체문제'를 기술한다.

'전체문제'를 기술하는데 필요한 '명사'는 변수나 상수로 선언한다. '전체문제'를 기술하는데 필요한 '동사'는 함수를 이용한다.

'전체문제'를 기술하는데 필요한 함수들

Page 17: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

17

topdown2.c (2/2)

실행결과: 정수를 하나 입력하세요. 7762 7762 의 바로 다음 정수는 7763 이고 7762 의 반은 3881.0 입니다.

Page 18: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

18

추상화

추상화(abstraction)

중요한 것만 남기고 불필요한 것은 과감히 생략하는 기법

프로그래밍의 키워드(keyword): 프로그래밍에서 가장 중요한 기법

함수의 중요성

구체적인 동작을 추상화하기 위한 기본적인 방법

하향식 프로그래밍의 기초가 됨

추상화

Page 19: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

19

8.3 함수호출 메커니즘

Page 20: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

20

함수 호출과 복귀 개요

기본적인 방식 호출자 함수 A는 함수 B를 호출하면 수행을 멈춘다

호출된 함수 B는 1. return 문을 만나거나 2. 함수 몸체 끝에 도달할 때까지 수행한다

호출된 함수 B의 수행이 끝나면 호출지점 바로 다음으로 복귀한다.

복귀지점 복귀지점은 문장 단위가 아닐 수도 있다.

예를 들어, double result = add1(2) * half(3);

printf("result = %f\n", result);

에서 half()가 add1()보다 먼저 호출되었다면 그 복귀지점은 add1(2)가 된다.

Page 21: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

21

제어흐름과 자료흐름

제어흐름

프로그램 수행 순서를 제어흐름(control flow)라고 함

한 함수 내에서 제어흐름은 제어구조에 의해 결정됨

함수 사이의 제어흐름은 함수호출에 의해 결정됨

자료흐름

데이터가 전달되는 순서를 자료흐름(data flow)라고 함

한 함수 내에서 자료흐름은 대입문에 의해 결정됨

함수 사이의 자료흐름은 인수전달(parameter passing)과 반환값 전달에 의해 결정됨

함수호출 메커니즘

함수 호출, 복귀 시에는 제어흐름과 자료흐름이 함께 변경되므로 주의해야 한다.

Page 22: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

22

제어흐름 예

main 함수에서 f를 호출했다고 하면 f는 두 가지 방식으로 복귀할 수 있다

Page 23: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

23

자료흐름: 인수전달

함수 인수(argument)는 값을 구하여 매개변수(parameter)에 "복사"하여 전달한다.

예:

main 함수에서 print_sign(5);를 호출했을 경우

Page 24: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

24

자료흐름: 임시변수 사용

인수가 수식인 경우에는 호출자의 임시공간(임시변수)를 활용하여 수식 값을 구한 후 전달한다.

예:

다음과 같이 호출한 경우 수식 b - a 값은 main의

임시공간에서 계산된다.

Page 25: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

25

자료흐름: 리턴값 전달

값 반환 함수 호출

값 반환 함수 호출은 수식으로 간주하기 때문에 리턴값도 역시 호출자의 임시변수에 저장한다.

값 반환 함수는 사용자 정의 '연산자'라는 사실을 기억하자.

예:

다음과 같이 호출한 경우 read_int() 값과 num*num

값은 임시공간에 저장된다.

Page 26: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

26

sign.c 제어흐름

자료흐름

Page 27: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

27

함수호출 메커니즘 정리

함수 f가 함수 g를 호출했을 때, 함수호출 메커니즘

(1) f의 본체 내에서 g의 실인수 값을 계산한다.

(2) g에 대한 데이터 영역이 생성된다.

(3) 실인수 값을 g의 매개변수로 복사한다. 인수가 여러 개일 때, 복사 순서는 컴파일러마다 다르다.

(4) 제어흐름이 f에서 g로 전달된다. f는 수행을 멈춘다.

(5) g의 본체 끝에 도달하거나 수행 중 return 문에 도달할 때까지

g의 본체 내 문장을 수행한다.

(6) 리턴 수식이 있는 return 문에 도달한 경우 리턴 값을 구한다.

(7) 리턴 값을 f 영역 내의 임시변수에 복사한다.

(8) 제어흐름이 g에서 f로 전달된다. g 영역은 소멸된다.

(9) f의 본체가 이전에 멈추었던 위치 바로 다음부터 계속 수행된다.

Page 28: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

28

8.4 함수 밖에 있는 변수

Page 29: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

29

함수 밖에 있는 변수

지역변수(local variable)

함수 내에 있는 변수

함수 내부에서만 볼 수 있음

함수가 호출될 때 생성되므로 동적변수(dynamic variable)임

비지역변수(nonlocal variable)

함수 밖에 있는 변수

여러 함수에서 볼 수 있음

전역변수(global variable): 프로그램 전체에서 볼 수 있음

파일범위변수(file scope variable): 같은 파일 내의 함수에서만 볼 수 있음

프로그램이 시작할 때 생성되므로 정적변수(static variable)임

Page 30: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

30

nonlocal.c

비지역 변수 GX는 세 함수에서

모두 볼 수 있다.

이렇게 선언된 GX는 전역변수다.

다른 파일에서 GX를 볼려면 extern int GX;

선언을 해 주어야 한다.

실행결과: [main 에서] GX = 12345 [f 에서] GX = 12345 [g 에서] GX = 12345

Page 31: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

31

외부변수란 무엇인가요?

아주 오랜 옛날… 초창기 C에서는 함수 밖에 있는 변수를 모두 '외부변수(external

variable)'라고 했습니다.

그래서 아직도 다음과 같이 선언할 수 있습니다. int main()

{

extern int GX;

printf("GX = %d\n", GX);

}

그러나 지금은… 다른 파일에 정의된 변수를 외부변수라고 하는 것이 보통입니다.

즉, extern 선언이 꼭 필요한 경우에 extern으로 선언된 변수를 외부변수라고 합니다.

Page 32: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

32

파일범위 변수

함수 밖에 선언된 변수 중 static으로 선언된 변수

파일범위 변수는 전역변수와는 달리 다른 파일에서는 볼 수 없음

nonlocal1.c nonlocal2.c 볼 수 있음

볼 수 없음

Page 33: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

33

여러 파일로 구성된 프로그램 빌드

MSVC IDE에서… FileView 탭에서 Source Files 폴더모양을 마우스 우측버튼으로 클릭한 후 "Add Files to Folder…" 선택

Page 34: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

34

비지역 변수를 통한 데이터 전달

가능하다. 하지만…

비지역 변수를 통해 데이터를 전달하면 데이터를 전달하는 함수와 데이터를 전달받는 함수 외의 함수도 그 데이터를 볼 수 있음

불필요한 의존성(dependency)이 발생하므로 바람직하지 않음

매개변수를 통해 데이터를 전달하는 것이 바람직함.

'호동' 함수가 '선영' 함수에게 사랑을 고백하려면, 칠판에 고백하는 것보다 '선영'의 다이어리에 몰래 써 두는 것이 더 안전하고 로맨틱하다.

Page 35: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

35

지역 정적변수

정적변수(복습)

프로그램이 시작될 때 생성되어 프로그램이 종료될 때까지 지속되는 변수

모든 비지역변수는 정적변수(static variable)임

지역 정적변수 지역변수를 선언할 때, static 키워드를 붙이면 이 변수도 정적변수가 됨

정적변수는 함수 영역이 사라진다고 해도 사라지지 않음

따라서 이전 호출 종료시 저장되어 있던 값을 다음 호출 시 사용할 수 있음

이런 변수를 '역사에 민감한 변수(history sensitive variable)'라고 함

Page 36: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

36

count.c

정적변수 초기화 • 모든 정적변수는 초기화

해야 한다. • 초기화하지 않았을 경우

엔 0으로 초기화 된다.

지역 정적변수 타입이 생략되었으므로 자동으로 int형이다.

호출 사이에 값이 보존된다.

실행결과: count = 1 count = 2 count = 3 count = 4 count = 5

Page 37: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

37

변수 분류

유효범위(scope): 해당 변수를 볼 수 있는 범위

지속시간(lifetime): 변수가 생성과 소멸 사이의 시간

지속시간

유효범위

동적변수

(dynamic variable)

정적변수

(static variable)

지역변수

(local)

함수 본체 내부에

그냥 선언

함수 블록 내부에

static으로 선언

파일범위변수

(file-scope) 선언 불가

함수 외부에

static으로 선언

전역변수

(global) 선언 불가

함수 외부에

그냥 선언

지속시간이 길어짐

유효범위가 넓어짐

Page 38: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

38

8.5 재귀함수

Page 39: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

39

재귀함수

재귀호출(recursive call)

어떤 함수가 종료되지 않은 상황에서 자신을 다시 호출하는 것

재귀함수(recursive function)

재귀호출을 이용하는 함수

재귀적인 그림 Niklaus Wirth, Algorithms + Data Structures = Programs (발췌)

Page 40: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

40

fact.c

계승(factorial) 정의

n ! = n × (n – 1) × … × 1

재귀적인 계승 정의

0 ! = 1

n ! = n × (n – 1) !

실행결과: 자연수를 하나 입력하세요: 10 fact(10) = 3628800 입니다.

재귀호출

Page 41: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

41

8.6 매크로 함수

Page 42: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

42

max.c : 매크로 함수

매크로 함수

인수를 받는 매크로

함수와 유사하지만 실제로 함수는 아님

실행결과: 두 수를 입력하세요. 2 3 MAX(2, 3) = 3

MAX(i, j) 는 전처리기를 거치면 (i > j)? i: j

로 확장된다.

Page 43: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

43

매크로 오류

매크로 오류

매크로 함수는 실제로 함수가 아니므로 예기치 못한 오류를 발생시킬 수 있음

이러한 오류를 매크로 오류(macro anomaly)라고 한다.

매크로 오류 예 int i = 2, j = 3, max = 0;

max = MAX(++i, ++j);

printf("i = %d, j = %d, max = %d\n", i, j, max);

어떤 값이 출력될까?

이유는?

i = 3, j = 5, max = 5

max = (++i > ++j)? ++i: ++j;

Page 44: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

44

Key Point

Page 45: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

45

Key Point 1

프로그래밍에서는 작은 프로그램을 함수라고 한다. 함수는 주로 값을 리턴하기 위해 사용하지만 이 외에도 다른 부수효과를 일으킬 수 있다.

함수 헤더는 함수를 호출하기 위한 방법(호출 인터페이스)을 나타내고 함수 본체는 실제로 함수가 수행되는 방법(구현)을 나타낸다. 함수 헤더에서 인수 자료형과 리턴타입 등의 정보를 알 수 있다.

return 명령어는 함수 결과 값을 리턴하기 위해 사용된다. 리턴 값을 계산하기 위한 수식을 괄호로 묶을 필요는 없지만 괄호로 묶으면 프로그램을 더 이해하기 쉽다.

함수 프로토타입이란 함수 호출 방법만을 기술한 것을 뜻한다. 결국 함수 헤더 부분의 정보만 따로 떼어 내어 부를 때 프로토타입이라고 한다.

함수 선언이란 것은 함수의 프로토타입을 명시하는 것을 뜻한다. 함수에 대해서도 ‘사용전 선언(declaration before use)’ 규칙이 적용되는데, 구체적으로 말해서 함수 f를 사용하기 위해서는 그 전에 미리 f의 정의나 f의 선언이 나타나야 한다.

Page 46: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

46

Key Point 2

값을 리턴하지 않고 부수효과만 일으키는 함수를 프로시저라고 한다. 이에 대하여 항상 값을 리턴하는 함수를 값 리턴 함수라고 한다. C 프로그램에서 프로시저는 void 함수로 나타낸다.

함수와 언어 구성요소와는 유사한 면이 있다. 값 리턴 함수는 연산자에 대응하고 프로시저는 명령어에 대응한다. 따라서 값 리턴 함수는 ‘사용자 정의 연산자’, 프로시저는 ‘사용자 정의 명령어’라고 볼 수 있다.

함수 이름은 함수가 하는 일을 구체적으로 나타낼 수 있도록 작성해야 한다. 여러 단어로 함수 이름을 구성해야 하는 경우에는 밑줄 _을 이용하거나 대소문자를 이용하여 각 단어를 구별한다.

해결해야 할 문제를 하나의 간단한 문장으로 기술하고 문제의 하위 작업을 점진적으로 세분화하여 구현해 나가는 방식을 하향식 프로그래밍이라고 한다.

Page 47: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

47

Key Point 3

return 문은 값을 리턴하는 역할을 할 뿐만 아니라 제어흐름을 넘기는 역할도 수행한다.

함수에 전달되는 값을 인수(argument)라고 하고 인수를 저장하기 위한 변수를 매개변수(parameter)라고 한다. 어떤 경우에는 인수와 매개변수 용어를 뒤섞어 사용하기도 하는데, 이 경우에는 인수를 실인수 또는 실매개변수라고 하고 매개변수를 형식인수 또는 형식매개변수라고 부르기도 한다.

함수 호출 메커니즘은 호출자와 피호출자 사이의 제어흐름과 자료흐름을 관리하는 메커니즘이다. 함수가 호출되고 리턴될 때 제어흐름이 변경된다. 제어흐름이 변경됨에 따라서 피호출자의 데이터 영역이 생성되고 소멸된다.

동적 변수는 프로그램 수행 중에 생성되거나 소멸되는 변수를 말하고 정적 변수는 프로그램 수행 시작 시 생성되었다가 프로그램 종료 시 소멸되는 변수를 말한다. static 표시가 없는 지역변수는 동적 변수이고 전역변수와 파일 범위 변수는 정적 변수이다.

Page 48: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

48

Key Point 4

외부변수를 이용하여 함수들 사이에 데이터를 전달할 수 있다. 그러나 외부변수를 이용하면 함수들 사이의 자료 흐름이 명확하게 드러나지 않고, 함수들 사이에 불필요한 의존성이 발생하므로 이런 방식은 자제하는 것이 좋다.

지역변수를 선언할 때 static 키워드를 붙이면 정적 변수가 된다.

정적 변수에 대한 초기화는 한 번만 수행된다.

Page 49: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

49

Key Point(고급 주제)

재귀함수란 함수 본체를 수행하는 도중에 자신을 다시 호출하는 함수를 말한다.

매크로 인수를 그대로 복사함으로 인해서 발생되는 매크로 함수 오류를 매크로 오류라고 한다. 매크로 오류는 완벽히 제거할 수 없다. 매크로 오류를 방지하려면 일반 함수를 사용해야 한다.

Page 50: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

50

요약(1/4)

함수

함수는 원래 대응관계를 의미한다

프로그래밍에서 함수는 '인수'에 '리턴값'을 대응시키는, 독립된 프로그램을 의미한다

프로그래밍에서 함수는 '부수효과(side effect)'를 발생시킬 수 있으며 리턴값을 돌려주지 않을 수도 있다.

함수 프로토타입

함수 헤더에는 함수 호출에 필요한 정보가 담겨 있다.

함수 헤더 부분만 따로 떼어 선언한 것을 '프로토타입(prototype)'이라고 한다.

함수 프로토타입이 먼저 나타나면 함수를 정의하기 전에 함수 호출 구문을 사용할 수 있다.

Page 51: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

51

요약(2/4)

리턴값에 따른 함수 분류 값을 리턴하는 함수를 '값 반환 함수(value-returning function)'라고 하고

값을 리턴하지 않는 함수를 'void 함수(void function)'이라고 한다.

void 함수는 부수효과에만 의존하는 함수로서 '프로시저(procedure)'라고도 부른다.

하향식 프로그래밍 '전체문제(top)'를 점차 세분화하여 바로 구현할 수 있는 단계까지 기술해 내려가는 프로그래밍 방식을 하향식 프로그래밍(top-down programming)이라고 한다.

함수는 하향식 프로그래밍에 사용되는 기본적인 추상화 장치다.

추상화 중요하지 않은 것을 생략하는 것을 추상화(abstraction)라고 한다.

추상화는 프로그래밍에서 가장 중요한 요소다.

Page 52: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

52

요약(3/4)

함수 호출 메커니즘 함수 호출 및 복귀 시에는 제어흐름이 변경되며 자료흐름이 진행된다.

함수가 호출되면 함수 고유의 데이터 영역이 생성된다.

인수는 실인수 값을 매개변수로 '복사하여' 전달한다.

리턴값은 호출자의 데이터 영역에 '복사하여' 전달한다.

변수의 지속시간과 유효범위 변수를 볼 수 있는 범위를 '유효범위(scope)'라고 하고

변수가 지속되는 시간을 '지속시간(lifetime)'이라고 한다.

변수 분류 유효범위에 따라: 지역변수, 파일범위 변수, 전역변수

지속시간에 따라: 동적변수, 정적변수

파일범위 변수와 지역 정적변수를 선언할 때에는 static 키워드를 사용한다.

Page 53: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

53

요약(4/4)

분리 컴파일

여러 파일로 하나의 프로그램을 작성할 수 있으며,

이 때, 컴파일러는 파일 하나씩 컴파일한 후 링킹한다.

재귀함수

자신을 호출하는 것을 재귀호출(recursion)이라고 하며,

재귀호출을 이용하는 함수를 재귀함수(recursive function)이라고 한다.

매크로 함수

매크로 인수를 이용하여 함수 효과를 내는 매크로를 '매크로 함수(macro function)'라고 부른다.

매크로 함수는 진짜 함수가 아니므로 예기치 않은 오류를 발생시킬 수 있다.

이러한 오류를 '매크로 오류(macro anomaly)'라고 한다.

Page 54: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

54

프로그래밍 실습

Page 55: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

55

▶ 프로그래밍 실습 1

매달 초에 금액 a를 n개월 동안 정기적금에 불입하고자 한다. 정기적금의 이율이 r이라고 할 때 만기 후 원리금 합계를 계산하는 프로그램을 작성하라.

1. 기간이 n일 때 원리금 합계 산출 공식은 다음과 같다. 이 공식을 이용하여 원리금 합계를 산출하는 프로그램을 작성하라.

2. 월초 불입액이 a이고 월이율이 r일 때 1개월 후의 원리금 합계는 a(1+r)이 된다. 다시 2개월 초에 a만큼 불입한다면 2개월 후의 원리금 합계는 (a(1+r) + a)(1+r)이다. 이런 식으로 n 개월만큼 불입액을 계산할 수 있다. 이 방식에 따라서 원리금 합계를 계산하는 프로그램을 작성하라.

Page 56: Part 08 함수 - GWNUcadcam.gwnu.ac.kr/subject/pwc/chap8.pdf함수 내에 있는 변수 함수 내부에서만 볼 수 있음 함수가 호출될 때 생성되므로 동적변수(dynamic

56

▶ 프로그래밍 실습 2

하노이 탑은 다음 그림처럼 원반 n 개로 구성된 탑이다. 첫 번째 막대기에 있는 하노이 탑을 세 번째 막대기로 옮기고자 한다. 원반은 한 번에 하나씩만 옮길 수 있으며 옮기는 과정 중에 작은 원반 위에 큰 원반을 올리면 안 된다.

이 때, 어떻게 원반을 움직여야 하는지 출력하는 프로그램을 작성하라. 막대기 1의 맨 위 원반을 2의 맨 위로 옮기는 것은 다음과 같이 출력한다.

1 -> 2

프로그램은 하노이 탑 높이 n만 입력으로 받고 막대기 1의 높이 n인 하노이 탑을 막대기 3으로 옮기는데 필요한 원반 이동을 출력한다.