매개변수 전달 ②
값을 복사하지 않고 넘기면, 무엇을 얻고 무엇을 잃을까?
③ 값-결과 전달 · 인아웃 모드
들어갈 때 한 번, 나올 때 한 번 더
앞 편의 예제를 이어서 봅니다. 값-결과 전달(pass-by-value-result)은 값 전달과 결과 전달을 합친 것입니다. 부를 때 복사해 넣고, 끝날 때 다시 복사해 내보냅니다.
복사 전달(pass-by-copy)이라고도 합니다. a가 자기 칸을 가지므로 두 방식의 단점을 모두 가집니다.
④ 참조 전달 · 인아웃 모드
같은 칸을 가리킵니다
참조 전달(pass-by-reference)은 값이 아니라 접근 경로, 곧 칸의 주소를 넘깁니다. a는 x의 칸을 가리킬 뿐이어서, 안에서 a를 바꾸면 밖의 x가 바로 바뀝니다.
공유 전달(pass-by-sharing)이라고도 합니다. 점선 칸은 값이 아니라 가는 길만 든 자리입니다.
참조 전달의 장단점
복사는 없지만 한 번 더 거칩니다
참조 전달은 복사도 없고 저장 공간도 겹치지 않아 넘기는 과정이 효율적입니다. 대신 형식 매개변수를 쓸 때마다 주소를 거쳐 가서 값 전달보다 느리고, 밖의 변수가 뜻하지 않게 바뀌는 부작용이 생길 수 있습니다.
부작용은 서브프로그램이 자기 밖의 변수를 바꾸는 것입니다(1편).
원치 않는 앨리어스
두 이름이 한 칸을 가리킵니다
두 이름이 같은 칸을 가리키는 것이 앨리어스(alias)입니다. 참조 전달에서 같은 변수를 두 번 넘기면 형식 매개변수 둘이 앨리어스가 되어, 한쪽으로 바꾼 값이 다른 쪽에서도 바뀝니다.
값 10, 20은 예시입니다. i와 j가 같으면 list[i]와 list[j]도 같은 칸입니다.
⑤ 이름 전달 · 인아웃 모드
식을 글자 그대로 끼웁니다
이름 전달(pass-by-name)은 형식 매개변수가 나오는 자리마다 실 매개변수를 글자 그대로 끼워 넣은 것처럼 동작합니다. a = 7은 x = 7이 됩니다.
ALGOL 60이라는 언어에서 도입됐고, 복잡해서 요즘 언어에서는 거의 쓰지 않습니다.
이름 전달의 특징
쓸 그때 계산합니다
끼워진 식은 호출 때가 아니라 쓰는 그때 값이나 칸에 묶입니다. 이 늦은 바인딩이 유연함을 줍니다. 참조 전달이었다면 부를 때의 i로 정해져 list[0]이 바뀝니다.
바인딩은 이름에 값이나 칸을 묶는 일입니다(4강). 구현하려면 부른 쪽에서 보이는 이름들(참조 환경)을 함께 넘겨야 합니다. 예시입니다.
실행 시간 스택
네 방식을 한 호출에 모으면
대부분의 언어에서 매개변수는 실행 시간 스택(run-time stack)을 거쳐 오갑니다. 서브프로그램을 부르면 그 호출이 쓸 칸이 스택에 쌓입니다.
이 강의가 따르는 교재의 예입니다. 참조 전달은 주소 하나만 놓으면 되어 구현이 가장 단순합니다.
다음 편