본문 바로가기
언어/C++

[C++ 기본 공부정리] 11-2. 함수의 매개변수(parameter), 인수(argument)

by 민-Zero 2019. 12. 8.

공부 내용을 정리하는 목적 이므로 참고용으로만 읽어 주시기 바랍니다.

틀린 부분에 대한 지적은 감사합니다.

함수가 반환 값을 통해 호출한 곳으로 돌아가 값을 돌려주는 것을 확인하였다. 함수를 이용함에 있어 반환값을 통해 값을 돌려주는 것 뿐만 아니라 함수의 기능을 이용하기 위해 함수에게 값을 전달하는것 또한 필요하다.

이때 사용되는 변수가 매개변수(parameter) 와 인수(argument)이다. 두 변수의 차이점을 알아 두자.

 

1. 매개변수와 인수

함수의 매개변수(parameter)는 함수가 정의될때 전달 되는 인수를 함수 내부에서 사용할 수 있도록 하는 변수이다.

함수명(매개변수1, 매개변수2, ..) 로 사용할 수 있으며 , 를 통해 여러 값을 구분한다.

함수의 인수(argument)는 함수를 사용하기 위해 호출할때 함수로 전달하는 값이다. 매개변수가 없는 함수를 정의하였 다면 인수를 전달 하지 않아도 에러가 발생 하지 않는다. 또한 매개변수의 개수와 인수의 개수가 일치해야 에러가 발생하지 않는다.

 

2. 인수 전달 방법

함수를 이용할때 인수에 변수를 통해 값을 전달하게 되면 매개변수가 그 값을 받아 정의된 기능을 수행하고 반환값이 있을경우 호출자에게 돌려준 다음 종료되고 없을 경우 기능만 수행후 종료된다. 이때 함수의 인수에 변수를 통해 값을 전달하는 방법이 3가지 존재한다. 

 

1) 값을 이용한 전달(call by value)

call by value는 포인터 변수를 이용하지 않고 인수를 전달하는 경우 발생한다.

이 경우는 인수를 통해 전달되는 변수가 가지고 있는 값을 함수 내의 매개변수에 값을 복사하여 사용하는 방식이다. 값이 복사되어 사용되기 때문에 함수의 매개변수와 인수로 전달한 변수는 완전히 별개의 변수 이므로 인수로 전달되는 변수의 값에는 전혀 영향을 미치지 않게 된다. 

arg1 에 1 이란 값을 저장한뒤 ChangeValue함수에 인수로 전달한다. 함수가 매개변수를 통해 값을 전달받아 내부에서 10을 더하여 값을 확인 한다. 그런데 맨처음 전달한 1이란 값이 x에 들어간뒤 10을 더해주는 기능을 수행하여도 인수로 전달한 변수의 값이 10을 더한 값으로 변하지 않은 것을 확인할 수 있다.  즉, call by value방식을 사용하여 arg1 변수 자체를 사용한것이 아니라 저장된 값 1을 복사하여 매개변수로 전달하였기 때문에 원본 arg1의 값이 영향을 받지 않는다.

 

장점 및 단점

- 장점은 값을 복사하여 전달하기 때문에 예상치 못한 부작용으로 인해 원본 데이터가 손상, 변경, 제거등의 위험이 없다는 것이다. 단점은 함수가 호출될 때 마다 매번 값을 복사하여야 하기 때문에 함수가 여러번 호출될 경우 많은 비용이 들어 성능 저하의 가능성이 있다.

 

 

2) 참조를 이용한 전달(call by reference)

call by value의 경우 호출자에게 값을 반환하거나 값을 수정하려면 방법이 return값을 이용하는 것 뿐이다. 어떤 경우에는 함수에서 인수를 직접 수정하는 것이 좀더 효율적이고 명확할 수 있다. 이때 사용할 수 있는 방법이 call by reference로 이는 인수를 참조로 전달하여 값의 복사를 통한 전달이 아닌 원본 데이터를 직접 전달하는 방법 이다.

 

call by value와 차이점은 함수의 매개변수가 일반 변수가 아닌 참조 변수로써 &가 붙는것 이외에는 동일하다. 참조를 통해 인수를 전달 받을 경우 값의 복사가 아닌 원본 arg1의 값 자체에 접근하여 기능을 수행 하여 arg1의 값이 함수호출 전후로 바뀌는 것을 확인 할 수 있다. return을 통해 arg1의 값을 변경하지 않고 함수만으로도 값의 수정이 가능하다.

 

물론 값에 직접 접근할 필요는 있지만 예를 들어 읽기전용과 같은 경우에는 데이터의 수정이 이루어 지면 안되므로 call by reference로 원본의 직접접근은 하되 값의 변경은 원하지 않을 수 있다.

함수가 인수의 값을 변경해서는 안 되고 call by value를 사용하면 단점이 너무 부각 되는 경우 const 참조를 시킨다면 값의 변경은 불가능 하면서 원본 데이터의 접근은 가능하게 한다.

const참조를 사용할 경우 위 처럼 변경하면 안되는 데이터에 대해 오류를 보여주어 값을 변경하지 않도록 도와주고 함수가 값을 변경하지 않음을 명시해 주기 때문에 디버깅 할 경우 편리하다.

 

일반 변수 뿐만 아니라 포인터 변수에 대한 참조도 가능하다.

포인터 변수를 참조를 통해 전달할 경우 함수를 이용하여 포인터변수가 가진 주소값을 변경할 수 있다.

 

장점 및 단점

-참조를 사용하여 함수가 인수로 전달할 변수의 원본 데이터에 접근 가능하고 const 참조를 사용하여 함수가 인수의 원본 데이터를 변경하지 않음을 보장할 수 있다. 복사본이 생성되지 않으므로 비용이 적게들어 성능저하 걱정 없이 사용 가능하다. 참조를 통하여 함수에서 매개변수를 통해 여러 값을 반환할 수 있게 된다.

단점은 인수가 변경 되는지 안되는지의 여부는 호출에서 알 수 없기 떄문에 프로그래머가 주의 하지 않으면 값이 변경되는 것을 인식 하지 못하여 의도치 않은 동작이 진행될 수 있다.

 

3) 주소를 이용한 전달(call by address)

인수로 전달되는 변수의 원본 데이터에 직접 접근할 수 있는 또다른 방법으로 call by address가 있다. 인수로 주소를 사용 하기 떄문에 매개변수는 포인터를 사용 한다.

 

함수 내부에서 포인터의 역참조를 통해 원본 데이터에 접근 할 수 있다.  call by address 의 경우 포인터 변수를 사용 하기 때문에 배열을 사용할때 편리하다.

배열의 이름을 인수로 넘겨줄 경우 배열의 주소값이 들어가기 떄문에 배열의 모든 원소에 접근 할 수 있다.

 

포인터를 매개변수로 사용할 경우 원본 데이터에 접근 할 수 있는것 때문에 혼동할수 있는 경우가 존재 하는데, 인수로 포인터 변수를 넘겨줄 때이다. 위의 경우 원본 데이터에 접근 한다는 생각에 SetNull 함수를 호출 할 경우 포인터 변수가 가진 값이 null로 변경 되어 num변수를 가리키지 않게 되었다고 착각 할 수 있지만 그렇지 않다.

인수로 포인터를 전달하면 포인터가 가리키는 주소가 함수의 매개 변수로 복사된다. 즉, 주소라는 값이 call by value로 전달된 것이다. 따라서 함수 매개 변수의 값을 변경하면 복사본만 변경되기 때문에 원래 포인터 인수는 변경되지 않는다. 주소 자체가 call by value를 통한 전달이 되더라도 여전히 그 주소를 역참조하여 인수의 값을 변경할 수 있기 때문에 원본 데이터에 대한 접근이 가능한 것이다.

 

장점 및 단점

- 장점은 함수가 인수의 원본 값을 변경할 수 있고 인수의 복사본이 생성되지 않으므로 구조체나 클래스와 함께 사용할 경우 빠른 속도가 보장된다.

단점은 포인터를 역참조 할 경우 직접 접근하는 것 보다는 느리며 만약 null값을 역참조 하게 되는 경우 프로그램이 강제종료 되므로 null값이 존재한는지 점검 해야한다.

댓글