#include <iostream>
/** 문자열 관련 라이브러리*/
#include <string>
/** C++ 표준 라이브러리 사용합니다. */
using namespace std;
// 값에 의한 호출을 테스트 하기 위해 CallByValue라는 함수를 정의한다.
void CallByValue(int value)
{
// 함수 내부에서 값을 변경하기
value = 20;
cout << "value : " << value << ", address : " << &value << endl;
}
// 주소에 의한 호출을 테스트 하기 위해 CallByAddress라는 함수를 정의한다.
void CallByAddress(int* address)
{
// * : 역참조 연산자, 포인터 변수가 가리키는 실제 값 20을 의미한다.
*address = 20;
cout << "address : " << *address << ", address address : " << address << endl;
}
// 참조에 의한 호출을 테스트 하기 위해 CallByReference라는 함수를 정의한다.
void CallByReference(int& reference)
{
reference = 20;
cout << "reference : " << reference << ", reference address : "<< &reference << endl;
}
// 값을 위한 호출을 테스트 하기 위해 SwapByValue라는 이름의 함수를 정의한다
void SwapByValue(int value1, int value2)
{
int temp = value1;
value1 = value2;
value2 = temp;
cout << "value1 : " << value1 << ", value2 : " << value2 << endl;
}
// 주소에 의한 호출을 테스트 위해 SwapByAddress라는 함수를 정의한다.
void SwapByAddress(int* value1, int* value2)
{
int temp = *value1;
*value1 = *value2;
*value2 = temp;
cout << "value1 : " << *value1 << ", value1 : " << *value2 << endl;
}
// 참조에 의한 호출을 테스트 하기 위해 SwapByReference 함수를 정의
void SwapByReference(int& value1, int& value2)
{
int temp = value1;
value1 = value2;
value2 = temp;
cout << "value1 : " << value1 << ", value1 : " << value2 << endl;
}
int main()
{
// 함수의 매개 변수에 값을 전달하는 방식입니다
// 1. CallByValue : 값을 의한 호출
// 2. CallByAddress : 주소에 의한 호출
// 3. CallByReference : 참조에 의한 호출
// 1. CallByValue :
// 값을 의한 호출로 함수의 매개 변수에 값을 복사해서 넘겨주는 방식이다. 값에 의한 호출이다.
// 함수가 호출될 때 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다. 함수가 종료되면 해당 공간은 사라진다.
// 메모리 공간은 스택(Stack)영역과 힙(heep)영역이 있다.
// 스택 : 함수 호출시 할당되는 메모리 영역이다. 지역변수의 선언으로
// 할당되는 메모리 영역이다. 값에 의한 호출 방식은 전달되는 변수의 값을
// 복사해서 함수의 매개 변수로 전달한다. 복사된 변수의 값은 함수 안에서
// 지역적으로 사용되는 지역 변수의 성격을 가진다.
// 따라서 함수 안에서 매개 변수의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다.
// 2. CallByAddress : 주소에 의한 호출
// CallByAddress와 CallByReference는 결과값이 같다.
// CallByReference는 C++에서 지원한다.
// 3. CallByReference : 참조에 의한 호출
// 함수를 호출할 때 메모리 공간 안에서는 함수를 위한 별도의 공간이 생성된다.
// 함수가 종료되면 해당 공간은 사라진다.
// 참조에 의한 호출은 매개 변수로 전달되는 변수의 레퍼런스(참조)를 전달한다.
// 해당 변수를 계속 가리키게 된다.
// 따라서 함수 안에서 매개 변수의 값이 변경되면, 매개 변수로 전달된 값도 변경된다.
// 값에 의한 호출을 테스트 하기 위해 CallByValue라는 함수를 정의한다.
// 문장 추가
// 함수가 호출되면 int value = intValue3 형태로 값의 복사가 이뤄진다.
// 실제로 intValu3을 대입시키는 것이 아니라 intValue3 변수가 가지는 값을 복사하고
// 임시로 메모리에 저장한 후 그 값을 value에 넣는다. value와 intValue3은 지역 변수로
// 각각 다른 주소값을 가지게 되기 때문에 value값을 변경해도 intValue3변수의 값은 변경되지 않는다.
int intValue3 = 10;
CallByValue(intValue3);
cout << "intValue3 : " << intValue3 << ", intValue3 address : " << &intValue3 << endl;
cout << endl;
// 주소에 의한 호출을 테스트 하기 위해 CallByAddress라는 함수를 정의한다.
// 함수가 호출되면 int* address : &intValue4 의 형태로 intValue4의 주소를 가리키고 있기 때문에
// 역참조 연산자로 intValue4의 주소에 접근을 하고 값을 변경하면 intValue4의 값이 변경되게 된다.
//
int intValue4 = 10;
CallByAddress(&intValue4);
cout << "intValue4 : " << intValue4 << ", intValue4 address : " << &intValue4 << endl;
cout << endl;
// 참조에 의한 호출을 테스트 하기 위해 CallByReference라는 함수를 정의한다.
int intValue5 = 10;
CallByReference(intValue5);
cout << "intValue5 : " << intValue5 << ", intValue5 address : " << &intValue5 << endl;
cout << endl;
// 매개 변수에 값을 전달하더라도 원본 변수의 값을 변경하지 않으려면 CallByValue를 쓴다.
// 메개 변수에 값을 전달하면서 원본 변수의 값을 변경하려면 CallByReference를 쓴다.
// CallByAddress와 CallByReference는 결과 값이 동일하다.
// 값을 위한 호출을 테스트 하기 위해 SwapByValue라는 이름의 함수를 정의한다
// intValue1의 값은 value1에 복사되고 intValue2의 값은 value2에 복사되어 전달하기 때문에
// intValue1과 intValue2의 값이 바뀐것이 아니라 value1 value2의 값만 변경된다.
// CallByValue는 값을 복사해서 전달되기 때문에 함수 외부에 변수가 변결될 가능성이 없다는 특징이 있지만
// 전달해 주는 값이 크다면 넘겨줄 때마다 데이터 복사에 의한 비용손실 문제가 발생하는 단점이 있다.
int intValue6 = 1;
int intValue7 = 2;
SwapByValue(intValue6, intValue7);
cout << "intValue6 : " << intValue6 << ", intValue7 : " << intValue7 << endl;
cout << endl;
// CallByAddress는 주소에 의한 호출로 주소 값을 매개 변수로 전달하는 함수 호출을 말한다.
// 주소에 의한 호출을 테스트 위해 SwapByAddress라는 함수를 정의한다.
// 메모리 주소값을 저장하는 포인터 변수 value1 value2를 매개 변수로 받아와서 value1이
// 가리키는 값과 value2가 가리키는 값을 변경하는 함수이다.
int intValue8 = 1;
int intValue9 = 2;
SwapByAddress(&intValue8, &intValue9);
cout << "intValue8 : " << intValue8 << ", intValue9 : " << intValue9 << endl;
cout << endl;
// 참조에 의한 호출
// 참조에 의한 호출을 테스트 하기 위해 SwapByReference 함수를 정의
int intValue10 = 1;
int intValue11 = 2;
// SwapByReference의 value1은 intValue10을 가리키는 참조자이고, value2는 intValue11을 가리키는 참조자이다.
// 즉, 참조자는 같은 데이터 공간을 가리키는 변수이지만, 이름만 다를 뿐이다
// 참조자 별명, 별칭이라고 볼 수 있다.
SwapByReference(intValue10, intValue11);
cout << "intValue10 : " << intValue10 << ", intValue11 : " << intValue11 << endl;
cout << endl;
}