4교시
// 레퍼런스문법총정리
// 1. 개념: 기존메모리에대한별명.
int main()
{
        int  n = 10;
        int* p = &n;
        int& r = n;            //
        r = 20;
        cout << n << endl;     // 20
        int& r2;               // ? Error. 반드시초기화되어야한다.
        //----------------------------------------------------
        int*& rp = p;  // ok. 포인터의별명
        int&* pr = r;  // 별명의주소?  error
}
 
// 2. 원리: 내부적으로대부분의컴파일러는포인터를사용한다.
//         "자동으로역참조되는포인터" 라고도부른다.
void inc1( int x )     { ++x; }
void inc2( int* p )    { ++(*p); }
void inc3( int& r ) { ++r; }
void main()
{
        int a = 10;
        int b = 10;
        int c = 10;
        inc1( a );             // 실패- call by value
        inc2( &b );            // ok. call by pointer
        inc3( c );             // ok. call by reference int &r = c;
        cout << a << endl;     // 10
        cout << b << endl;     // 11
        cout << c << endl;     // 11
}
 
// 3. 함수호출과레퍼런스
// 인자값을변경하는함수-> 포인터가좀더좋다. ( 명확하다. )
// 인자값이바뀌지않은함수
// 1) bulit in type => const T&가오히려나쁘다.(4byte사용, 레지스터사용못함.)
//                     call by value를사용.
// 2) user type     => const T&
struct AAA
{
        int data[10000000];   // 1M라고가정.
};
void foo( const AAA& a )   // call by value :  값을 변경하지 않을것 이다.
{                          // 단점: 메모리 사용량이 2개가 된다.
        a = 20;            // const& : 메모리 사용량을 줄이고 값을 변경하지 않게 한다.
}
void main()
{
        AAA x = 10;
        foo ( x );
        
        cout << x << endl;
}