함수의 인자 전달 방식

shinyeongwoon·2022년 11월 22일
0

C++

목록 보기
4/10

인자 전달 방식

  • 값에 의한 호출
    함수가 호출되면 매개 변수가 스택에 생성됨
    호출하는 코드에서 값을 넘겨줌
    호출하는 코드에서 넘어온 값이 매개 변수에 복사됨

  • 주소에 의한 호출
    함수의 매개 변수는 포인터 타입 -> 함수가 호출되면 포인터 타입의 매개 변수가 스택에 생성 됨
    호출하는 코드에서 명시적으로 주소를 넘겨줌 -> 기본 타입 변수나 객체의 경우, 주소 전달 배열의 경우, 배열의 이름
    호출하는 코드에서 넘어온 주소 값이 매개 변수에 저장 됨

값에 의한 호출

#include <iostream>
#include <string>

using namespace std;
//해당 매서드에는 return 이 없기 때문에 단순히 지역 변수로만 활용 됨
void swap(int a, int b){
  int tmp;
  tmp = a;
  a = b;
  b = tmp;
}

int main(){

  int m = 2, n = 9;
  //swap 에서 값을 넘겨 줌
  swap(m,n);
  cout << m << n;

}

결과
2 9

주소에 의한 호출

#include <iostream>
#include <string>

using namespace std;
// 매개변수에 포인터 변수 선언
void swap(int *a, int *b){
  int tmp;
  tmp = a;
  a = b;
  b = tmp;
}

int main(){

  int m = 2, n = 9;
  //주소를 인자로 넘김
  // 같은 주소의 값을 수정하므로 Swap이 이뤄짐
  swap(&m,&n);
  cout << m << n;

}

결과
9 2

값에 의한 호출로 객체 전달

  • 함수를 호출하는 쪽(실인수)에서 객체 전달
    객체 이름만 사용
  • 함수의 매개 변수 객체 생성
    매개 변수 객체의 공간이 스택에 할당
    호출하는 쪽의 객체가 매개 변수 객체에 그대로 복사됨
    매개 변수(가인수) 객체의 생성자는 호출되지 않음
  • 함수 종료
    매개 변수 객체의 소멸자 호출
    📌 매개 변수 객체의 생성자 소멸자의 비대칭 실행 구조
    📎 값에 의한 호출 시 매개 변수 객체의 생성자가 실행 되지 않는 이유?
    호출 되는 순간의 실인자 객체 상태를 매개 변수 객체에 그대로 전달하기 위함

#include <iostream>
#include <string>

using namespace std;

class Circle{
private:
  int radius;
public:
  Circle();
  Circle(int r);
  ~Circle();
  double getArea(){
    return 3.14*radius*radius;
  }
  int getRadius(){return radius;}
  void setRadius(int radius){this->radius = radius;}
};

Circle::Circle(){
  radius = 1;
  cout << "생성자 실행" << radius << endl;
}


Circle::Circle(int r){
  this -> radius = r;
  cout << "생성자 실행" << radius << endl;
}


Circle::~Circle(){
  cout << "소멸자 실행" << radius << endl;
}

void increase(Circle c){
  int r = c.getRadius();
  c.setRadius(r+1);
}

int main(){
  Circle waffle(30);
  increase(waffle);
  cout << waffle.getRadius() << endl;  
}

결과
생성자 실행 30
소멸자 실행 31
30
소멸자 실행 30

주소에 의한 호출로 객체 전달

  • 함수 호출 시 객체의 주소만 전달
    함수의 매개 변수는 객체에 대한 포인터 변수로 선언
    함수 호출 시 생성자 소멸자가 실행되지 않는 구조

객체 치환 및 객체 리턴

동일한 클래스 타입의 객체끼리 치환 가능
객체의 모든 데이터가 비트 단위로 복사

Circle c1(5);
Circle c2(30);
//c2 객체를 c1 객체에 비트 단위 복사, c1의 반지름은 30이 됨
c1 = c2; 

치환된 두 객체는 현재 내용물만 같을 뿐 아니라 독립적인 공간 유지

객체 리턴

Circle getCircle(){
 Circle tmp(30);
 return tmp; //객체 tmp return
}

// c의 반지름은 1 : 기본 생성자의 내용이 radius = 1로 되어 있다고 가정
Circle c;
//  tmp 객체의 복사본이 c에 치환. c의 반지름은 30이 됨
c = getCircle();

참조

참조 (reference) : 가리킨다는 뜻 , 이미 존재하는 객체나 변수에 대한 별명

  • 참조 활용
    참조 변수
    참조에 의한 호출
    참조 리턴

참조 변수 선언

  • 참조자 & 도입
  • 이미 존재하는 변수에 대한 다른 이름(별명)을 선언
    참조 변수는 이름만 생기며 참조 변수에 새로운 공간을 할당하지 않는다
    초기화로 지정된 기존 변수를 공유
int n = 2;
// 참조 변수 refn 선언, refn은 n에 대한 별명
int &refn = n;

// n의 값도 3, refn의 값도 3
refn = 3;


Circle circle;
// 참조 변수 refc 선언, refc는 circle 에 대한 별명
Circle &refc = circle;

//circle의 radius도 30, refc의 radius도 30
// 별명일 뿐 같은 공간의 같은 객체 이므로 값이 변경되는 것이 당연
refc.setRadius(30);

refc->setRadius(30)으로 사용 불가

참조에 의한 호출

  • 참조를 가장 많이 활용하는 사례
  • call by reference 라고 부름
  • 함수 형식
    함수의 매개 변수를 참조 타입으로 선언
    참조 매개 변수 (reference parameter)리고 부름 -> 참조 매개변수는 실일자 변수를 참조함
    참조 매개 변수의 이름만 생기고 공간은 생기지 않음
    참조 매개 변수는 실인자 변수 공간 공유
    참조 매개 변수에 대한 조작은 실인자 변수 조작 효과
#include <iostream>
#include <string>

using namespace std;

void swap(int &a, int &b){
  int tmp;

  tmp = a;
  a = b;
  b = tmp;
}

int main(){
  int m = 2, n=9;
  swap(m,n);
  cout << m << n;
}

결과
9 2

참조 리턴

  • C 언어의 함수 리턴
    함수는 반드시 값만 리턴
    기본 타입 값 : int, char, double 등
    포인터 값
  • C++의 함수 리턴
    함수는 값 외에 참조 리턴 가능
    참조 리턴
    변수 등과 같이 현존하는 공간에 대한 참조 리턴
    변수의 값을 리턴하는 것이 아님

값을 리턴하는 함수 vs 참조를 리턴하는 함수

char c = 'a';
// char 리턴
char get(){
	return c;
    // 변수 c의 문자('a') 리턴
}

// a = 'a'가 됨
char a = get();

//컴파일 오류
get () = 'b';
char c ='a';

char& find(){//char 타입의 참조 리턴
	return c; // 변수 c에 대한 참조 리턴
}

char a = find(); // a = 'a'가 됨

char &ref = find(); //ref는 c에 대한 참조

ref = 'M';  // c = 'M'

find() = 'b'; // c = 'b'가 됨

예제 )

#include <iostream>
#include <string>

using namespace std;

char& find(char s[],int index){
  return s[index];
}

int main(){
  char name[] = "Mike";
  cout << name << endl;

  find(name,0) = 'S';
  cout << name << endl;

  char& ref = find(name,2);
  ref = 't';
  cout << name << endl;

}

결과
Mike
Sike
Site

0개의 댓글