프로그래밍 언어 - C# (1) 자료형과 변수, 그리고 상수

이형눈이이상해
이형눈이이상해
∙∙조회 5

1. 자료형

1.1. 이진법

  • 0, 1로만 이루어진 숫자.
  • CPU는 이진법(0과 1로 표기)을 쓰는 것이 사람과의 약속인 셈. 전원 마크(⏻)의 기원.

1.2. 게임에서의 자료형

<데이터가 모이면 캐릭터를 만든다>

  • 데이터들은 보통 숫자로 구성이 된다.
  • 다양한 유형의 데이터들이 모여 필요한 정보를 제공하고 프로그램이 구동한다.
  • 데이터 타입이나 자료형 유형에서 자유로운 프로그래밍 언어도 존재는 하지만 C#은 알려줘야만 한다.

1.3. 값 형식과 참조 형식

  • C#에서 자료형을 나눌 때의 2가지 큰 갈래이다.
  • 간단히 말하자면 데이터 유형을 다룬다.
  • CPU에서는 다양한 종류 데이터를 다룰 수 있는지 살필 필요가 있다.
  • CPU는 이진법으로 굴러가고 특정 회로에 전기 신호가 있는지 없는지 데이터 종합해서 판단한다.
  • 데이터 타입은 몇자리씩 끊어 읽을까의 규약이다.
  • 그래서 byte, bit의 개념을 알고 있어야 한다.
  • bit는 0 혹은 1 한자리를 의미. CPU가 처리할 수 있는 최소 단위.
  • binary digit의 약자이다.
  • 참, 거짓 여부를 알 수 있는 정도.
  • bit이 한 자리씩 늘어났을 때 2배씩 증가한다.
  • bit이 8개 모인 것이 1 byte이다.
  • 프로그래밍을 할 때, 일반적으로 byte 단위부터 시작이다.
  • 숫자 데이터는 몇 바이트인지 직결될 수 있다.
  • Word라는 용어는 win32에서 출범한 용어이다.
  • 기존에는 한 번에 32자리만 가능해서 메모리가 4G(32 bit)가 한계임.
  • 아무튼 다시 돌아와서 데이터 타입 종류는 많다. 각 자료형 별로 byte 단위가 각각 존재.
  • 크기를 논할 수 있고 보통 byte 단위로 표기
  • 몇 자리씩 읽으라고 CPU에 명령하는 것이 값 형식인 셈.

2. 자료형 형식

2.1. 정수형

  • int라고 하며 크기는 4 byte.
  • 보통 재화, 레벨, HP, MP 등에 쓰이며 가장 많이 쓰게 될 단위다.
  • 정수라는 것이 표기에 따라 다양하게 존재함.
  • 표기할 수 있는 단위가 -21억 ~ 21억까지.
  • 하지만 현재는 게임에서 감당할 수 없는 한도이므로 long이라는 단위까지 출범하게 된다.
  • uint는 unsigned라고 해서 부호가 없으므로 42억까지.

2.2. 실수형

  • float를 쓴다.
  • 정밀도에 따라 double, decimal까지 갈 수도 있다.
  • 기본 크기는 4 byte. 정밀도에 따라 크기가 2배씩 증가.

3. 문자형과 논리형

3.1. 문자형

  • 한 글자의 문자를 다루는 단위는 char이다.
  • 문자형의 경우는 한 글자만 넣는 경우가 존재.
  • 그런데 한 글자만 하는 것이 아니다. 그래서 char가 쭉 늘어진 것을 문자열이다.
  • 문자열을 가리키는 타입의 이름은 string이다.
  • 작은 따옴표 안에는 글자 하나가 들어가고 큰 따옴표 안에 들어가면 문자열로 판단할 수 있다. 이것에 대한 구분은 해야 함.

3.2. 논리형

  • 참, 거짓을 나타내주는 것을 bool형 타입이다.

4. 콘솔 작성

4.1. 주석

  • // 를 통해 적었을 때, 실행해도 출력되지 않는다. 이렇게 적는 것을 주석이라고 부른다.
  • 주석은 프로그램 명령어로써 쓰이지 않는다.
  • 프로그램이 인식하지 못하는 주석을 쓰는 이유는 사람이 보기 위해서이다.
  • 하지만 코드 자체를 보고도 쓰게끔 만드는 것이 베스트이므로 주석이 남용되어서는 안된다.

4.2. 콘솔

  • 검은색 배경의 창을 콘솔이라고 부른다.
  • 보통은 텍스트만 출력한다.
  • WriteLine이 아닌 Write만 썼을 때는 한 줄에 다 출력된다.

5. 변수

5.1. 개요

  • 하나의 값에 대한 데이터 이름을 지어주는 것을 뜻함.
  • 변수명은 직관적으로 알아보기 쉽게 만들어야 한다.
  • 물론 데이터나 변수명은 얼마든지 변화시킬 수 있다.

5.2. 선언과 대입

  • 변수는 크게 '선언'과 '대입'하는 과정을 겪는다.
  • 펜만 담을 수 있는 상자를 지정시키는 것이 선언.
  • 펜을 담는 것이 대입.
    csharp
    using System;
    
    class Program
    {
        static void Main(string[] args)
        {
            // 선언
            int nNumber;
            // 대입
            nNumber = 15;
        }
    }
    
  • 선언만 한 상태에서 대입이 일어나는 것을 '초기화'라고 부른다.
  • 이렇듯 변수에 담긴 데이터는 바꿀 수 있게 된다.
  • 변수는 하나의 값을 담을 수 있다.

5.3. 변수에서 지켜야 할 것

  • 문법을 지켜서 선언을 해야 변수가 제대로 작동한다.
  • 선언과 동시에 초기화를 진행하고자 한다면 (type) (name) = (value); 가 되는 셈이다.
  • 그런데 int int 이런 식으로 사용하는 예약어로는 변수명으로 사용할 수 없고 사용하면 안된다.
  • 실제로 데이터 타입이나 문법 관련 예약어들은 쓸 수 없다.
  • 유니티를 들어갈 때 참고하기 좋은 것 중 하나가 코드 스타일 관련이니 유니티를 들어갈 때, 확인해볼 것.
  • 당연하지만 한글로 코딩하지 말 것. C#은 되긴 하지만 C++의 경우는 막히는 것을 알고 있기 때문.
  • 좋은 예시로는 bool 형을 사용할 때, bool canJump;, bool isDead; 등으로 직관적이게 짓는 것이 좋음.

6. 참조 타입

6.1. 생명주기

  • 변수에는 생명 주기라는 것이 존재한다.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA;
        nNumberA = 15;

        int nA = 5;
        int nB = 10;
        Console.WriteLine(nA + nB);
    }
}

위 상태에서

csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA;
        nNumberA = 15;

        int nA = 5;
        {
            int nB = 10; // 비활성화
        }
        Console.WriteLine(nA + nB);
    }
}

  • 이렇게 되었을 때, nB가 비활성화 되면서 에러가 발생하게 된다.
  • nB는 할당되었지만 중괄호 되자마자 할당 해제가 된 것이어서 더이상 쓸 수 없게 된다.
  • int는 값 type이라서 확실히 이렇게 된다(예외는 제외하고 일반적인 경우).
  • 중괄호로 감싸진 것은 스코프 혹은 블록 범위라고 한다.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA;
        nNumberA = 15;

        int nA = 5;
        {
            int nB = 10;
            nA = 145;
        }
        Console.WriteLine(nA + nB);
    }
}

  • 만일 저 상태의 블록 범위에서 nA를 할당하면 수행이 될 수 있다.

6.2. 다양한 자료형에 대한 사용

  • 실수형은 f를 붙여주어야 한다.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;

        float fFloatNumber = 25.5f;
        
        Console.WriteLine(nNumberA);
        Console.WriteLine(fFloatNumber);
    }
}
  • 생각보다 bool 타입은 많이 쓰인다.
  • 예를 들어, 진행 상태, 수취 여부 등.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.5f;
        bool bIsBool = false;
        char cSymbol = 'c';
        
        Console.WriteLine(nNumberA);
        Console.WriteLine(fFloatNumber);
        Console.WriteLine(bIsBool);
        Console.WriteLine(cSymbol);
    }
}

  • 만일 여러개의 문자열을 사용하려면 컴파일러 에러가 발생하므로 알아둘 것.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.5f;
        bool bIsBool = false;
        char cSymbol = 'c';
        string sLetters = "Hello World";
        
        Console.WriteLine(nNumberA);
        Console.WriteLine(fFloatNumber);
        Console.WriteLine(bIsBool);
        Console.WriteLine(cSymbol);
        Console.WriteLine(sLetters);
    }
}

  • 다시 한 번 더 이야기하지만 한 글자는 작은 따옴표 쌍, 문자열은 큰 따옴표 쌍.
  • 어떤 방식의 데이터 어떤 유형의 데이터이냐에 따라 적절히 자료형을 지정해줘야 한다는 것이 키포인트이다.

7. 형변환

7.1. 사용법

csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.7f;
        bool bIsBool = false;
        char cSymbol = 'c';
        string sTexts = "Hello World";
        
        // 이것을 정수형으로 바꾸고 싶다면?
        Console.WriteLine((int)fFloatNumber);
    }
}

  • 캐스팅을 했을 때, 반올림을 하는 것이 아니라 그냥 버리는 것이므로 만일 반올림을 바란다면 추가적인 사항이 필요한 것.
  • 이번엔 char를 출력해보도록 하자.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'a';
        string sTexts = "Hello World";
        
        Console.WriteLine((int)cSymbol);
    }
}

  • 결과는 97로 나온다.
  • 이것이 바로 아스키 코드 쪽이다.
  • 코테 쪽에서 문자열이 주어지고 대문자를 모두 소문자로 바꾸라는 것이 있을 것이다. 그렇다면 아스키 코드 상에서 32를 빼면 될 것이다.
  • 예를 들어 다른 코드를 살펴보도록 하자.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sTexts = "Hello World";

        int nNewSymbol = cSymbol + 32;
        
        Console.WriteLine((char)nNewSymbol);
    }
}

  • 이렇게 했을 때 출력값은 c(소문자)이다.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";
        string sText2 = "20";

        Console.WriteLine(sText1 + sText2);
    }
}

  • 이것은 1020 이라고 문자열 합만이 뜰 뿐임.
  • int를 적용해보자.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";
        string sText2 = "20";
        
        int a=int.Parse(sText1);
        int b=int.Parse(sText2);

        Console.WriteLine(a + b);
    }
}

  • 30이 제대로 출력된다. 그렇다면 문자열을 추가해버리면?
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10a";
        string sText2 = "20";
        
        int a=int.Parse(sText1);
        int b=int.Parse(sText2);

        Console.WriteLine(a + b);
    }
}

  • 적어도 원인을 알려주며 터진다.
  • 원인 상에서는 '입력된 10a가 정확한 포멧이 아니다.' 라고 발생한다.
  • 문자열을 변환할 때는 안전장치를 충분히 마련해야 한다.
  • 나중 배열을 배울 때 더 상세하게 나올 예정.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";

        int a = 10;
        long b = 5234532253255642;

        int c;
        long d;
        
        // 명시적 변환 형태는 선언하지 않을 것. 
        c = b;
    }
}

  • 요런 것의 경우 c = b;에서 에러가 발생한다.
  • 이럴 때는 캐스팅을 붙여야겠거니 하고 생각하면 된다. 현재로써는.

7.2. 반올림

  • 반올림은 아래와 같이 진행된다.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.7f;
        bool bIsBool = false;
        char cSymbol = 'c';
        string sTexts = "Hello World";
        
        // 이것을 정수형으로 바꾸고 싶다면?
        Console.WriteLine((int)fFloatNumber);
        
        // 이것을 반올림하여 int형으로 변환하고 싶다면?
        Console.WriteLine(Convert.ToInt32(fFloatNumber));
    }
}

  • 저 int32는 구조체를 알아야 한다. 지금은 무시.
  • 자릿수를 지정하고 싶다면 또 어떻게 해야할지 막막할 수 있음.
  • 그렇다면 자릿수를 지정해보자.
csharp
using System;

class Program
{
    static void Main(string[] args)
    {
        int nNumberA= 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'c';
        string sTexts = "Hello World";
        
        // 이것을 정수형으로 바꾸고 싶다면?
        Console.WriteLine((int)fFloatNumber);
        
        // 이것을 반올림하여 int형으로 변환하고 싶다면?
        Console.WriteLine(Convert.ToInt32(fFloatNumber));
        
        // 자릿수 반올림을 하고 싶다고 한다면..
        Console.WriteLine(Math.Round(fFloatNumber, 2));
    }
}

  • Math.Round() 함수를 사용하여 어떤 변수와 자릿수를 지정한다.

8. 상수

8.1. 개요

  • readonly는 나중에 진행할 예정.
  • 정해져있는 수이다. 바꿀 수 없는 수이다.
  • const와 readonly는 어떤 시점에서 적용이 되느냐의 차이인데 지금은 const 위주로 볼 것이다.
  • 컴파일 시점에서 확정되는 값이다.

8.2. const

  • 일단 사용부터 해보도록 하자. 이번엔 class 프로그램 안쪽, 그러니까 main 밖에서 사용해보도록 하자.
csharp
using System;

class Program
{
    private
        const int nMaxLevel = 100;
    
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";

        nMaxLevel = 200;
    }
}
  • 아무리 해도 값이 바뀌지 않는다.
csharp
using System;

class Program
{
    private
        const int nMaxLevel;
    
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";

        nMaxLevel = 200;
    }
}
  • 이 때는 둘 다 터진다.
  • 그래서 선언과 동시에 값을 넣어줘야 하며 무엇을 변경해도 할 수 없다.
  • 아래와 같이 지정하면 된다.
csharp
using System;

class Program
{
    private const int nMaxLevel = 100;
    private const string sVersion = "1.0.1";
    private const float fPI = 3.14f;
    private const float fGravity = 9.81f;
    
    static void Main(string[] args)
    {
        int nNumberA = 15;
        float fFloatNumber = 25.754f;
        bool bIsBool = false;
        char cSymbol = 'C';
        string sText1 = "10";
    }
}
  • 지금은 이게 끝.
  • 아무튼 프로그램을 시작할 때인 컴파일 때 상수는 정해지고 시작한다(const).

8.3. readonly

  • 객체 지향과 class 이후에 설명이 가능한 사항이므로 패스.

배운 것 외의 사항

  • 혹시 Rider에서 .NET 관련으로 말썽이라면 다음을 설치해서 해결볼 것. 설치링크