rueki

다양한 타입의 return 본문

C,C++ 기초 및 자료구조

다양한 타입의 return

륵기 2020. 7. 15. 23:40
728x90
반응형

1. 값을 return 받는 경우

#include <iostream>
using namespace std;


//값을 반환 받는 경우
int getValue(int x)
{
	int value = x * 2;
	return value;
}

int main()
{	
	int value = getValue(3);
	return 0;
}

int 값이 선언되는 즉시 복사된다. 즉, 함수값을 받고 value라는 변수로 바로 저장이되며, 흔히 볼 수 있고 선언하는 방식이다. 그러나 단점으로는 매번 변수가 복사되고 선언이 되는 작업이 진행된다. 

 

2. 주소값으로 return 받는 경우

//포인터함수인 경우에는 주소값으로 return 받으면된다.
int *getValue(int x)
{
	int value = x * 2;
	return &value;
}

int main()
{	
	
	int value = *getValue(3); 
	int *value = getValue(3); 
	int value = &getValue(3);




	return 0;
}

함수를 포인터 함수를 선언했고 return값으로는 주소값을 받는다. 

이는 함수를 포인터로 선언함에 따라 함수 내부의 리턴 값에 대한 주소를 출력하게 되는데 이는 메인 함수에 선언한 것과 같이 여러 방식으로 사용될 수 있으나 문제가 있다.

일단 첫번째 경우에는 값을 받는 쪽에서 dereference를 했는데, 이는 사라질 값에 대해 dereference라는 문제 가능성이 있다. 즉, 요약하자면 포인터함수의 내부에서 선언한 것은 내부에만 존재하고 return을 하게되면 사라지는데 이를 참조하면 문제가 발생할 수가 있다.

그리고 두 번째, value에 포인터를 선언한 경우에는 함수로 인해 return을 받았는데 변수는 사라졌으나 주소 및 메모리만 남아있는 경우가 될 수 있기에 역시 안좋다.

세 번째는 함수 내의 지역변수 주소값을 return 받기 때문에 안 좋다.

 

//주소반환
int* allocateMemory(int size)
{
	return new int[size];
}


int main()
{	
	int* array = allocateMemory(1024);

	delete[] array;
	return 0;
}

 위의 방식도 동일하지만, 이는 배열에 있어서 메모리 할당 관련해서 자주 쓸 수 있다고는 하지만, 여기서 문제는

 배열을 동적할당을 하는데 함수내에서 선언하고 메인함수 내에서 delete를 하면 복잡할 수 있다고 한다.

 

 

 

3. return by reference

//값을 반환 받는 경우
int getValue(int x)
{
	int value = x * 2;
	return value;
}


int main()
{	

	//함수의 value는 반환하고 사라지는데 그것의 reference를 받는 것은 위험
	//메모리가 사라지게 됨
	int &value = getValue(5);
	return 0;
}

함수는 값을 반환받는 함수이지만 main에서는 value에 주소변수로 선언을 했다. 값을 return 받는데 이를 주소 변수에 넣으면, 사라진 값에 대한 reference를 받게 될 수 있기에 사용하지 않는 것이 좋다.

 

 

 

4. 배열 선언

int& get(std::array<int, 100>& my_array, int ix)
{
	// 한 element의 reference 리턴받는다.
	return my_array[ix];
}

int main()
{	
	//메모리 선언, 함수선언 전후 동일하게 메모리 잡혀있음
	std::array<int, 100>  my_array;
	my_array[30] = 10;
	get(my_array, 30) = 1024;
	cout << my_array[30] << endl; //1024
}

 

5. 구조체 사용

struct S {

	int a, b, c, d;

};
S getStrct()
{
	S my_s{ 1,2,3,4 };
}

//함수 선언할때마다 구조체를 선언해야되는 단점이 있음
int main()
{	
	//구조체 통해서 값 여러개 받음
	S my_s = getStrct();
	my_s.b;
}

한번에 여러값을 받기 위해서 구조체를 사용할 수도 있는데 이는 단점으로 값을 받을 함수마다 구조체를 선언해야한다는 단점이 있다.

 

6. 튜플형태

#include <tuple>


std::tuple<int, double> getTuple()
{
	int a = 10;
	double b = 3.14;
	return std::make_tuple(a, b);

}

int main()
{	
	std::tuple<int, double>my_tp = getTuple();
	std::get<0>(my_tp);//a 10
	std::get<1>(my_tp);//d 3.14

}

코드를 보면 쉽게 알 수 있듯이 튜플을 선언하고 그 값을 받을 때 튜플 형태의 함수를 사용해서 값을 받는다.

728x90
반응형
Comments