9장 부프로그램(Subprogram)
1
목차
• 부프로그램 개념
• 부프로그램 설계시 고려사항
• 매개변수 전달 방법
• 중복 부프로그램
• 포괄형 부프로그램
2
Parameter passing
3
매개변수 전달의 데이터 이동 방법
4
a의 주소
매개변수 전달(parameter passing)의 구현 모델
5
call by-value(값-전달)
• 입력 모드의 구현
– 실 매개변수의 값이 형식 매개변수로 전달 – 형식 매개변수는 지역변수로 사용
– Ex. In C
– return한 결과, 실 매개변수는 영향을 받지 않는다. 6
main() { void swap(int a, int b) { . int temp;
. x temp=a;
x=10; a=b;
y=20; y b=temp;
swap(x, y); } printf( … x, y);
}
10 20
10 20 10
a b temp
20 10
값 전달
• 평가
– 장점:
• 스칼라 변수(값만 존재하는 변수)의 경우 전달 비용과 접근 시간이 효율적
• 부프로그램의 변화로부터 호출 프로그램이 보호를 받는다.
– 단점
• 배열과 같은 구조체의 경우? => 일일이 값을 전달해야 하기 때문에 매우 비효율적
7
call by-result(결과-전달)
• 출력 모드의 구현
– 실 매개변수는 형식 매개변수에 값을 전달하지 않으며, – 형식 매개변수는 지역 변수로 사용되고,
– 피호출자 종료 전에 형식 매개변수의 값을 대응 실 매개변수로 전달
• 예제
8
int main() {
…
sub(x, y);
… }
void sub(int a, int b) {
…
a = 20; b = 30;
20 }
30
x y
결과-전달
• 실 매개변수가 충돌하면? => 매우 위험
9
int main() {
…
sub(x, x);
… }
void sub(int a, int b) {
…
a = 20; b = 30;
}
? x
결과-전달
• 실 매개변수의 주소가 언제 평가되는가?
10
- call 하기 전에 미리 실 매개변수의 주소가 결정되면 관계 없지만, 매우 위험 Index가 sub()
에서 변경되면?
void sub(int k) {
…
index = 5;
} int main()
{
…
index = 2;
sub(list[index]);
… }
index 2
list[2] k
call by-value and result(값-결과-전달)
• 입출력 모드의 구현
– 값-전달과 결과-전달의 혼합
• 실 매개변수는 대응 형식 매개변수로 초기화
• 형식 매개변수는 지역 변수로 사용
• 부프로그램 종료시에 형식 매개변수는 대응 실 매개변수로 전달 – 복사-전달(pass-by-copy)라고 함
• 예제
11
int main() {
…
x = 10; y = 20;
sub(x, y);
… }
void sub(int a, int b) {
…
a = 20; b = 30;
}
10
20
x y
10
20
a b
20
30 30 20
값-결과-전달
• 평가
– 값-전달, 결과-전달의 문제점 공유
12
call by-reference(참조 전달)
• 출력 모드의 구현
– 실 매개변수의 주소가 형식 매개변수로 전달
– 형식 매개변수의 변화가 바로 실 매개변수를 변화시킴 – Ex. In C
13
int main() {
…
x = 10; y = 20;
sub(&x, &y);
… }
void sub(int *a, int *b) {
…
a = 20; b = 30;
}
10
20
x y
x의 주소
a
30 b
20
y의 주소
참조 전달
• 실 매개변수가 충돌 되면? => 매우 위험
14
int main() {
…
x = 10;
sub(&x, &x);
… }
void sub(int *a, int *b) {
…
a = 20; b = 30;
}
x 10 a x의 주소
b
20
x의 주소
30
- side-effect가 발생. 즉 함수 수행의 결과 formal parameter의 변화가 바로 actual parameter에 영향을 줌
참조 전달
• 전역변수가 형식 매개변수로 사용되면? => 매우 위험
15
int global;
int main() {
…
x = 10;
sub(global);
… }
void sub(int a) {
… }
10
global
x
global의
a 주소
- global 변수는 모든 함수에서 공유하는 것.
- sub()를 수행하고 나니 바뀌었다. => side-effect
참조 전달
• 평가
– 출력모드에서는 매우 효과적
– 그러나 side-effect가 발생한다.
16
Test
• 다음 각 매개변수 방법에 대한 프로그램 실행 결과는?
– 값-전달(by-value)
– 참조-전달(by-reference)
– 값-결과-전달(by-value and result) – 이름-전달(by-name)
17
int i;
int a[2];
void p(int x, int y) { x++; i++; y++;}
main() {
a[0] = 1; a[1]= 1;
i = 0;
p(a[i], a[i]);
printf(“%d %d\n”, a[0], a[1]);
return 0;
}
18
1
1
x y
1 1
a[0]
a[1]
2 2
P(): Global:
i 0
main():
1
1) call by-value
Print 결과: a[0] = 1 a[1] = 1
1
1
x y
1 1
a[0]
a[1] 2
2 2
P(): Global:
i 0
main():
1
2) call by-value and result
Print 결과: a[0] = 1 a[1] = 2
a[0]의 주소 a[0의 주소
x y
1 1
a[0]
a[1]
2
P(): Global:
i 0
main():
1
3) call by-reference
Print 결과: a[0] = 3 a[1] = 1
xy 1
1
a[0]
a[1]
2
P(): Global:
i 0
main():
1
4) call by-name : 이름이 대치
Print 결과: a[0] = 3 a[1] = 1
3 3
2
매개변수 전달방법 구현
• 대부분 언어에서 매개변수 전달은 스택 이용
19
sub(w, x, y, z) sub(int a, int b, int c, int d)
값, 결과, 값-결과, 참조
caller: callee:
주요 언어의 매개변수 전달 방법
언어 매개변수 전달 방법
C 디폴트는 값-전달, 참조-전달은? => 포인터 사용
C++ C와 유사, 참조-전달은? => &사용
Java 디폴트는 값-전달, 참조-전달은? => new로 생성한 객체를 파라메터로 넘길때
C# 디폴트는 값-전달, 참조-전달은? => ref 키워드 사용 Ada 3가지 의미적 모델 지원: in, out, inout
Pascal 디폴트는 값-전달, 참조-전달은 var 키워드 사용 Fortran 77 버전 이전: 참조-전달
77 버전 이후: 스칼라 변수에 대해서는 값-결과-전달 Algol W 값-결과-전달
Algol 60 디폴트는 이름-전달, 값-전달은 선택적
20
C와 C++의 call by-reference 비교
in C : call by-reference with pointer in C++ : call by-reference with reference
21
main() { . . x=10;
y=20;
swap(&x, &y);
printf( … x, y);
}
void swap(int *a, int *b) { int temp;
temp=*a;
*a=*b;
*b=temp;
}
main() { . . x=10;
y=20;
swap(x, y);
cout << x << y ; }
void swap(int &a, int &b) { int temp;
temp=a;
a=b;
b=temp;
}
주요 언어의 매개변수 전달 방법
22
// in C++
void fun(const int &p1, int p2, int &p3) {…}
// in Ada
procedure Adder(A: inout integer;
B: in integer;
C: out float) // in Pascal
adder(a, b: integer; var c: integer) // in C#
void sumer (ref int oldSum, int newOne, out res)
…
sumer(ref sum, newValue, out res);
매개변수의 타입 검사
• 실 매개변수의 타입과 대응 형식 매개변수의 타입 과의 일치(consistency) 여부 검사
• 신뢰성을 위해서 매우 중요
23