참조 – 3.참조에 의한 전달

매개변수 전달 방식

값에 의한 전달(call by value)

함수의 매개변수는 기본적으로 값에 의한 전달을 합니다. 이 방식으로 값을 전달하게 되면 함수 내에서 값을 변경하게되면 함수 밖에 있는 값을 변경하는 것을 불가능합니다. 값에 의한 전달은 대입연산자에 의한 할당에서와 마찬가지로 원본의 복사본을 함수 내로 전달하기 때문에 복사본을 아무리 변경해 보았자 원본의 내용은 그대로 남아있기 때문입니다.

참조에 의한 전달(passing by reference 또는 call by reference)

참조에 의한 전달을 하게 되면 원본의 별명을 함수 내로 전달하게 되며 이 별명은 원본의 내용을 그대로 나타내고 있습니다. 따라서 함수 내에서 별명에 의해 수정한 내용이 원본에 그대로 반영되는 것입니다. 따라서 매개변수(원본의 내용)를 수정하려면 참조에 의한 전달 방식을 사용하여야 합니다.

참조에 의한 전달

전달 방법

참조에 의해 함수의 매개변수를 전달하면 이러한 매개변수는 호출측의 사용범위를 갖는 동시에 함수 내에서 사용하는 지역변수로도 사용됩니다. 쉬운 말로 하면 호출측에서 사용하는 원본을 함수 내로 직접 보내는 것입니다. 예를 들어 아래와 같은 예제를 실행하면 $a가 6임을 알 수 있습니다.

이것은 함수 foo 내에 있는 변수 $var이 $a와 동일한 내용을 참조하기 때문입니다. 위에서 보면 함수를 호출할 때는 참조표시(reference sign) &(ampersand)가 없으며 단지 함수를 정의하는 부분에만 참조표시를 하고 있습니다. 이와 같이 함수 정의에서만 참조표시를 하더라도 참조에 의한 전달을 정확히 할 수 있습니다. 때에 따라서는 함수 정의에서 참조표시를 하지 않더라도 함수를 호출할 때 참조표시 &를 첨부하여 호출하면 참조에 의한 매개변수 전달을 할 수 있습니다.

기본적으로는 값에 의한 전달을 하고 특별한 경우에만 참조에 의한 전달을 할 필요가 있는 경우에만 이와 같이 호출측에서 참조표시 &를 붙일 수 있습니다. 그러나 이와 같은 방법은 특별한 이유가 없는 한 좋은 방법은 아닙니다. 함수를 정의할 때 매개변수를 참조로 받을 것인지 아니면 평상시와 같이 복사하여 받을 것인지를 결정하는 것이 바람직합니다.

전달할 수 있는 요소

참조로 전달할 수 있는 요소로는 아래와 같이 “변수”, “new문”, “함수에서 반환되는 참조”가 있습니다.

  • 변수 : foo($a)
  • new문 : foo(new foobar())
  • 함수에서 반환되는 참조 :

전달할 수 없는 요소

위에서 정의된 요소가 아닌, 예를 들어 함수의 반환값이 참조가 아닌 경우, 표현식(expression), 상수를 참조에 의한 매개변수로 전달할 수 없습니다.

참조는 포인터가 아님.

아래와 같은 예에서 여러분은 실행결과 $bar값이 “91”라고 생각할 지 모르겠으나 $bar값은 여전히 “1000”입니다.

foo 함수를 호출하면 foo 함수에 있는 $var은 $bar와 바인딩되어 있습니다. 그러나 이 때 $var이 $GLOBALS[“baz”]와 다시 바인딩할 것입니다. 함수 내에서 참조 메커니즘을 이용하여 호출측 사용범위를 가지고 있는 $bar에 바인딩할 방법이 없습니다. $bar은 함수 foo에서는 사용할 수 없는 변수입니다. $var에 의해 표현되어지기는 하지만 $var은 단지 변수 내용만 가지고 있을 뿐입니다.

scope 변수명 변수값이 저장된
메모리 주소
설명
호출측 $bar 0x6000
$baz 0x7000
함수내 $var 0x6000 매개변수가 참조로 넘어갈 때
0x7000 $var = &$GLOBALS[“baz”]를 실행한 직후

< 심볼 테이블 >

참조에 의한 객체 전달

생성된 객체를 참조로 함수 내로 전달할 수 있습니다. 이 때 참조로 넘기지 않고 값으로 넘기게 되면 최초로 생성된 객체의 복사본을 함수 내로 전달하게 되며 이것은 원본과는 다른 별개의 객체입니다. 이것은 마치 앞장에서 $a = new test에 의해 객체가 복사되는냐 아느면 $a = &new test에 의해 객체가 참조되느냐와 같은 원리입니다.

아래와 같이 new test로 객체를 생성하자 마자 함수로 전달할 수도 있습니다. 이 예만 가지고는 왜 이렇게 코딩하는지 이해가 되지 않을 것입니다. 이는 참조에 의한 반환과 함께 사용될 때 그 효과가 나타나게 됩니다. 그러니 다음장에 있는 참조에 의한 반환을 참조하세요.

$this의 동작 방식

객체 메소드에서 사용하는 $this는 호출측 객체에 대한 참조입니다. 따라서 $this를 가지고 수정한 내용은 호출측 객체의 내용에 그대로 반영됩니다.

$this가 참조가 아니고 복사였다면 echo $a->mb의 결과는 아무 값도 나타나지 않겠지요.

답글 남기기