1. Pass-by-Name ; 참조가 일어날 때마다 주소 계산
(1) inout-mode 파라미터 전송 방식
(2) actual parameter는 서브 프로그램에서 발생하는 모든 formal parameter에 대해 텍스트로 대체됨
(3) pass-by-name 파라미터는 서브 프로그램이 호출될 때 메쏘드에 access하지만,
value나 주소에 대한 actual binding은 formal parameter가 할당되거나 참조될 때까지 delay => late binding
(4) actual parameter의 형식은 pass-by-name 파라미터 방식의 구현을 나타냄
=> passing variable : pass-by-reference
=> passing constant : pass-by-value
=> passing array element ( expression with variable ) : array의 원소 (표현식)의 값은 formal parameter에 대한 각 참조로 변경될 수 있음
procedure BIGSUB ;
integer GLOBAL ;
integer array LIST[1..2] ;
procedure SUB (PARAM) ;
int PARAM ;
begin
PARAM := 3 ;
GLOBAL := GLOBAL + 1 ;
PARAM := 5 ;
end ;
begin
LIST[1] := 2 ;
LIST[2] := 2 ;
GLOBAL := 1 ;
SUB(LIST[GLOBAL]) ;
end ;


(5) Jesen's Devices; 단일 procedure는 다양한 목적으로 쓰일 수 있음
- 표현식과 이 표현식에서 파라미터로 쓰이는 변수들을 서브 프로그램으로 전달
- 파라미터의 변수 중 하나가 서브프로그램에서 변경될 때마다, 이 변화는 표현식의 actual parameter에 상응하는 formal parameter의 나중 발생 값의 변화를 일으킬 수 있음
real procedure SUM (ADDER, INDEX, LENGTH) ;
real ADDER ;
integer INDEX, LENGTH ;
begin
real TEMPSUM ;
TEMPSUM := 0.0 ;
for INDEX := 1 step 1 until LENGTH do
TEMPSUM := TEMPSUM + ADDER ;
SUM := TEMPSUM
end ;




-swapping


swap(x,y);
-> 수행 후 x, y 값
1) value : 변경 x
2) result : 초기화 하지 않았으므로 이상한 값으로 변경
3) value-result : 변경 가능
4) reference : 변경 가능
5) name : 변경 가능 (call by reference)

A[I]의 I는 윗줄에서 바뀐 I의 값이 들어감
2. Parameter-Passing Methods of the Major Languages
(1) C
- Pass-by-value
- Pass-by-reference는 파라미터로 포인터를 사용
(2) C++
- reference type이라 불리는 포인터 타입으로 pass-by-reference 사용
(3) Java
- 모든 파마미터는 pass by value로 전달됨 (inmode)
- Object 파라미터는 pass by reference
(4) Fortran 95+
- 파라미터는 in, out, inout 모드로 선언될 수 있음
(5) C#
- Default method : pass-by-value
- Pass-by-reference는 formal parameter와 actual paramter 앞에 "ref"를 붙여서 지정됨
(6) Pascal and Modula-2
- default parameter-passing method : pass-by-value
- pass-by-reference는 var를 사용하여 formal parameter의 머리말을 지정하여 사용

-Ada

- Python
pass-by-assignment를 사용 -> 모든 데이터 값은 object, 따라서 pass-by-object나 pass-by-reference
actual parameter는 formal parameter로 할당됨

main에서 스택에 a의 영역이 할당되고 heap 영역에 a에 들어갈 리스트의 데이터 값을 넣어줌
sub 함수 영역에서 x의 영역이 할당되고 이 x는 sub(a)에서 a를 받아오므로 heap 영역에 있는 a의 데이터 값의 주소를 가리킴
하지만 sub 함수에서 x를 다시 [7,6]의 데이터를 넣어주므로 x는 [3,7,9]를 가리키지 않고 [7,6]을 가리키게 됨
즉 a는 그대로 [3,7,9]를 가리키고 있지만 x는 다른 값을 가리키게 됨


파이썬에서 변수는 메모리에서 위치에 대해 alias를 하지 않음
대신 단순하게 파이썬 object에 바인딩
- Call-by-Object를 사용 / Call by Object Reference / Call by Sharing
: int, strings, tuples와 같은 변하지 않는 인자를 전달할 경우, Call-by-value와 같음
-> Object reference는 함수의 파라미터로 전달됨
-> 함수 내에서도 변경할 수 없음
: 변경이 가능한 인자를 넘길 경우, object reference에 의해 전달되지만 함수 내에서 변경 가능
-> 만약 함수로 리스트를 넘길 경우, 2가지 경우 생각
1. 리스트의 원소가 변경 가능할 경우, 즉, 리스트가 caller의 영역에서 변경이 가능한 경우
2. 이름에 새로운 리스트가 할당되었을 경우, 오래된 리스트는 영향을 받지 않음. 즉, caller 영역의 리스트는 그대로 유지됨
- 파이썬은 처음엔 call-by-reference로 수행되지만, 변수의 값을 변경하자마자 파이썬은 call-by-value로 수행됨
def ref_demo(x):
print "x=",x," id=",id(x)
x=42
print "x=",x," id=",id(x)

기존의 x의 주소는 변경되지 않고 ref_demo 안의 x의 주소가 42의 주소를 가리키게 됨

callee에서 포인터 자체를 변경할 수 없음
fib 변경되지 않음

callee에서 포인터 안의 내용은 수정할 수 있음
- 파이썬의 변수들은 메모리의 object들을 참조하는 것과 같음
- container와 user-defined type은 변경할 수 있음
- 변경 불가한 object
-> 생성 후 state가 수정될 수 없음
-> Numeric types(int, float, complex), string, tuple, frozen set, bytes
- 변경 가능한 obejcts
-> list, dict, set, byte array

I는 변경 가능하지만, s, a는 변경 불가

- 파이썬이 불변의 object에서 사용될 때 (a +=1 / s += 'qwertz')
-> 새로운 객체를 생성하고 변수가 그 객체를 포인트하도록 함
- 그러나 변할 수 있는 object 일 경우 ( I += [1,2,3] ) , 변수에 의해 포인트된 object는 변할 수 있음

- Variable Length Arguments
: "*"은 파이썬에서 인자의 변경 가능한 개수를 정의, *은 파라미터 리스트에서 변수 앞에 위치



'PL' 카테고리의 다른 글
| [PL] CH10. Implementing Subprograms (0) | 2022.05.24 |
|---|---|
| [PL] CH9. Subprograms (Module) (3) (0) | 2022.05.19 |
| [PL] CH9. Subprograms (Module) (0) | 2022.05.10 |
| [PL] CH8. Statement-Level Control Structures (2) (0) | 2022.05.10 |
| [PL] CH8. Statement-Level Control Structures (0) | 2022.05.03 |