본문 바로가기
C#

[C#] 참조 매개 변수, ref와 out의 차이점

by RucA 2024. 4. 25.
728x90
반응형

빠르게 진도를 나가서 비동기 프로그래밍이랑 쓰레드 나가고 싶지만, 자꾸 익숙하지 않은 단어와 문법이 보여서 기초를 다 잡고 가야할 것 같아 열심히 처음 보는 단어와 개념을 찾아 정리하고 있다... 이 글은 out이 뭔지 이해하지 못한 과정에서 쓰게 되었다.

 

 

참조 매개 변수 


코드를 작성하다보면, 함수나 메소드로 int형 매개변수를 입력받아 연산 후 입력받은 외부 변수를 초기화 또는 변경할 필요가 생길 경우가 있다. 이를 간편하게 지원하는 것이 바로 참조 매개 변수이다. 그 중 자주 쓰이는 ref와 out을 살펴보고 둘의 쓰임새의 차이점을 살펴본다.

 

  • ref : 메서드 내에서 매개 변수의 원본을 변경(할당)"할 수 있도록" 하는 키워드
    • 메서드를 호출하기 전에 인수를 초기화해야 한다.
    • 매서드는 매개 변수에 새 값을 할당할 수 있으나 강제성은 없다
    • ref 매개 변수의 인수에는 ref 한정자가 포함되어야 한다.
//공식 문서 코드

//메서드 내에서 매개변수 원본 값을 변경한다
void Method(ref int refArgument)
{
    refArgument = refArgument + 44;
}

//원본 변수 : ref 키워드는 원본 변수를 초기화해야 한다
int number = 1;

//ref 한정자를 사용해 메서드 호출 
Method(ref number);

//원본 값이 변경된 것을 확인
Console.WriteLine(number);
// Output: 45

 

  • out : 메서드 내에서 매개 변수의 원본을 변경(할당)"해야만" 하는 키워드
    • 메서드를 호출하기 전에 인수를 초기화할 필요가 없다
    • 매서드는 매개 변수에 값을 할당해야 한다.
    • out 매개 변수의 인수에는 out 한정자가 포함되어야 한다.
//공식 문서 코드

//원본 변수 : out 키워드는 원본 변수를 초기화할 필요가 없다
int initializeInMethod;

//out 한정자를 사용해 메서드 호출
OutArgExample(out initializeInMethod);

//원본이 초기화된 것을 확인
Console.WriteLine(initializeInMethod);     // value is now 44

//메서드 내에서 매개변수 원본 값을 초기화한다
void OutArgExample(out int number)
{
    number = 44;
}

 

ref 키워드는 주로 메서드 연산 도중에 매개 변수의 원본 값을 변경할 수도 있을 때 사용하고, out 키워드는 주로 메서드를 통해 매개 변수의 값을 초기화하려고 할 때 사용한다는 것을 볼 수 있다. 특히 out은 손쉽게 메서드 도중에 매개변수를 초기화할 수 있는 수단이기 때문에, 주로 문자열을 파싱해서 바로 변수를 선언 및 초기화할 때 자주 사용한다. 

 

//공식 문서 코드

//숫자가 담긴 문자열
string numberAsString = "1640";

//문자열을 파싱해 곧바로 number라는 정수형 변수를 선언 및 초기화한다.
if (Int32.TryParse(numberAsString, out int number))
    Console.WriteLine($"Converted '{numberAsString}' to {number}");

//정수로 전환에 실패할 경우 실패함을 출력
else
    Console.WriteLine($"Unable to convert '{numberAsString}'");
    
// 올바르게 파싱된 후 변수를 초기화했음을 확인    
// The example displays the following output:
//       Converted '1640' to 1640

 

위의 예제에서처럼 활용해 사용자의 입력을 받아 곧바로 정수형 변수를 선언 및 초기화해보겠다.

using System;

class Practice
{
    static void Main()
    {
        // 승리 : 1, 무승부 : 0, 패배 : -1
        //        가위  바위  보
        // 컴퓨터 나    0   1   2
        // 가위   0    0   1   -1
        // 바위   1   -1   0    1
        //   보   2    1  -1    0
        int[,] mat = new int[3, 3] {{0,1,-1}, {-1,0,1}, {1,-1,0}};
        
        string[] events = ["가위", "바위", "보"];
        Random random = new Random();
        int randVal = random.Next(3);
        string machine = events[randVal];

        Console.Write("가위[0], 바위[1], 보[2]!: ");
        if (int.TryParse(Console.ReadLine(), out int intInput) && intInput >= 0 && intInput <=2)
        {
            Console.WriteLine($"컴퓨터의 선택 : {machine}");

            if (mat[randVal, intInput] > 0) Console.WriteLine("승리");
            else if (mat[randVal, intInput] < 0) Console.WriteLine("패배");
            else Console.WriteLine("무승부");
        }
        else Console.WriteLine("잘못된 입력 : 반칙패");
    }
}

 

오늘 내가 이 글을 쓰게 된 이유

 

나머지 곁가지는 생략하고, 사용자 입력에 주목해보자.

if (int.TryParse(Console.ReadLine(), out int intInput) && intInput >= 0 && intInput <=2)

 

위의 문장에서 사용자의 입력을 받아, 새로 생성한 정수형 변수을 파싱된 값으로 초기화 한 후 바로 사용할 수 있다. out 키워드를 적절히 사용하는 것으로 몇줄에 걸쳐 작성해야 하는 코드를 직관적이고 간편하게 작성할 수 있다.

728x90
반응형