[따배씨++]Chapter7-1. 함수

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모님의 홍정모의 따라하며 배우는 C++ 강의를 듣고 정리한 내용입니다.
공부하는 식빵맘 님의 블로그를 참고했습니다.


🚆 매개변수(Parameter) vs 인자(Argument)

void func(int x, int y) {}; // int x, int y : 매개변수 (paramater)

int main()
{
	func(1, 2);         // 1, 2 는 인자 (argument)
	
	return 0;
}
  • parameter는 함수 끝나면 os로 메모리 반납


🚆 인수 전달

Call by Value

void func(int x)
{
	x = 20;
}

int main()
{
	int a = 0;
	func(a);
	cout << a << endl; // 0 출력
	
	return 0;
}
  • 값이 복사되어 넘어감
  • 함수 내에서 바꿔봐야 함수 끝나면 사라짐


Call by Reference

void func(int& x)
{
	x = 20;
}

int main()
{
	int a = 0;
	func(a);
	cout << a << endl; // 20 출력

	return 0;
}
  • 참조 변수는 메모리 공유
  • 함수 내에서 변경한 값 유효함


포인터 참조

void func(int*& ptr)
{
	cout << ptr << endl;
}

int main()
{
	int x = 5;
	int* ptr_x = &x;
	func(ptr_x);
	
	return 0;
}
  • typedef int* pint 지정하면 조금 덜 햇갈림
  • 함수 내에서 변경한 값 유효함


배열 & 벡터 참조

void func(int (&arr)[4])
{
	for (auto& elements : arr)
		cout << elements << endl;
}

void func(vector<int>& arr)
{
	for (auto& elements : arr)
		cout << elements << endl;
}
  • 배열 참조시 사이즈 지정해줘야 함 (누가 쓰나..?)


call by reference 꿀팁

void getSinCos(double degrees, double& sin_out, double& cos_out)
{
	static const double pi = 3.141592; // 자주 쓰는 값이면 static이 좋음
	double radians = degrees * pi / 180.0;
	sin_out = std::sin(radians);  //  #include <cmath>
	cos_out = std::cos(radians);  //  #include <cmath>
}

int main()
{
	double sin = 0.0, cos = 0.0;

	getSinCos(30.0, sin, cos);

	return 0;
}
  • Reference input을 이용해 여러개의 output 효과를 낼 수 있음!


Call by Address

void func(int* ptr)
{
	*ptr = 100;
}

int main()
{
	int value = 5;
	int* ptr_value = &value;

	func(ptr_value);  // OK
	func(&value);     // OK
	func(5);          // Error

	return 0;
}
  • 주소 자체는 복사하지만 같은 주소를 가리킴
  • 함수 내에서 변경한 값 유효함
  • R-Value는 못 넘어감


🚆 다양한 리턴 값

포인터 리턴

int* allocateMemory(int size)
{
	return new int[size];
}

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

	delete[] my_arr;

	return 0;
}
  • 동적 할당은 함수가 끝나도 사라지지 않음
  • 종종 쓰는 디자인 패턴


주의할 점

int* getValue(int x)
{
	int value = x * 2;
	return &value;
}

int main()
{
	int* value_1 = getValue(3);

	return 0;
}
  • value는 함수가 끝나면 메모리가 사라질 지역 변수
  • 사라질 변수를 de-reference 하면 안 됨
  • 참조 리턴도 마찬가지


int& get(std::array<int, 100>& my_arr, int ix)
{
	return my_arr[ix];
}

int main()
{
	std::array<int, 100> my_arr;
	
	get(my_arr, 30) = 1024;

	return 0;
}
  • 위와 같이 미리 메모리를 잡고 있는 상태에서 함수로 넘기면 괜찮음


구조체 리턴

struct S
{
	int a, b, c, d;
};

S getStruct()  // 이거 inline 함수인가?
{
	S my_s{ 1,2,3,4 };
}

int main()
{
	S my_s = getStruct();
	cout << my_s.b << endl;

	return 0;
}
  • 구조체를 이용하면 여러가지 리턴 값을 받을 수 있음
  • 한 번 쓰고 마는 경우 구조체 만들기 비효율적 → 튜플 이용


튜플(tuple) 리턴

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

	return std::make_tuple(a, d);
}

int main()
{
	std::tuple<int, double> my_tp = getTuple();
	cout << std::get<0>(my_tp) << endl;     // 10 출력
	cout << std::get<1>(my_tp) << endl;     // 3.14 출력

	return 0;
}


🚆 inline 함수

inline int min(int x, int y)
{
	return (x > y) ? x : y;
}

int main()
{
	cout << min(1,3) << endl;
	cout << min(15,30) << endl;

	return 0;
}
  • 함수 앞에 inline 을 선언하면 매크로처럼 작동
inline int min(int x, int y)
{
	return (x > y) ? x : y;
}

int main()
{
	cout << (1 > 3) ? 1 : 3; << endl;
	cout << (15 > 30) ? 15 : 30; << endl;

	return 0;
}
  • 다만 inline은 강제가 아닌 권유
  • 예전에는 최적화를 위해 inline을 사용했다고 하는데 요즘은 컴파일러가 알아서 해준다고 함



맨 위로 이동하기

Cpp 카테고리 내 다른 글 보러가기

댓글 남기기