매개변수 전달 ③

자바에서 객체를 메서드에 넘기면, 복사본이 갈까 원본이 갈까?

C와 C++

기본은 값 전달입니다

C는 값 전달이 기본입니다. 참조 전달이 필요하면 포인터를 매개변수로 써서 주소를 값으로 넘깁니다. C++은 참조 전달을 위해 참조 타입(reference type)이라는 특별한 포인터 타입을 둡니다.

포인터는 칸의 주소를 담는 값입니다. int *p는 p가 포인터라는 선언, int &r은 r이 참조라는 선언입니다. 예시 코드입니다.

자바

값도 복사, 화살표도 복사

자바에서 객체가 아닌 값(기본 타입)은 값 전달이어서 메서드가 밖의 변수를 바꿀 수 없습니다. 객체를 넘기면 객체를 가리키는 참조가 복사되어 안팎이 같은 객체를 가리킵니다. 그래서 객체의 속을 바꾸면 밖에서도 보입니다.

그래서 객체 매개변수는 참조 전달처럼 동작합니다. 객체는 값과 기능을 묶은 덩어리, 메서드는 클래스에 딸린 함수입니다. 값은 예시입니다.

그 밖의 언어

적어서 고르게 한 언어들

전달 방식을 프로그래머가 적어서 고르는 언어가 많습니다. C#은 헤더와 호출문 양쪽에 ref를 붙이면 참조 전달이 됩니다. PHP는 한쪽에만 적어도 됩니다.

대입에 의한 전달은 영어로 pass-by-assignment입니다. 참조는 앞 장에서 본, 객체를 가리키는 화살표입니다. @_는 배열의 이름입니다.

매개변수 타입 검사

넘긴 값의 타입이 맞는가

실 매개변수의 타입이 형식 매개변수와 맞는지 보는 타입 검사는 신뢰성에 매우 중요합니다. 그런데 언어마다 다릅니다.

파이썬과 루비는 변수에 타입이 없고 객체에 타입이 있어 검사할 수 없습니다. 프로토타입은 C의 함수 선언입니다(2편).

다차원 배열 전달

열의 수를 알아야 칸을 찾습니다

행과 열이 있는 배열도 메모리에서는 한 행씩 이어 놓은 한 줄입니다(5강). 칸을 찾으려면 열의 수를 알아야 해서, C와 C++에서는 첫 번째를 뺀 나머지 크기를 형식 매개변수에 적습니다.

따로 컴파일(번역)되는 서브프로그램은 넘어올 배열을 볼 수 없습니다. 3행 4열은 예시입니다.

크기가 달라도 받으려면

크기를 따로 넘기거나, 배열이 알거나

크기를 적으면 그 크기의 배열만 받습니다. C와 C++에서는 배열을 포인터로, 각 차원의 크기를 따로 넘기고 자리 계산을 직접 씁니다. 자바와 C#의 배열은 저마다 길이 length를 가진 객체입니다.

이 계산이 저장 공간 대응 함수(storage mapping function)입니다. rows는 행, cols는 열의 수.

설계 고려 사항

안전이냐, 효율이냐

전달 방식을 고를 때 볼 것은 둘입니다. 효율, 그리고 한 방향으로 넘길지 양방향으로 넘길지입니다. 좋은 프로그래밍은 변수에 닿는 길을 좁히라고 하니 단방향이 낫습니다. 하지만 큰 구조를 넘길 때는 참조 전달이 더 효율적입니다.

막대의 길이는 예시입니다.

다음 편

값 말고 서브프로그램 자체를 넘길 수도 있습니다

8편함수를 값처럼 넘기면? 8강 목록