복사와 참조

이승한·2023년 6월 7일
0

CSharp

목록 보기
2/25

ref 와 out

코드:

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)
        {
            //복사 (가짜) , ref 참조 (진짜)
            int a = 0;
            Program.AddOne(ref a);
            Console.WriteLine(a);
            
            a = Program.AddOne2(a);
            Console.WriteLine(a);

            Console.WriteLine(a);
        }
    }
}

결과:

둘 다 1씩 증가시키는 로직은 똑같은데 어떤 디자인을 선택해서 구현할 지 생각해보면

a = Program.AddOne2(a);
Console.WriteLine(a);
가 훨씬 더 좋다고 할수있는데 첫번째처럼 ref의 참조로 진짜값으로 작업을 하다보면 그냥 값을 테스트하는 경우에는 좋지않기에 두번째 방법으로 작업하는 경우가 좋다.
진짜값으로 하기좋은 경우로는 swap함수처럼 진짜값들을 서로 바꿀때는 용이하다.

out

out 매개 변수를 사용하면 함수에서 꼭 할당을 해야한다.

ref랑 out 둘다 참조값(진짜값)을 넘기는 것

	static void Divide(int a , int b, out int result1,out int result2)
        {
            result1=a / b;
            result2=a % b;

        }

정리

ref와 out은 둘 다 참조 값을 넘기는 것

ref - 기존 변수를 함수에서 수정하려 할 때 사용

out - 함수 내에서 생성된 값을 반환할 때 사용

out은 일반적으로 함수에서 여러개의 결과 값을 생성하는 경우 여러개를 반환할 때 사용

구조체와 클래스

구조체와 클래스에서도 복사와 참조를 볼 수 있는데
예를 들어보면,
구조체로 Mage를 클래스로 Knight를 만들고 간단히 hp만 있다고 가정하고,
Mage와 Knight의 hp를 0으로 만드는 함수를 만들어서 실행해보자

struct Mage
{
	public int hp;
}
class Knight
{
	public int hp;
}
class Program
{
	static void KillMage(Mage mage)
    {
    	mage.hp=0;
    }
    static void KillKnight(Knight knight)
    {
    	knight.hp=0;
    }
	static void Main(string[] args)
    {
    	Mage mage;
        mage.hp =100;
        
        Knight knight = new Knight();
        knight.hp =100;
        
        KillMage(mage);
        KillKnight(knight);
    }
}

결과

mage는 hp가 100이고 Knight는 hp가 0이 된것을 볼수있다.
구조체인 mage는 복사값으로 함수를 처리하여 hp가 100인 반면에
클래스인 Knight는 참조값으로 함수를 처리하여 hp가 0이 될 것이다.

구조체를 ref로 넘겨준다면 참조값으로 처리하여 똑같이 hp가 0이 된다.

0개의 댓글