C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 예제소스
//struct (구조체) 생성
//가비지 컬렉팅의 대상이 아니고
//스택메모리에 할당되는 struct
struct MyStruct
{
//구조체에서는 미리 할당이 안됨. class에서는 됨.
//public int i = 10; //에러 - 구조체에는 인스턴스 필드 이니셜라이저를 사용할 수 없습니다.
public int i;
public int j;
//struct에서도 생성자를 몇가지 조건하에 만들 수있다.
//1. 매개변수가 무조건 있을 것
//2. 생성자 안에서 struct의 변수에 값을 모두 할당할 것
//매개변수가 없는 생성자는 불가
//public MyStruct()
//{
//}
public MyStruct(int num1, int num2) //인자 수가 꼭 변수 수에 맞추는 것은 아니다.
{
i = num1;
j = num2; //하나만 해도 안되고 변수 모두에 값을 할당해야 한다.
}
//함수는 그냥 만들 수 있다.
public void Show()
{
Console.WriteLine("i : {0}, j : {1}", i, j);
}
}
//class생성
class MyClass
{
public int i = 10;
public void Show()
{
Console.WriteLine("MyClass i : {0}", i);
}
public override string ToString()
{
//return base.ToString(); //base는 부모 타입. object
return base.ToString() +"는 i가 " + i + "입니다";
}
public override bool Equals(object obj)
{
//as로 캐스팅
MyClass other = obj as MyClass;
if(other != null)
{
if(other.i == this.i)
{
return true;
}
}
return false;
}
}
static void Func1(object o)
{
MyClass my = o as MyClass;
if(my != null)
{
my.Show();
}
{
Console.WriteLine("MyClass가 아니다." + o.ToString() + "입니다");
}
//메인 함수
static void Main(string[] args)
{
//MyStruct s1; //에러 - 할당 되지 않은 것은 사용 할 수 없다.
//s1.Show();
MyStruct s1 = new MyStruct(); //기본 생성자, 안만들어도 자동으로 있다.
s1.Show();
MyStruct s2; //생성 없이 사용 방법
s2.i = 5; //변수에 모두 값을 할당 한다.
s2.j = 6;
s2.Show(); //그러면 new없이 사용 가능 하다.
MyStruct s3 = new MyStruct(100, 200); //별도의 생성자로 할당
s3.Show();
MyStruct s4 = s2; //class같은 경우는 heap메모리에서
//같은 것을 참조하지만
s2.i++; //struct에서는 값 복사를 한다.(별개로 복사, 깊은 복사)
s2.Show();
s4.Show(); //결과가 다르다
//class 할당
MyClass c1 = new MyClass(); //class는 무조건 new로 heap에 할당
Console.WriteLine(c1.ToString()); //class 는 object 타입을 기본적으로 상속 받는다.
MyClass c2 = new MyClass();
c2.i = 10;
if(c1 == c2) //class는 ==로 비교하면 주소값을 비교 한다.
{
Console.WriteLine("c1과 c2는 같다.");
}
else
{
Console.WriteLine("c1과 c2는 다르다."); //주소값이 다르기 떄문에 false
}
//비교함수 재정의 하여 처리
if (Object.Equals(c1, c2)) //MyClass의 public override bool Equals(object obj) 를 탄다.
{
Console.WriteLine("c1과 c2는 같다."); //i값이 같아서 true
}
else
{
Console.WriteLine("c1과 c2는 다르다.");
}
//object;
//박싱언박싱(Boxing, Unboxing)
//class나 struct나 기본적으로 object class를 상속받고 있어
//object를 인자로 받는 함수에 인자로 들어 갈 수 있다.
Func1(c1); //class는 같은 heap 메모리에서 참조만 넘겨준다.
Func1(s1); //구조체를 object로 받으면 heap에 new 로 새로 생성된다.(본체는 stack에 남아있다.)
//메모리 낭비. 복사체는 가비지컬렉터 기다림.
Object obj = s1; //박싱이 일어남.(stack에 있는 struct가 object 클래스에 들어가야 하므로 Stack에서 Heap으로 모두 복사된다.)
MyStruct s5 = (MyStruct)obj; //언박싱(heap에 있는걸 Stack에 복사한다. 매우 리소스를 까먹으므로 안좋다.)
//int, float같은 기본 형은 다 struct이다.
string str1 = "abc";
string str2 = "abc";
if(str1 == str2)
{
//class 타입은 주소값을 비교한다. 하지만...
//string은 class 타입이지만
//너무 자주 사용되기에 이미 값비교로 override 되어있다.
Console.WriteLine("str1 == str2는 참이다."); //참으로 나온다.
}
else
{
Console.WriteLine("str1 == str2는 거짓이다.");
}
}
'공부 > C#' 카테고리의 다른 글
파일 저장 - FileStream, StreamWriter, WriteAllText, WriteAllLines (0) | 2016.05.12 |
---|---|
컬렉션(Collection), 제네릭 컬렉션(Generic Collection) - 예) ArrayList, List<T> (0) | 2016.05.11 |
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 개념 (0) | 2016.05.11 |
정렬 Array.Sort, Array.Reverse (0) | 2016.05.10 |
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 개념
//c#에서는 struct와 class가 많이 다르다.(c++에서는 거의 동일)
//c#의 메모리 구조
//c++에서는 stack메모리, heap 메모리와 함께 데이터 영역이 별도로 있었다.
//c#에서는 데이터 영여이 stack에 포함된다고 생각하자.
//----------------------------------------------------------------------------
// stack 메모리(데이터 영역 포함)
//----------------------------------------------------------------------------
// 사이즈가 작다.
// struct 선언(new해도 stack이다.)
// 속도가 빠름.
// 지역변수, 함수 파라미터 관리(가비지 커렉터의 대상이 아니다.)
// 복사 시 깊은 복사가 이루어 진다.(값들이 다 새로 할당)
//----------------------------------------------------------------------------
// heap 메모리
//----------------------------------------------------------------------------
// 사이즈가 크다. 램 메모리 그 자체라고 봐도 무방할정도로 크다. (c++에선 동적할당 new 한것들이 들어감)
// class 선언시 할당
// 속도가 좀 느림.
// 복사하면 참조 복사가 된다.
//----------------------------------------------------------------------------
// Boxing, Unboxing(박싱언박싱) - 중요
// stack메모리에서 heap메모리로 넘어가는 것이 Boxing
// heap메모리에서 stack메모리로 넘어가는 것이 UnBoxing
// stack에 있는 것들은 값 형식으로 되어있고(기본 형들( Int, float, double.....)과 enum, struct 등등)
// heap에 있는 것들은 참조 형식이라고 생각하자.(class string array....등등)
'공부 > C#' 카테고리의 다른 글
컬렉션(Collection), 제네릭 컬렉션(Generic Collection) - 예) ArrayList, List<T> (0) | 2016.05.11 |
---|---|
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 예제소스 (0) | 2016.05.11 |
정렬 Array.Sort, Array.Reverse (0) | 2016.05.10 |
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |
랜덤 (0) | 2016.05.09 |
정렬 Array.Sort, Array.Reverse
//정렬 Array.Sort
//int 정렬
int[] intArray = { 1, 40, 34, 23, 56, 53, 87, 85, 32, 10 }; //int 배열
Array.Sort(intArray); // 오름 차순으로 정렬 되어 고정(1 10 23 32 34 40 53 56 85 87)
Array.Reverse(intArray); // 역정렬 되어 고정(87 85 56 53 40 34 32 23 10 1)
//--------------------------------------------------------//
//별도의 class 정렬
class Pistol : IComparable<Pistol> //Sort를 하려면 IComparable<T>가 있어야 한다. Interface 이다.
{
public int damage = 1; //데미지 변수
public Pistol(int power) //생성자
{
damage = power;
}
//IComparable<T> 를 상속받고 비교하는 함수를 만든다.
public int CompareTo(Pistol other)//인자는 T값(템플릿)
{
//데미지 별로 정렬 하겠다.
//Sort할 때 앞으로 갈껀 -1, 뒤는 1, 같으면 0
if(this.damage < other.damage)
{
//쟈기가 적으면 앞으로
return -1;
}
else if(this.damage > other.damage)
{
//쟈기가 크면 뒤로
return 1;
}
//같으면 0
return 0;
}
}
//main에서........
Pistol[] guns = new Pistol[10]; //class 배열 공간 생성
//랜덤객체 생성
Random random = new Random();
for (int i = 0; i < guns.Length; ++i )
{
//데미지 랜덤 생성
guns[i] = new Pistol(random.Next(100) + 1);
}
Array.Sort(guns); //class 배열 정렬 가능
'공부 > C#' 카테고리의 다른 글
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 예제소스 (0) | 2016.05.11 |
---|---|
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 개념 (0) | 2016.05.11 |
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |
랜덤 (0) | 2016.05.09 |
함수인자 ref, out (0) | 2016.05.09 |
추상 클래스, 추상 함수(abstract), 인터페이스(interface)
//추상 클래스, 추상 함수(abstract)
abstract class Gun
{
public int damage = 1; //변수 지정 가능
public int ammo = 5;
//virtual public void Fire() = 0; //c++에서의 순수가상함수. 자식이 무조건 오버라이드해야 하는 함수.
public abstract void Fire(); //추상 함수를 가지면 class도 추상 클래스 여야 함. 자식이 무조건 오버라이드 해야함.
}
//인터페이스(interface)
interface IReload //순수가상함수만 가지는 class 비스무리한 거...
{
//함수만 가능하다. abstract class와는 다르게 변수는 들어갈 수 없다.
//int i = 0; //에러 - 인터페이스는 필드를 포함할 수 없습니다.
void Reload(); //일반 함수는 접근 제한자가 없으면 private였으나
//interface는 무조건 public 이다.
//void Reload(){}; //구현부가 있으면 안된다.
}
//테스트용 interface1
interface IScope
{
void Aim();
}
//테스트용 interface2
interface IAim
{
void Aim();
}
//class에서 상속 받음
class Pistol : Gun, IReload, IScope, IAim //class상속은 무조건 1개만 되지만, interface는 다중 상속 가능(정부 순수 가상 함수이기에...)
{
public Pistol() //생성자
{
damage = 1;
}
public Pistol(int power) //생성자 인자1개
{
damage = power;
}
//가상함수 오버라이드
public override void Fire() //class Gun 에 있는 virtual함수
{
ammo -= 1;
Console.WriteLine("탕. {0}의 데미지", damage);
}
//인터페이스 함수 구현은 override를 안해도 된다.
public void Reload() //interface IReload 에 있는 순수 가상 함수이다.
{
ammo = 10;
Console.WriteLine("장전 완료. ammo : {0}", ammo);
}
//interface IScope와 IAim에 둘다 Aim()함수가 있다.
//아래 함수 자체로도 에러는 안난다. 어짜피 둘 다 추상 함수(순수 가상 함수)이므로..
public void Aim()
{
Console.WriteLine("조준");
}
//하지만 나눠 사용할 경우가 있다.
//아래처럼 인터페이스 명을 앞에 붙여 쓰면 된다.
void IAim.Aim() //public은 안쓴다.
{
Console.WriteLine("그냥 조준");
}
void IScope.Aim()
{
Console.WriteLine("조준경으로 조준");
}
}
//main class
class Program
{
static void Main(string[] args)
{
Pistol myGun = new Pistol(5);
myGun.Fire();
myGun.Reload();
myGun.Aim();
IScope scope = myGun as IScope; //요런 캐스팅이 되는 작업은 느리므로 자주 안하는 것이 좋다.
//myGun 이 IScope를 상속 받았으면 scope에 myGun이 들어간다. 아니면 null.
if(scope != null)
{
scope.Aim();
}
Pistol bigGun1 = new BigGun(5);
bigGun1.QuickFire1();
bigGun1.QuickFire2();
BigGun bigGun2 = new BigGun(5);
bigGun2.QuickFire1();
bigGun2.QuickFire2();
bigGun2.QuickFireOld();
IReload reloadable = bigGun1; //캐스팅
reloadable.Reload();
if(reloadable is BigGun)
{
Console.WriteLine("reloadable은 BigGun");
}
}
'공부 > C#' 카테고리의 다른 글
C#에서의 struct(구조체)와 class - 메모리 구조 차이, Boxing, Unboxing 개념 (0) | 2016.05.11 |
---|---|
정렬 Array.Sort, Array.Reverse (0) | 2016.05.10 |
랜덤 (0) | 2016.05.09 |
함수인자 ref, out (0) | 2016.05.09 |
Console Title명, 창 크기 (0) | 2016.05.08 |
//랜덤
Random random = new Random();
int r = random.Next(); //랜덤 int 음수가 아닌 난수
random.Next(10); //지정한 값보다 작은 음수가 아닌 난수. 0~9
random.Next(50, 100); //50~99
random.NextDouble(); //0.0 ~ 1.0
byte[] byteArray = new byte[10];
random.NextBytes(byteArray); //배열에 모두 난수가 들어간다.
'공부 > C#' 카테고리의 다른 글
정렬 Array.Sort, Array.Reverse (0) | 2016.05.10 |
---|---|
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |
함수인자 ref, out (0) | 2016.05.09 |
Console Title명, 창 크기 (0) | 2016.05.08 |
Console 입력 버퍼 검사 (0) | 2016.05.08 |
함수인자 ref, out
// 함수인자 ref, out
static void Main(string[] args)
{
//int num; //불가 -> 참조로 넘기려고 한다면 값이 할당되어있어야 한다.
int num = 10;//class 변수의 경우는 new 되어있거나 ,
//일반형 변수의 경우 값이 최기화되어 들어가 있어야 함.
Test4(ref num); //참조 하는 변수라고 명시
Console.WriteLine("Test4 after : {0}", num); //11
int num2; //out용 변수는 값이 할당되어있지 않아도 된다.
Test5(out num2);
Console.WriteLine("Test5 : {0}", num2); //50
}
/// <summary>
/// ref 테스트
/// </summary>. 파라미터를 참조로 받기
/// <param name="num">참조하게 될 파라메터</param>
static void Test4(ref int num)
{
Console.WriteLine("Test4 : {0}", num);
num++; //원래 값 자체를 변화시킨다.
}
/// <summary>
/// out 출력용 함수
/// </summary>
/// <param name="num">출력값이 될 파라메터</param>
static void Test5(out int num)
{
//num++; //불가 -> 해당 값만 가져오는 거지
//원래 변수 자체를 가져오는 것이 아니라 변화시킬 수 없다.
num = 50; //이 값이 원래 변수의 값이 된다.
}
'공부 > C#' 카테고리의 다른 글
추상 클래스, 추상 함수(abstract), 인터페이스(interface) (0) | 2016.05.09 |
---|---|
랜덤 (0) | 2016.05.09 |
Console Title명, 창 크기 (0) | 2016.05.08 |
Console 입력 버퍼 검사 (0) | 2016.05.08 |
Console 커서 포지션(CursorPosition) (0) | 2016.05.08 |
Console Title명, 창 크기
/*
//c++ 에서는 아래의 같았다.
system("title Son's RPG"); //타이틀 명 수정 "Son's RPG" 을 넣는 것
system("mode con:cols=127 lines=36"); //창크기 127글자, 36글자
*/
//c# 에서는 아래와 같다.
Console.Title = "Son's RPG"; //타이틀 명 수정 "Son's RPG"을 넣는 것
Console.SetWindowSize(127,36); //창크기 127글자, 36글자
//pixel 단위가 아니라 한 글자 크기 단위
'공부 > C#' 카테고리의 다른 글
랜덤 (0) | 2016.05.09 |
---|---|
함수인자 ref, out (0) | 2016.05.09 |
Console 입력 버퍼 검사 (0) | 2016.05.08 |
Console 커서 포지션(CursorPosition) (0) | 2016.05.08 |
class - is , as (0) | 2016.05.08 |
Console 입력 버퍼 검사
//입력이 있을 때까지 While()문 내에 있기 위해
//c++ 에서는 _kbhit()을 사용했었다.
//c#에서는 Console.KeyAvailable 이다.
while (true)
{
//0.5초는 please press anykey 를 보여주고
Console.SetCursorPosition(50, 31);
Console.Write("please press anykey");
System.Threading.Thread.Sleep(500);
if (Console.KeyAvailable) break; //입력 된게 있으면 while문 break;
//0.5초는 비어있게 하고
Console.SetCursorPosition(50, 31);
Console.Write(" ");
System.Threading.Thread.Sleep(500);
if (Console.KeyAvailable) break; //입력 된게 있으면 while문 break;
}
'공부 > C#' 카테고리의 다른 글
함수인자 ref, out (0) | 2016.05.09 |
---|---|
Console Title명, 창 크기 (0) | 2016.05.08 |
Console 커서 포지션(CursorPosition) (0) | 2016.05.08 |
class - is , as (0) | 2016.05.08 |
델리게이트(delegate) - 대리자 (0) | 2016.05.08 |
Console 커서 포지션(CursorPosition)
//Console 커서 포지션 체인지
/*
//c++
COORD pos = { x, y }; //좌표(COORD 는 short 2개를 받는 변수형)
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); // WIN32API 함수
*/
//c#
int left = 14; //x좌표
int top = 5; //y좌표
Console.SetCursorPosition(left , top ); //left 부터 커서의 열, top 부터 커서의 행
'공부 > C#' 카테고리의 다른 글
Console Title명, 창 크기 (0) | 2016.05.08 |
---|---|
Console 입력 버퍼 검사 (0) | 2016.05.08 |
class - is , as (0) | 2016.05.08 |
델리게이트(delegate) - 대리자 (0) | 2016.05.08 |
함수 주석 /// (0) | 2016.05.08 |
class - is , as
//is - 선언된 변수의 class비교 (true, false)
//as - 선언된 변수의 class비교 하여 입력 (대입이 되거나 null )
MyClass mc = new MyClass();
if(mc is MyClass)
{
Console.WriteLine("mc는 MyClass 입니다.");
}
else
{
Console.WriteLine("mc는 MyClass가 아닙니다.");
}
//==========================//
MyClass2 mc22 = new MyClass2();
//mc22가 MyClass2이면 mc33에 들어가고
//아니하면 mc33에 null이 들어간다.
MyClass1 mc33 = mc22 as MyClass2; //MyClass2는 MyClass1을 상속 - 부모나 본인 Class 변수가 아니면 에러
if (mc33 != null)
{
Console.WriteLine("mc33는 MyClass2 입니다.");
}
else
{
Console.WriteLine("mc33는 MyClass2가 아닙니다.");
}
'공부 > C#' 카테고리의 다른 글
Console 입력 버퍼 검사 (0) | 2016.05.08 |
---|---|
Console 커서 포지션(CursorPosition) (0) | 2016.05.08 |
델리게이트(delegate) - 대리자 (0) | 2016.05.08 |
함수 주석 /// (0) | 2016.05.08 |
상속 가상 함수 선언 (0) | 2016.05.08 |