C++에서 함수의 인자 전달

C언어,C++,함수,인자,function,argument,전달



 함수는 인자(argument)를 통해서 기능 수행에 필요한 값들을 전달 받는다. 또한 함수는 결과값을 반환하는 경우도 있고 반환 값이 없는 함수도 있다. 이렇게 함수와 호출자 사이의 정보 교환은 인자반환값이라는 매개체를 통해서 이루어진다.


  • 인자(argument) : 함수가 값을 받는 매개 변수

  • 반환값(return value) : 함수가 되돌려 주어야 할 수행 결과값


C++ 언어에서 함수 인자 전달 매커니즘을 한 번 살펴보도록 하자.


//호출부
int main() {
   int is = add(ix, 20); //① ix, 20은 실인자
}

//피호출부
int add(int ia, int ib) { //② ia, ib 값은 가인자
   int isum = ia + ib;
   return isum;
}


호출하는 함수의 인자를 실제 값이라는 의미로 실인자라고 하고 호출되는 함수에서는 가인자라고 한다. 실인자와 가인자 사이에 데이터를 넘겨주는 방식은 값에 의한 호출(call-by-value) 방식으로서 실인자의 값이 복사되어 넘겨진다.


 호출되는 함수의 return 명령은 이 함수가 내부적으로 연산을 수행한 후 반환값이 있다면 그 뒤에 반환값을 두게 된다. 반환값이 없다면 return문만 단독으로 사용한다. 입력 인자는 없을 수 도 있고 여러 개일 수 있지만 반환값은 없거나 한 개뿐이다.


 위의 예제에서처럼 호출하는 함수는 반드시 main()함수이어야 되는 것은 아니다. 어떤 함수에서든지 다른 함수를 자유롭게 호출할 수 있다. 심지어 어떤 함수 내부에서 그 함수 자체를 호출할 수도 있으며 이를 재귀 호출(recursive call)이라 한다.


사용자 함수를 작성하여 사용하려면 다음과 같은 단계를 따른다.


  1. 함수의 기능 및 인자, 반환값을 설계한다.

  2. 정해진 형식에 따라 함수를 선언한다.

  3. 함수의 본체 부분을 작성한 후 (정의) 호출하여 사용한다.

  4. 호출하는 쪽의 인자의 개수와 형식 그리고 반환값의 형식이 모두 정의된 대로여야 한다.


 앞에서도 언급했지만 C/C++ 언어의 값에 의한 호출 방식은 호출부와 피호출부의 인자들 사이의 관계에서 값만을 전달하는 방식으로 데이터값을 복사하여 전달한다. 이는 문서를 복사했을 때 복사본을 아무리 수정해도 원본이 변하지 않는 것과 같은 원리이다.


 다음 예를 보자.


//호출부:
int main() {
   int ia = 10, ib = 10, ic;
   ....
   ic = sub(ia, ib); //❶
   ....
   printf(“%d”,ia);
}

//피호출부:
int sub(int ia, int ib) { //❷
   ia -= ib;
   return ia;
}


호출부 ❶에서의 변수 ia, ib와 피호출부 ❷에서의 변수 ia, ib는 변수명은 같으나 저장 공간이 다른 완전히 다른 변수라는 점을 유의해야 한다. sub()함수 내부에서 ia값은 바뀌지만 그렇다고 main()함수 안의 변수 ia가 바뀌는 것은 아니다. 서로 다른 변수이기 때문이다.


호출부에서 반환값을 받을 때도 피호출된 함수에서 반환값이 복사되어 새로운 변수를 통해 전달된다. 즉, return ia; 실행문에 의해서 ia변수의 '값'이 복사되어 호출부의 변수 ic에 전달되는 것이다. 이것이 값에 의한 호출 방식의 동작 원리이다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0015}


Posted by 살레시오
,

 명령어 return은 함수 내부에서 사용되어 함수의 실행을 끝내는 역할을 한다. return 다음에는 반환값이 오기도 하고 void형 함수의 경우는 반환값이 없이 단독으로 사용된다.


  • return; // void형 함수의 종료

  • return 반환값; // 반환값이 있는 함수의 종료 및 결과값 반환


이 명령은 또한 함수 실행 도중에 강제로 수행을 종료하려는 목적으로 사용할 수 있다.


void sayHi() {
 printf("Hi ");
 return;
 printf("all."); //절대 실행되지 않는다.
}


이 예에서 두 번째 printf()함수는 절대로 실행되지 않는다. return명령어에 의해서 함수의 실행이 종료되기 때문이다.


long factorial(long n){
 if (n<0) return -1;
 long lf = 1;
 while(n>1) {
   lf *= n--;
 }
 return lf;
}


이 함수는 만약 인자의 값이 음수라면 -1을 반환하고 바로 종료되어 버린다. 그렇지 않다면 팩토리얼을 구해서 반환한다.


 또 다른 예를 살펴보자. 함수 exec()는 char형을 받아서 char형을 반환한다. main()함수에서는 사용자로부터 숫자를 하나 입력 받아서 cn 변수에 대입한 후 그것을 exec()함수의 인자로 넘겨주면서 호출하도록 되어 있다. ❶줄을 보면 조건 검사를 하기위해서는 exec()함수를 호출해야만 하도록 되어있다. exec()함수 내부에서 보면 만약 입력한 인수가 1,2,3 셋 중 하나가 아니라면 ❷번 줄의 return –1; 명령에 의해서 함수의 수행이 바로 종료되게 된다. 1, 2, 3중 하나라면 해당되는 명령을 수행했다는 표시를 하게 된다. main()함수에서는 이 함수의 반환값이 –1이라면 수행이 제대로 안 되었다고 판단하고 “Execution failed.”라는 메세지를 표시한다. 또한 반환값이 1이라면 정상적으로 명령이 수행되었다고 판단할 수도 있다. 이 예에서와 같이 함수 내에서 return명령을 만나면 그 즉시로 함수는 종료되게 된다.


#include <stdio.h>

char exec(char);

int main(void) {
  char cn;
  printf("1. Turn left.\n");
  printf("2. Turn right.\n");
  printf("3. Stop.\n");
  printf("Command : ");
  scanf("%d", &cn);
  if (exec(cn)==-1) //❶
      printf("Execution Failed.\n");
}

char exec(char ca) {
  if (ca!=1 && ca!=2 && ca!=3)
      return –1; //❷

  switch (ca) {
      case 1:
          printf("Robot turned left.\n");
          break;
      case 2:
          printf("Robot turned right.\n");
          break;
      case 3:
          printf("Robot stopped.\n");
          break;
  }
  return 1;
}


직접 실행해 보고 결과를 확인해 보기 바란다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0026}


Posted by 살레시오
,

 이전 포스트에서는 사용자 정의 함수가 main()함수 이전에 위치하였다. 또 다른 예를 들어보자.


double getArea(double dr) { //반지름으로 원의 면적을 구하는 함수
   double dArea = 3.14*dr*dr;
   return dArea;
}

int main() {
   double da = getArea(5.0);
}


하지만 C++ 프로그램은 관례적으로 main()함수를 다른 함수들보다 위에 위치시킨다. 맨 먼저 실행되는 함수이기도 하지만 이렇게 배치해야 다른 함수들과 호출 순서나 상관 관계를 파악하기 쉽다.


  하지만 다음과 같이 단순히 순서를 바꾸기만 해서는 문제가 생긴다.


int main() {
   double da = getArea(5.0); //문제 발생
}

double getArea(double dr) {
   double dArea = 3.14*dr*dr;
   return dArea;
}


왜냐면 컴파일을 수행할 때 main()함수 내부의 함수 호출 getArea() 을 처리하는 시점에서 이 함수에 대한 어떠한 정보도 없기 때문이다. 이렇게 하면 컴파일러는 오류를 발생시킨다.


 이런 경우 함수에 기본적인 정보를 주는 부분이 main()함수 위에 와야 하는데 이것을 ‘함수의 선언’ 이라고 한다. 함수의 선언은 함수 정의부에서 본체를 제외한 첫 줄만 따로 적어주면 된다.

  

double getArea(double dr); //함수의 선언

int main() {
   double da = getArea(5.0);
}

double getArea(double dr) { //함수의 정의 (본체 포함)
   double dArea = 3.14*dr*dr;
   return dArea;
}


이렇게 하면 컴파일시에 오류를 발생시키지 않는다. 이와 같이 함수의 정의가 호출하는 부분보다 뒤에 온다면 반드시 함수의 선언이 선행되어야 한다.


실행 가능한 전체 프로그램을 다음과 같다.


#include <stdio.h>
double getArea(double);

int main(int argc, char **argv) {
   double da = getArea(5.0);
   printf("Area: %f", da);
}

double getArea(double dr) {
   double dArea = 3.14 * dr * dr;
   return dArea;
}
//실행결과
78.500000


함수의 선언과 정의의 차이점을 다시 한 번 살펴보자.


  • 정의(definition) : 사용자가 만든 함수의 본체 부분까지 실제로 구현된다. 따라서 컴파일러가 함수 본체를 저장할 메모리를 당연히 확보하고 호출부보다 먼저 위치한다면 선언과 겸할 수 있다.


  • 선언(declaration) : 컴파일러에게 사용자가 만든 함수의 인자와 반환 자료형을 미리 알려준다. 컴파일러가 본체를 위한 메모리를 확보하지는 않는다 선언은 정의를 겸할 수 없다.


 함수의 선언에서 인자의 변수명은 생략할 수 있으나 인자의 자료형을 반드시 명시해주어야 한다. 다음 예를 보자.


#include <stdio.h>

int add(int, int);

int main() {
  int ia = 100, ib=150;
  int isum1, isum2;
  isum1 = add(10,20);
  isum2 = add(ia, ib);
  add(10, isum1);
  printf("%d, %d\n", isum1, isum2);
}

int add(int ix, int iy) {
  return ix+iy;
}

실행결과

30, 250


이 예제에서 함수 add()의 선언에서 인자의 변수명을 생략했음을 알 수 있다. 이렇게 해도 문법적으로 오류가 발생하지 않는다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0014}

'프로그래밍언어.Lib > C,C++' 카테고리의 다른 글

C++에서 함수의 인자 전달  (0) 2015.05.18
C++ 의 return 명령어  (0) 2015.05.18
C++ 사용자 함수(function)의 정의  (0) 2015.05.17
C/C++ 함수(function) 개요  (0) 2015.05.17
C++ 클래스 예제 : Led 클래스  (0) 2015.05.17
Posted by 살레시오
,