09. ref, out — 웹툰PD 지망생 : 정민재
09. ref, out
●/섹션 2. 코드의 흐름 제어

09. ref, out

728x90

 

using System;

namespace Csharp
{
    class Program
    {
        //첫 번째 모델
        static void AddOne(ref int number)
        {
            number = number + 1;
        }

        //두 번째 모델
        static int AddOne2(int number)
        {
            return number + 1;
        }

        static void Main(string[] args)
        {
            int a = 0;

            //첫 번째 모델
            AddOne(ref a);
            Console.WriteLine(a);

            //두 번째 모델
            a = AddOne2(a);
            Console.WriteLine(a);
        }
    }
}

1과 2가 나왔다는 건 

 

정상적으로 AddOne함수에서 1이 증가했고,

 

정상적으로 AddOne2함수에서 1이 또 증가했다는 의미

 

그렇다면 두 함수 중에 뭘 써야할까?

 

 

사실, 두 번째 모델이 훨씬 좋은 모델이다.

 

ref 같은 경우, 원본에 값을 영향을 주기 때문에,

 

신경써서, 꼭 써야할 때만 써야하는 문법이다.

 

using System;

namespace Csharp
{
    class Program
    {       
        static void AddOne(ref int number)
        {
            number = number + 1;
        }

        static int AddOne2(int number)
        {
            return number + 1;
        }

        static void Main(string[] args)
        {
            int a = 0;

            AddOne(ref a);
            Console.WriteLine(a);

            //값을 저장만 하는 용도로도 가능
            int b = AddOne2(a);

            //필요하면 저장된 값을 원본에 넣는것도 가능
            a = b;
            Console.WriteLine(a);
        }
    }
}

이 부분은 아직 잘 이해가 안되는데,

 

첫 번째 모델 같은 경우도 void를 int로 바꾸고

 

b에 넣어서 해보니 똑같이 나오는데.. 흠..

 

using System;

namespace Csharp
{
    class Program
    {   
        static void Swap(ref int a, ref int b)
        {
            int temp = a;
            a = b;
            b = temp;
        }

        static void Main(string[] args)
        {
            //복사(짭퉁), 참조(진퉁)ref

            int num1 = 1;
            int num2 = 2;

            Swap(ref num1, ref num2);

            Console.WriteLine(num1);
            Console.WriteLine(num2);
        }
    }
}

이럴 때는, ref를 쓰는게 필수적이다.

 

이런 경우가 아니라면, 

 

일반적으로 return으로 실제값이 아닌 그냥 다른 값을

 

반환 한 다음, 필요에 따라 그 값을 원본에 넣든, 

 

다르게 사용하든 선택을 하면 된다.

 

 

또 다른 문법 Out

using System;

namespace Csharp
{
    class Program
    {
        //out이란 개념도, ref와 같이 참조를 한다는 뜻
        //값을 여러개 반환해야 할 경우, ref 말고 out을 이용
        static void Divide(int a, int b, out int result1, out int result2)
        {
            result1 = a / b;
            result2 = a % b;
        }

        static void Main(string[] args)
        {
            int num1 = 10;
            int num2 = 3;

            int result1;
            int result2;

            //Divide 함수의 매개변수 4개 : 10, 3은 입력값으로, out result1, out result2는 받아오는 값으로
            Divide(10, 3, out result1, out result2);

            Console.WriteLine(result1);
            Console.WriteLine(result2);
        }
    }
}

10 / 3 = 3 * 3 + 1 이므로 

 

몫 = 3

나머지 = 1

 

 

ref vs out

 

안녕하세요,
기능적으로나 성능적으로나 ref vs out은 별다른 차이가 없고,
내부적으로 주소를 참조해서 데이터를 다루게 됩니다. (C++의 포인터와 유사)

다만 이루고자 하는 목적이 다르기 때문에 문법도 2개로 구분이 되는데,
ref의 경우 [함수 외부] <-> [함수 내부] 양방향으로 통신하기 위해서 데이터 참조를 주고 받는 개념이고
out의 경우 [함수 내부]에서 작업한 최종 결과물을 [함수 외부] 쪽으로 넘겨주는 일방적 통행이라 보시면 됩니다.
결과적으로 ref를 사용할 때는 [함수 외부]에서 데이터를 설정하지 않으면 에러가 나고,
out의 경우 [함수 내부]에서 데이터를 설정하지 않으면 에러가 납니다.
추가로 ref를 사용할 때는 [함수 내부]에서 [함수 외부]로부터 전달받은 값을 읽거나 덮어쓰는 행동이 다 가능하지만,
out을 사용할 때는 <결과물을 넘겨주는 용도>로 사용하기 때문에
[함수 외부]에서 무슨 값을 넘겨줬는지 읽는 용도로는 사용이  안됩니다.

TextRPG 전투에서는 실제 Player 정보를 이리저리 ref로 넘겨주면서 서로 원본 Player의 정보를 조작하고 있는데,
이 원본 값은 [함수 내부]에서 정의된 것이 아니기 때문에 out으로 대체할 수는 없습니다.

요약하자면 [함수 내부/외부 사이에 데이터를 빠르게 넘겨주기 위해 사용할 것이냐] 아니면
[그냥 최종 데이터를 함수 외부로 넘겨주기 위한 용도로 사용할 것이냐]를 먼저 구분하면,
자연스럽게 ref/out 중 하나를 고를 수 있게 됩니다.

 

출처
https://www.inflearn.com/questions/30171

728x90

' > 섹션 2. 코드의 흐름 제어' 카테고리의 다른 글

11.연습문제  (0) 2021.07.11
10. 오버로딩  (0) 2021.07.10
08. 함수(ref)  (0) 2021.07.10
07.break, continue(흐름 제어)  (0) 2021.07.10
06. for  (0) 2021.07.10