본문 바로가기

공부 하기

C#프로그래밍 강좌 따라가기 | 데이터형 (4) - 사용자 지정형

최근 하고 싶은 것도 많고 배우고 싶은 것도 많아서 하루가 아주 짧다. 몇일 야근을 했더니 12시가 넘어서야 공부를 시작하게 된다. 오늘은 19호 태풍이 상륙한다고 하는데 아직 서울까지는 큰 영향을 미치지 않는듯 하다. 내일 출근이 많이 걱정되지만 30분이라도 공부를 하고 자야겠다. 

목차
  1. 데이터형
  2. 변환
  3. 표준입력
  4. 사용자 지정형
  5. 값 형식과 참조 형식
  6. 정리

사용자 지정형은 임의로 데이터형을 만들 수 있는 것으로 말하는 것
struct, enum, class, interface 등 사용자 지정형 부터 객체 지향형에 대한 특징이 조금식 나타나기 시작 

구조체

c/c++ 프로그래밍 언어에서 구조화된 데이터를 처리할때 struct를 사용하는데 이를 구조체라고 한다. 구조화 되었다는 말은 의미가 연결되어 한 덩어리로 처리되는 방식을 의미한다. 
하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것 

형식
    public 은 구조체를 사용하는 권한을 명시 (접근 지정자), private

public struct 구조체명 
{
 // 멤버, 속성, 메서드

구조체 변수의 선언 
    구조체의 정의와 선언을 동시에 / 구조체 정의와 변수의 선언을 각각 


제한 사항1
    구조체에 선언된 const, static 변수만 초기화 가능 

// 구조체 안의 const, static 변수만 선언과 초기화 하는 예
    public struct MyStruct
    {
        public const float PI = 3.14f;
        public const int Age = 12;
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0} {1}", MyStruct.PI, MyStruct.Age);
        }
     }


제한 사항2
    구조체 안에 선언한 생성자는 매개변수가 반드시 있어야함. 

    // 구조체 안에 생성자, 소멸자 명시
    // new로 생성, 일반 선언 했을 때의 초기화
    public struct MyStruct
    {
        public int Age;
        public MyStruct(int InAge)
            // InAge가 매개변수이고 생성과 동시에 초기화 가능
        {
            Age = InAge;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct TestStruct1;
            // 구조체는 값 형식이라 선언만해도 메모리에 생성됨
            TestStruct1.Age = 12;
            // 단 이 경우는 별도로 초기화 하고 있긴 함(옛날방식)
            Console.WriteLine(TestStruct1.Age);
            
            MyStruct TestStruct2 = new MyStruct();
            // 이거처럼 매개변수 없이 쓰면 기본값이 들어감 (기본 생성자 0)
            Console.WriteLine(TestStruct2.Age);
            
            MyStruct TestStruct3 = new MyStruct(12);
            // 이 경우 생성과 동시에 매개변수 넣음
            Console.WriteLine("{0}", TestStruct3.Age);
        }
     }


제한 사항3
    구조체를 같은 구조체에 대입하게 되면 값이 복사됨. 

public struct MyStruct
    {
        public int Age;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct TestStruct1, TestStruct2;
            // 두개의 구조체 생성(값 형식이기 때문에 바로 생성이 가능, 클레스는 이와같이 했을 때 참조 형식이 됨) 
            TestStruct2.Age = 10;
            TestStruct1 = TestStruct2;
            // 값이 복사됨 
            MyStruct test;
            // new 로 생성 하기 위해 선언 
            test = new MyStruct();

            Console.WriteLine("{0}", TestStruct1.Age);
            Console.WriteLine(test.Age);  
        }
     }

제한 사항4
    구조체는 값 형식이고 클래스는 참조 형식임.
    참조는 원래의 이름이 있지만 다른 이름으로 부른다는 의미와 같다고 보면 됨 (포인터의 잔재라고 하는데..)

    public struct MyStruct
    {
        public int Age;
    }
    class MyClass
    {
        public int Age;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct test1 = new MyStruct();
            test1.Age = 12;
            MyStruct test2 = test1;
            test2.Age = 24;
            Console.WriteLine("{0} {1}", test1.Age, test2.Age);
            //new를 통해서 생성했지만 서로 참조형태가 아니라서 각자의 값을 가짐.
            MyClass test3 = new MyClass();
            test3.Age = 12;
            MyClass test4 = test3;
            // 여기에서 대입연산자 = 은 참조형식이 된다.
            test4.Age = 24;
            Console.WriteLine("{0} {1}", test3.Age, test4.Age);
        }
     }


제한 사항 5
    구조체는 값 형식임으로 선언만으로도 사용 가능 
    new를 통해서 생성하면 생성자가 호출됨(없으면 기본생성자 0) 변수가 기본값으로 초기화됨 

public struct MyStruct
    {
        public int Age;
        public float Num2;
        public bool IsReady;
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct test = new MyStruct();
            Console.WriteLine("{0} {1} {2}", test.IsReady, test.Age, test.Num2);
            // 생성자 없이 생성 시 어떻게 초기화가 되는가? False, 0, 0
        }
     }


제한 사항6
    구조체는 구조체 또는 클래스에 상속할 수 없음 
    구조체는 인터페이스를 상속하여 메서드를 구현 할 수 있음 
    // 국어 영어 수학 점수를 구조체 멤버 변수로입력하고
    // Compute() 메서드를 호출하면 평균과 총점이 계산 되도록 프로그래밍
    public struct MyStruct
    {
        public int Kor, Eng, Math, Total;
        public float Average;
        public void Compute()
        {
            Total = Kor + Eng + Math;
            Average = Total / 3.0f;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyStruct Test1 = new MyStruct();
            Test1.Kor = 80;
            Test1.Eng = 90;
            Test1.Math = 88;
            Test1.Compute();

           Console.WriteLine("총점 : {0}  평균 : {1:f1} ", Test1.Total, Test1.Average);            
        }
     }




열거형
상수를 여러개로 열거해 쓰고자 할 때 문자열로 대치하여 선언하는것(상수에 의미를 부여) > 오류를 줄일 수 있음 

형식 
enum 열거형 명칭 {문자열1, 문자열2};
enum 열거형 명칭 {문자열 1 = 상수, 문자열 2 = 상수 };
enum 열거형 명칭 {문자열 1 = 상수, 문자열 2};

열거형의 기본 데이터형은 int 형이지만(4byte) char 형을 제외한 형식 지정을 할 수 있음 
enum Day : byte {Sun = 0, Mon, Tue, Wed, Thu}; 
// 이렇게 하면 4byte가 아니라 1byte로 값을 저장 할 수 있음 

열거형 변수가 아닌 변수에 열거형 값을 대입할 때는 데이터형을 명시해야 함 
(int 형이기 때문에 다른 데이터형에 넣을수도 있음)
    enum Days { sun = 1, Mon, Tue, Wed, Thu, Fri, Sat };
    class Program
    {
        static void Main(string[] args)
        {
            int nValue = (int)Days.Mon;
            //(int) 이게 데이터형 명시
            Days day = Days.Tue;
            // 열거형 변수에 열거형 값을 넣음
            Console.WriteLine("{0} {1}", nValue, day);
        }
     }
    enum Days : byte { sun = 1, Mon, Tue, Wed, Thu, Fri, Sat };
    class Program
    {
        static void Main(string[] args)
        {
            int nValue = (byte)Days.Mon;
            //(byte) 로 데이터형 변경 
            Days day = Days.Tue;
            // 열거형 변수에 열거형 값을 넣음
            Console.WriteLine("{0} {1}", nValue, day);
        }
     }