메소드는 매개 변수를 전달받아 코드에 사용할 수 있습니다. 매개 변수가 전달되는 방식은 두 가지가 있습니다.
- 값에 의한 전달 (pass by value)
- 참조에 의한 전달 (pass by reference)
값에 의한 전달
public static void Swap(int a, int b)
{
int temp = b;
b = a;
a = temp;
Console.WriteLine($"2. a:{a}, b:{b}");
}
static void Main(string[] args)
{
int x = 3;
int y = 4;
Console.WriteLine($"1. x:{x}, y:{y}");
Swap(x, y);
Console.WriteLine($"3. x:{x}, y:{y}");
}
Swap() 메소드는 매개 변수 두 개를 입력받아 서로 값을 바꾸는 메소드입니다. 위 예제를 실행하면 a, b는 값이 바뀌었지만 x, y는 그대로입니다.
메소드가 매개 변수를 전달 받을 때는 데이터의 복사가 이루어집니다. 그렇기 때문에 Main() 메소드 안에 선언된 x, y는 영향이 없습니다. 서로 별개의 메모리 공간을 할당받는 것입니다. 이것을 값에 의한 전달이라고 부릅니다.
참조에 의한 전달
public static void Swap(ref int a, ref int b)
{
int temp = b;
b = a;
a = temp;
Console.WriteLine($"2. a:{a}, b:{b}");
}
static void Main(string[] args)
{
int x = 3;
int y = 4;
Console.WriteLine($"1. x:{x}, y:{y}");
Swap(ref x, ref y);
Console.WriteLine($"3. x:{x}, y:{y}");
}
값에 의한 전달 예제와 비슷한데 매개 변수 앞에 ref 키워드가 추가된 것을 확인할 수 있습니다. 위 코드를 실행하면 변수의 값이 제대로 바뀝니다.
참조에 의한 전달은 매개 변수가 메소드에 넘겨진 변수 본래의 값을 직접 참조합니다. 따라서 원본 변수의 수정이 이루어 집니다.
public unsafe static void Swap(ref int a, ref int b)
{
int temp = b;
b = a;
a = temp;
Console.WriteLine($"2. a:{a}, b:{b}");
fixed (int* pa = &a)
{
Console.Write($"2. &a:{(long)pa:X}, ");
};
fixed (int* pb = &b)
{
Console.WriteLine($"&b:{(long)pb:X}");
};
}
unsafe static void Main(string[] args)
{
int x = 3;
int y = 4;
Console.WriteLine($"1. x:{x}, y:{y}");
int* px = &x;
int* py = &y;
Console.WriteLine($"1. &x:{(long)px:X}, &y:{(long)py:X}");
Swap(ref x, ref y);
Console.WriteLine($"3. x:{x}, y:{y}");
}
출력 결과 1. x:3, y:4 1. &x:CBD757E448, &y:CBD757E440 2. a:4, b:3 2. &a:CBD757E448, &b:CBD757E440 3. x:4, y:3 |
위 예제는 참조에 의한 전달 첫 번째 예제에서 각 변수가 할당되는 메모리 공간의 주소를 출력하는 예제입니다. Main() 메소드에 선언된 변수와 Swap() 메소드가 전달받은 매개 변수의 주소가 같은 것을 확인할 수 있습니다.