-
참조형식과 값형식 차이, 함수 매개변수(in, out, ref)@ 16. 1 ~ 17. 1/C# 2016. 11. 18. 03:05
- 첫째, 참조 기반의 형식(class, interface, delegate)
- 둘째, 값 기반의 형식 (struct, enum)
클래스는 인자 없는 기본 생성자를 만들 수 있음. 구조체는 기본 생성자를 만들 수 없음.(예약됨)
둘다 생성시에
CPoint cpt = new CPoint();
cpt.Print();
SPoint spt = new SPoint();
spt.Print();
이렇게 가능
그러나..이건 안됨..
CPoint cpt; // 객체가 없으므로 말도 않됨!
cpt.x = 1; // 객체가 없는데 헐!
cpt.y = 1; // 객체가 없는데 헐!
cpt.Print();// 객체가 없는데 헐!
SPoint spt; // 변수 선언이 곧 객체 생성이므로 당근 가능!!
spt.x = 5; // 굿!
spt.y = 5; // 굿!
spt.Print();// 굿!
클래스는 참조자(참조 변수)만 생성하고 객체를 생성하지 않아 오류!!
구조체는 변수 선언이 곧 객체 생성이며 모든 멤버 변수 초기화 후 사용할 수 있습니다.
다음은 메모리 그림입니다
cpt는 힙 객체의 참조를 갖는 참조자(참조 변수)이며 spt는 객체 값 자체를 갖는 값 변수입니다. 또 cpt(참조자)는 Main() 함수 블록({})이 종료될 때 변수(참조자)는 바로 사라지지만 cpt가 가리키는 객체는 가비지 컬렉션 대상이 되는 힙 객체입니다. spt는 Main() 함수 블록({})이 종료될 때 변수와 객체(변수가 값 자체)가 모두 바로 사라지는 스택 객체입니다.
2, 메소드 매개변수 한정자(in, out, ref, params)
매개변수는 변수의 사용 목적에 따라 크게 2가지로 나뉩니다.
- 출력 매개변수(out parameter): 서버에서 클라이언트로 값을 전달할 목적으로 사용됩니다.
- 입력 매개변수(in parameter): 클라이언트에서 서버로 값을 전달할 목적으로 사용됩니다.
보통 메소드는 매개변수를 사용하여 입력을 받고 리턴을 사용하여 출력하지만 출력 매개변수를 사용해서도 출력할 수 있습니다.
아래는 리턴과 출력 매개변수를 사용한 값 출력 그림입니다.
C# 문법에서도 입력, 출력 매개변수를 구분하기 위한 키워드를 제공합니다.
입력 매개변수
- 키워드 생략(없음): 입력 매개변수로 사용됩니다.
출력 매개변수
- out : 출력 매개변수로만 사용됩니다.
- ref : 입,출력 매개변수로 사용됩니다.
입,출력 매개변수는 값 형식과 참조 형식이 약간 다르게 동작합니다.
둘째, 출력 매개변수(out)
using System;
namespace NetGong
{
class Program
{
static void Add(int c, int d, out int sum)
{
sum = c + d;
}
static void Main(string[] args)
{
int a=10, b=20;
int n;
Add(a, b, out n);
Console.WriteLine(n);
}
}
}
30
sum은 출력 매개변수(out)로 sum과 n은 같은 메모리 공간의 이름(변수)입니다. sum은 즉 n의 참조입니다. 그러므로 sum이 변경되면 n도 변경됩니다.
셋째, 입,출력 매개변수(ref)
using System;
namespace NetGong
{
class Program
{
static void Increment(ref int num)
{
num++;
}
static void Main(string[] args)
{
int n=10;
Console.WriteLine(n);
Increment(ref n);
Console.WriteLine(n);
}
}
}
10
11입,출력 매개변수 키워드 ref는 out과 동일하게 동작합니다. 단지 다른 점은 꼭 값이 초기화되어 있어야 합니다. 입력으로도 사용하고 출력으로도 사용하기 위한 변수니까요. 만약 초기화되지 않은 변수를 ref 인수로 전달하면 에러가 발생합니다. C#은 이렇게 사용 용도에 대한 명확한 문법을 제공합니다.
그래서 ref 키워드는 Swap()처럼 입력 값을 매개변수로 받아 다시 출력하고자 할 때 사용합니다.
using System;
namespace NetGong
{
class Program
{
static void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
static void Main(string[] args)
{
int n1 = 10, n2 = 20;
Console.WriteLine("{0} {1}", n1, n2);
Swap(ref n1, ref n2);
Console.WriteLine("{0} {1}", n1, n2);
}
}
}
10 20
20 10결과는 간단!
'@ 16. 1 ~ 17. 1 > C#' 카테고리의 다른 글
델리게이트, 이벤트 - 1 (0) 2016.11.18 object 란? boxing unboxing! (0) 2016.11.18 getter setter (0) 2016.11.18 C# 시작2 (0) 2016.11.16 C# 시작 (0) 2016.11.16