본문 바로가기

C#/이것이 C#이다

[ 이것이 C#이다 ] Chapter 03 . 데이터 보관하기

[ 학습 흐름 ]

[ 학습 흐름]

  1. 다양한 데이터의 종류
  2. 변수
  3. 값 형식과 참조 형식
  4. 기본 데이터 형식
  5. 상수와 열거 형식
  6. Nullable 형식
  7. var
  8. 공용 형식 시스템
  9. 문자열 다루기

[ 다양한 데이터의 종류 ]

[ 데이터 형식 ]

데이터 형식

- C#이 제공하는 다양한 데이터 형식은 기본데이터 형식,상수,열거형식등이 근간이 된다 .


복합 데이터 형식

- 기본 데이터 형식을 부품 삼아 구성됨 .

- 구조체, 클래스, 배열등이 있다 .


값 형식 - 참조 형식

- 데이터 형식은 "기본 데이터 형식 / 복합 데이터 형식"으로 나눔과 동시에 "값 형식 / 참조 형식"으로 분류가 가능하다 .


[ 변수 ]

[ 변수 ]

변수

- 코드에서 보자면 "값을 대입시켜 변화시킬 수 있는 요소"

- 메모리에서 보자면 "데이터를 담는 일정 크기의 공간"

- 변수는 데이터 형식( int ) 식별자( x )로 이루어진다 .


선언

- 프로그래머는 코드위에 "만든다"가 아닌 "선언한다"라는 표현을 사용한다 .

- int ( 데이터 형식 ) a ( 식별자 ) ; (세미 콜론 )과 같이 선언하면 컴파일러는 int형식을 위한 메모리를 할당한다 .

- 선언된 a에는 대입 연산자를 통해 데이터 입력이 가능하다. ex) a=10; ( 할당된 메모리 공간에 데이터가 기록 )

- 선언과 데이터 할당을 동시에 할 수 있다 . ex) int b=10;

- 데이터 형식이 같다면 여러 변수를 동시에 선언 할 수  있다 . ex) int a,b,c;


초기화

- 변수에 최초의 데이터를 할당하는 것을 의미한다 .

- C , C++에서는 선언후 초기화가 없다면 쓰레기 데이터가 들어간다 .

- C#에서는 초기화 없이 변수 사용시 컴파일러가 에러메시지를 띄우며 초기화를 강제한다 . 


리터럴

- "문자 그대로의"라는 뜻을 가진 형용사 .

- 컴퓨터 과학에서는 고정값을 나타내는 표기법을 말함 .

- int x =30; 에서 30이 리터럴 .


[ 값 형식과 참조 형식 ]

[ 값 형식과 참조 형식 ]

값 형식

- 변수가 값을 담는 데이터 형식 .

- 스택 메모리 영역과 관련있음 .


참조 형식

- 변수가 값 대신 값이 있는 곳의 위치 (참조)를 담는 데이터 형식 .

- 힙 메모리 영역과 관련있음 .


[ 스택과 값 형식 ]

스택

{//코드 블록 시작
    int a=100;
    int b=200;
    int c=300;
}//코드 블록 끝

 

- 선입 후출의 구조를 가진 메모리 .

- 위 코드에 선언된 a,b,c는 차례로 스택에 쌓였다가 코드블록이 끝남과 동시에 쌓인 순서대로 제거된다 .

- 값 형식의 데이터는 스택 메모리에 저장된다 .

- 스택 메모리에 쌓인 데이터는 코드 블록이 끝날때 스택 메모리에서 제거된다 .


[ 힙과 참조 형식 ]

- 힙은 저장된 데이터를 스스로 제거하는 메커니즘을 가지고 있지 않다 .

- 그대신 CLR의 가비지 컬렉터가 힙에 사용하지 않는 객체가 있으면 쓰레기로 간주 , 수거한다 .

- 프로그래머가 원한다면 계속 데이터를 살릴 수 있다 .


참조 형식 

- 참조 형식의 변수는 힙과 스택을 같이 이용한다 .

- 힙 영역에는 데이터를 스택 영역에는 데이터가 저장된 힙 메모리의 주소를 저장한다(참조) .

{
	object a=10;
	object a=20;
}

 

- CLR이 코드를 실행하면 실제 값 ( 10,20 )은 힙에 저장 , 스택에는 힙의 주소( a,b )를 저장한다 .

- 코드 블록이 끝나면 스택에 저장된 주소를 저장한 변수들( a,b )은 사라진다 .

- 더이상 데이터를 참조하는 곳이 없을때 힙 메모리의 데이터들 ( 10,20 )은 가비지 컬렉터가 제거한다 .


[ 기본 데이터 형식 ]

[ 기본 데이터 형식 ]

기본 데이터 형식

- C#이 제공하는 기본 데이터 형식에는 15가지가 있다 .

- 값형식 (숫자형식 / 논리형식 ) , 참조형식 (문자열 형식 / 오브젝트 형식 )으로 나뉜다 .


[ 숫자 데이터 형식 ]

숫자 데이터 형식

- 정수 계열 / 부동 소수 계열 / 소수계열 3가지로 나뉜다 .

- 12가지가 존재한다 .


[ 1 . 정수 형식 ]

정수 형식

- 9가지의 정수 형식은 크기와 담을 수 있는데이터의 범위가 다르다 .

- 이는 프로그래머가 적절한 데이터 형식을 선택함으로 메모리를 효율적으로 사용하게 하기 위함 .

- 메모리가 귀한 모바일 디바이스에서는 메모리 효율의 고려가 필요함

- 8비트는 1바이트로 취급한다 . 바이트는 컴퓨터가 데이터를 다루는 기본 단위이다 .

 데이터 형식 담을 수 있는 값의 범위 설명 크기(바이트)
sbyte -128 ~ 127 부호 있는 8비트 정수 1(8비트)
byte 0 ~ 255 부호 없는 8비트 정수 1(8비트)
short -32,768 ~ 32,767 부호 있는 16비트 정수 2(16비트)
ushort 0 ~ 65,535 부호 없는 16비트 정수 2(16비트)
int -2,147,483,648 ~ 2,147,483,647 부호 있는 32비트 정수 4(32비트)
uint 0 ~ 4,294,967,295 부호 없는 32비트 정수 4(32비트)
long -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 부호 있는 64비트 정수 8(64비트)
ulong 0 ~ 18,446,744,073,709,551,615 부호 없는 64비트 정수 8(64비트)
char   유니코드 문자 2(16비트)
using System;

namespace IntegralType;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        sbyte a = -10;
        byte b = 40;

        Console.WriteLine($"a={a},b={b}");

        short c = -30000;
        ushort d = 60000;
        Console.WriteLine($"c={c},d={d}");

        int e = -1000_0000;
        uint f = 3_0000_0000;
        Console.WriteLine($"e={e},f={f}");

        long g = -5000_0000_0000;
        ulong h = 200_0000_0000_0000_0000;
        Console.WriteLine($"g={g},h={h}");
    }
}

 

- 다음 프로그램은 정수형 변수 몇가지를 만들어 데이터를 담고 출력하는 기능을 한다 .


2진수 , 10진수 , 16진수 리터럴

- C#은 2진수 리터럴을 위해 0b / 16진수 리터럴을 위해 0x ( 또는 0X ) 접두사를 제공한다 .

using System;

namespace IntegralLiterals;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        byte a = 240;   //10진수 리터럴 
        Console.WriteLine($"a = {a}");
        byte b = 0b1111_0000;   //2진수 리터럴
        Console.WriteLine($"b = {b}");
        byte c = 0xF0;   //16진수 리터럴
        Console.WriteLine($"c = {c}");
        uint d = 0x1234_abcd;   //16진수 리터럴
        Console.WriteLine($"d = {d}");

    }
}

 

- 다음 프로그램은 정수형 변수 몇가지를 만들어 10진수/2진수/16진수 데이터를 담고 출력하는 기능을 한다 .


부호 있는 정수와 부호 없는 정수

- sbyte,short,int,long은 부호 있는 정수이고 , byte,ushort,uint,ulong은 부호 없는 정수이다 .

- 음의 정수는 음의 부호 ( - ) 가 필수이다 .

- 부호 있는 정수의 경우 첫번째 비트 ( 부호 비트 )를 부호를 표현하는데 사용한다 .


부호의 절대값 방식

- 부호비트는 음과 양을 , 나머지 비트는 수를 나타내는 방식 .

- 0의 표현시 +0(0000 0000)과 -0(1000 0000) 두가지가 존재하는 문제가 발생한다 .


2의 보수법

-  대부분의 컴퓨터 시스템에서 음수 표현시 사용한다 .

- 방식은 "1.먼저 수 부분 비트를 채운다 / 2.전체 비트를 반전 / 3.1을 더한다" 의 과정을 거친다 .

- 장점은 +0과 -0의 혼돈에서 벗어나며 표현 가능한 수가 하나 더 늘어난다 . ( -128부터 127 까지)

using System;

namespace SignedUnsigned;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        byte a = 255;   
        Console.WriteLine($"a = {a}");
        sbyte b =(sbyte)a;  
        Console.WriteLine($"b = {b}");
    }
}

 

 

- 위 코드로 sbyte 형식 변수에 담긴 -1이 1111 1111임을 확인 할 수 있다 .


데이터가 넘쳐 흘러요

- 변수는 데이터를 담는 그릇과 같다 .

- 데이터 형식의 크기를 넘어 넘치는 것을 오버플로라고 한다 . 

using System;

namespace SignedUnsigned;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        uint a = uint.MaxValue;   
        Console.WriteLine($"a = {a}");
        a = a + 1;  
        Console.WriteLine($"a = {a}");

        int b = int.MaxValue;
        Console.WriteLine($"b = {b}");
        b = b + 1;
        Console.WriteLine($"b = {b}");
    }
}

 

- 위의 코드는 해당 데이터 형식의 최대값을 넘기는 것을 확인시켜주는 프로그램이다 .

- 최대값을 가진 정수가 오버플로되면 헤딩 데이터 형식의 최소값이 된다 .이를 오버플로 래핑이라고 한다 .


[ 2 . 부동 소수점 형식 ]

부동 소수점 형식

- 부동 소수점은 소수점이 고정되어 있지 않고 움직이며 수를 표현한다는 뜻 ( Floating Point )

- 이는 소수점을 이용시 고정했을때보다 더 제한된 비트로 넓은 범위의 값 표현이 가능하기 때문 .

- 부동 소수점 방식은 정수뿐 아니라 유리수를 포함한 실수 영역의 데이터를 다룬다 .


부동 소수점 형식이 실수형식을 대체 못하는 이유

- 소수점 표현을 위해 일부 비트를 사용하므로 같은 크기의 정수계열 형식과 같은 크기의 수 표현을 못함 .

- 산술 연산 과정이 정수계열 보다 복잡해서 느리다 .


부동 소수점 형식의 종류

 

 데이터 형식 설명 크기 ( 바이트 ) 범위
float 단일 정밀도 부동 소수점 형식 ( 7개 자리수 다룸 ) 4 ( 32비트) -3.402823e38 ~ 3.402823e38
double 복수 정밀도 부동 소수점 형식 (15~16개의 자리수 다룸) 8 ( 64비트 ) -1.79769313486232e308 ~ 1.79769313286232e308

- float의 이름은 floating Point에서 따옴

- double의 이름은 double Precision Floating Point에서 따옴 .


정밀도

- C#의 float 과 double은 IEEE754라는 표준 알고리즘에 기반한 데이터 형식이다 .

- IEE754 float을 표현할때 1비트는 부호 / 기수부 23 비트는 수 / 지수부 8비트는 소수점 위치를 나타내기 위해 사용한다.

- float은 4 바이트를 가지고 굉장히 넓은 범위를 다루지만 유효숫자는 7자리 뿐이라 그 이상의 수는 대략적으로 표현한다 . 

- float은 한정된 정밀도, 즉 단일 정밀도라고 표현한다 .

- double은 복수 정밀도를 가진 부동 소수점 형식이라고 한다 .

using System;

namespace FloatingPoint;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        float a = 3.1415_9265_3589_7932_3846f;
        Console.WriteLine($"a = {a}");

        double b= 3.1415_9265_3589_7932_3846d;
        Console.WriteLine($"b = {b}");
    }
}

 

- 실행결과 가수부가 담을 수 있는 부분까지만 저장하고 나머지는 버림을 알 수 있다 .

- float - double - decimal - 그 이상은 "직접 만든 복합데이터 형식 " 의 순으로 데이터의 손실이 적다 .


[ 3 . 소수 형식 ]

decimal 형식

 데이터 형식 설명 크기 ( 바이트 ) 범위
decimal 29자리 데이터를 표현할수 있는 소수 형식 16 ( 128비트) ±1.0 × 10^-28~
±7.9 × 10^28

- decimal은 부동 소수점 방식과는 다른 방식으로 소수를 다룬다 .

- 징밀도가 훨씬 높다 .

- 회계, 계산기 프로그램등 높은 정밀도를 원한다면 decimal은 좋은 선택지이다 .

using System;

namespace FloatingPoint;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        //f를 붙이면 float
        float a = 3.1415_9265_3589_7932_3846f;
        Console.WriteLine($"a = {a}");

        //아무것도 없으면 double
        double b= 3.1415_9265_3589_7932_3846;
        Console.WriteLine($"b = {b}");

        //m을 붙이면 decimal
        decimal c= 3.1415_9265_3589_7932_3846m;
        Console.WriteLine($"c = {c}");

    }
}

 


[ 4 . 문자 형식과 문자열 형식 ]

문자 형식

- char형식은 정수를 다루는 데이터 형식이지만 수가 아닌 문자 데이터를 다룬다 .

- 데이터를 담을때 따옴표( ' ' )로 문자를 감싸야 한다 .

using System;

namespace Char;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        char a = '안';
        char b = '녕';
        char c = '하';
        char d = '세';
        char e = '요';

        Console.Write(a);
        Console.Write(b);
        Console.Write(c);
        Console.Write(d);
        Console.Write(e);
        //데이터를 출력후 줄바꿈을 한다 .
        Console.WriteLine();
        
    
    }
}

 


문자열 형식

- string 형식은 문자열을 표현하기 위해 사용한다 .

- 변수가 담는 텍스트 양에 따라 크기가 달라진다 .

- 이스케이프 문자 , 큰 따옴표 3개등으로 줄바꿈을 처리 할 수 있다 .

using System;

namespace String;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string a = "안녕하세요";
        Console.Write(a);

        string multiline = "\n밥은 드셨어요?\n음료는요?\n";
        Console.Write(multiline);

        string multiline2="""
            별 하나에 추억과
            별 하나에 사랑과
            별 하나에 쓸쓸함과
            """;
        Console.Write(multiline2);
    }
}

 


[ 5 . 논리 형식 ]

논리 형식

 데이터 형식 설명 크기 ( 바이트 ) 범위
bool 논리 형식 1 ( 8비트) true,false

- 참과 거짓을 다룬다 .

using System;

namespace String;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        bool a = true;
        bool b = false;
        Console.WriteLine(a);
        Console.WriteLine(b);
    }
}

 


[ 6 . Object 형식 ]

논리 형식

- object 형식은 어떤 데이터든지 다룰 수 있는 데이터 형식이다 .

- 모든 데이터 형식은 object 형식을 상속받는다 .

using System;

namespace String;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        object a = 123;
        object b = 3.14124123123123123m;
        object c = true;
        object d = "안녕하세요";

        Console.WriteLine(a);
        Console.WriteLine(b);
        Console.WriteLine(c);
        Console.WriteLine(d);
    }
}

 


박싱

object a = 20;

- object 형식에 값 형식의 데이터를 할당하려 시도하면 , object 형식은 박싱을 수행하여 해당 데이터를 힙에 할당한다 .

- 값 형식의 데이터는 박스에 담겨 힙에 할당되고 , object 형식의 변수는 해당 힙의 주소를 참고한다 .


언박싱

int b = (int)a;

- 힙에 있던 값 형식 데이터를 값 형식 객체에 다시 할당하는 것을 언박싱이라고 한다 .

- 박신된 값을 꺼내 값 형식 변수에 저장하는 과정.

using System;

namespace BoxingUnboxibg;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 123;
        object b = (object)a;
        int c = (int)b;

        Console.WriteLine(a);
        Console.WriteLine(b);
        Console.WriteLine(c);

        double x = 3.1414213;
        object y = x;
        double z=(double)y;

        Console.WriteLine(x);
        Console.WriteLine(y);
        Console.WriteLine(z);
    }
}

 

 


[ 7 . 데이터 형식 바꾸기 ]

데이터 형식 바꾸기

- 변수를 다른 데이터 형식의 변수에 옮겨 닮는 것을 형식 변환이라고 한다 .

- 앞서 본 박싱 언박싱도 값 형식과 참조 형식간의 형식 변환이다 .


1. 크기가 서로 다른 정수 형식 사이의 변환

- 큰 형식의 변수를 작은 형식의 변수에 옮길때 오버플로가 발생한다 . ( 작은 형식 변수 범위 밖에 있는)

using System;

namespace IntegralConversion;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        sbyte a = 127;
        Console.WriteLine(a);

        int b=(int)a;
        Console.WriteLine(b);

        int x = 128;
        Console.WriteLine(x);

        sbyte y=(sbyte)x;
        Console.WriteLine(y);
    }
}

 

- int 형식 변수를 sbyte 형식 변수로 변환할때 , sbyte 범위를 벗어나자 오버플로 래핑이 일어나 최소값을 가짐을 볼 수 있다


2. 크기가 서로 다른 부동 소수점 형식 사이의 변환

- 부동 소수점  형식의 특성상 오버플로는 없지만 , 정밀성에 손상을 입는다 .

- float,double은 소수를 2진수로 메모리에 보관한다 .

- 다른 형식으로 변환시 (float - double/double - float) 소수를 10진수로 복원후  2진수로 변환해서 기록한다 .

- 1/3과 같은 수는 0.333등의 무한소수가 되므로 2진수로 표현하는 소수는 완전하지 않다 .

using System;

namespace FloatConversion;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        float a = 69.6875f;
        Console.WriteLine("a : {0}",a);
        double b = (double)a;
        Console.WriteLine("b : {0}", b);
        Console.WriteLine("69.6875 == b : {0}",69.6875 == b);

        float x = 0.1f;
        Console.WriteLine("x : {0}", x);
        double y= (double)x;
        Console.WriteLine("y : {0}", y);
        Console.WriteLine("0.1 == y : {0}", 0.1 == y);
    }
}

 

- 0.1의 경우 형변환 후 기대하는 값이 아님을 볼 수 있다 . 


3. 부호 있는 정수 형식과 부호 없는 정수 형식 사이의 변환

using System;

namespace SignedUnsignedConversion;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 500;
        Console.WriteLine(a);
        uint b=(uint)a;
        Console.WriteLine(b);

        int x = -30;
        Console.WriteLine(x);   
        uint y= (uint)x;
        Console.WriteLine(y);   

    }
}

 

- 최저값 보다 작은 데이터를 담으려 했을때 언더플로가 일어남을 볼 수 있다 .

- C#에서 음의 정수를 부호 없는 정수로 변환하면 부호 없는 정수의 동작으로 인해 결과 값이 순환된다.

- 이 순환 동작은 양수가 될 때까지 음수 값에 UInt32.MaxValue + 1 -30의 과정을 거쳐 위의 값이 나온다 .


4. 부동 소수점 형식과 정수 형식 사이의 변환

- 부동 소수점 형식의 변수를 정수 형식으로 변환하면 소수점 아래는 버리고 소수점 위의 값만 남긴다 .

using System;

namespace FloatToIntegral;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        float a = 0.9f;
        int b=(int)a;
        Console.WriteLine(b);

        float c = 1.1f;
        int d = (int)c;
        Console.WriteLine(d);

    }
}

 


문자열을 숫자로 ,  숫자를 문자열로

- 정수 계열 형식 , 부동 소수점 형식은 Parse 메서드 ,ToString , Convert.To~ 메서드를 통해 각 형변환이 가능하게 한다 .

using System;

namespace StringNumberConversion;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        int a = 123;
        string b = a.ToString();
        Console.WriteLine(b);

        float c = 3.14f;
        string d = c.ToString();
        Console.WriteLine(d);

        string e = "1234";
        int f = Convert.ToInt32(e);
        Console.WriteLine(f);

        string g = "1.234";
        float h = float.Parse(g);
        Console.WriteLine(h);
    }
}

 


[ 상수와 열거 형식 ]

[ 상수와 열거 형식 ]

상수와 열거 형식

- 상수와 열거 형식은 변수와 달리 안에 담긴 데이터를 바꿀 수 없는 메모리 공간이다 .


[ 상수 : 전 언제나 변하지 않을 거에요 ]

상수

const 자료명 상수명 = 값 ;

- 상수는 한번 선언하면 데이터를 변경 할 수 없다 .


[ 열거 형식 : 여러 개의 상수를 정리해요 ]

열거 형식

- 같은 범주안에 속하는 상수를 여러 개 선언할 때 유용하다 .

//기반자료형은 정수계열만 사용가능
enum 열거_형식명 : 기반 자료형 {상수 1,상수2, 상수3 ,...}
//기반 자료형은 생략 가능
enum 열거_형식명 {상수1 , 상수2 , 상수3 , ...}

 

- 기반 자료형은 생략 가능하며 생략시 int를 기반 자료형으로 사용한다 .

- 열거 형식의 각 요소는 값을 부여하지 않아도 정수 데이터를 컴파일러가 자동으로 0부터 할당하며 중복 되지 않는다  .

- 위 값은 프로그래머가 직접 할당 할 수도 있다 .

- 열거 형식은 변수가 아닌 새로운 형식이다 .

using System;

namespace StringNumberConversion;

class MainApp
{
    enum DialogResult : int {YES,NO,CANCEL=50,CONFIRM,OK }
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        DialogResult result = DialogResult.YES;
        Console.WriteLine(result == DialogResult.YES);
        Console.WriteLine((int)result);
        Console.WriteLine(DialogResult.CONFIRM);
    }
}

[ Nullable 형식 ]

[ Nullable 형식 ]

Nullable

데이터 형식? 변수이름;

- 변수에게 할당된 메모리 공간을 비우고 싶을때 Nullable 형식을 사용한다 .

- 값 형식에 한해 사용 가능하다 .

- Nullable 형식은 HasValue/Value 두가지 속성을 가지고 있다 .

 


HasValue

int?a = null;
a.HasValue;

- HasValue 속성은 해당 변수가 값을 가지고 있는지 아닌지를 나타낸다 .


Value

int?a = null;
int x = a.Value;

- Value 속성은 해당 변수에 담겨있는 값을 나타낸다 .

- 만약 null인 값을 Value 속성을 이용하여 값을 꺼내려 시도하면 CLR은 InvalidOperationException 예외를 띄울 것이다 .


[ Var 형식 ]

[ var 형식 ]

강력한 형식의 언어

- C#은 변수나 상수에 대해 깐깐하게 형식 검사를 하는 강력한 형식의 언어이다 .

- 이는 프로그래머의 실수 (의도치 않은 형식의 데이터를 읽거나 할당하는)를 막아준다 .

- 그러나 var 키워드를 통해 약한 형식 검사의 편리함도 지원한다 .


Var

var a=3;
var a="Hello";

- var 형식을 사용하면 컴파일러가 자동으로 해당 변수의 형식을 지정해준다 .

- 반드시 선언과 동시에 초기화가 필요하다 .

- var 키워드는 지역변수만 사용 가능하다 .


[ 공용 형식 시스템 ]

[ 공용 형식 시스템 ]

공용 형식 시스템

- C#과 마찬가지로 .NET 지원 모든 언어의 데이터 형식 체계는 CTS를 따르고 있다 . 

- 이는 .NET언어들간의 호환성을 가지게 하기 위해서이다 .

- CTS 형식은  각 언어에서 코드에 그대로 사용 가능하다 . ex) System.Int32 == int

- object 형식은 GetType()과 ToString() 메서드를 가지고 있다 .


[ 문자열 다루기 ]

[ 문자열 안에서 찾기 ]

문자열 안에서 찾기

- string 형식이 제공하는 탐색 메서드는 다음과 같다 .

메소드 설명
Index of() 현재 문자열 내에서 찾으려고 하는 지정된 문자 또는 문자열의
위치를 찾는다
LastIndexOf() 현재 문자열 내에서 찾으려고 하는 지정된 문자 또는 문자열의 위치를 뒤에서 부터 찾는다 .
StartsWith() 현재 문자열이 지정된 문자열로 시작하는지를 평가한다 .
EndsWith() 현재 문자열이 지정된 문자열로 끝나는지를 평가한다 .
Contains() 현재 문자열이 지정된 문자열을 포험허는지를 평가한다.
Replace() 현재 문자열에서 지정된 문자열이 다른 지정된 문자열로 모두 바뀐 
새 문자열을 반환한다 .
using static System.Console;

namespace StringSearch;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string greeting = "Good Morning"; 
        WriteLine(greeting);
        WriteLine();

        //IndexOf()
        WriteLine("Index Of 'Good' : {0}", greeting.IndexOf("Good"));
        WriteLine("Index Of 'o' : {0}", greeting.IndexOf("o"));

        //LastIndexOf()
        WriteLine("Last Index Of 'Good' : {0}", greeting.LastIndexOf("Good"));
        WriteLine("Last Index Of 'o' : {0}", greeting.LastIndexOf("o"));

        //StartsWith()
        WriteLine("Starts With 'Good' : {0}", greeting.StartsWith("Good"));
        WriteLine("Starts With 'Morning' : {0}", greeting.StartsWith("Morning"));

        //EndsWith()
        WriteLine("Ends With 'Good': {0}", greeting.EndsWith("Good"));
        WriteLine("Ends With 'Morning': {0}", greeting.EndsWith("Morning"));

        //Contains
        WriteLine("Contains 'Evening {0}",greeting.Contains("Evening"));
        WriteLine("Contins 'Morning' : {0}", greeting.Contains("Morning"));

        //Replace
        WriteLine("Replaced 'Morning' wirh 'Evening' : {0}", greeting.Replace("Morning", "Evening"));
    }
}

 


[ 문자열 변형하기 ]

문자열 변형하기

- string 형식은 문자열 삽입 / 특정 부분 삭제 / 대문자 - 소문자로의 변환 / 공백 제거 등의 변현 메서드를 제공한다 .

메소드 설명
ToLower() 현재 문자열의 모든 대문자를 소문자로 바꾼 새 문자열을 반환한다 .
ToUpper() 현재 문자열의 모든 소문자를 대문자로 바꾼 새 문자열을 반환한다 .
Insert() 현재 문자열의 지정된 위치에 지정된 문자열이 삽입된 새 문자열을 반환한다 .
Remove() 현재 문자열의 지정된 위치로부터 지정된 수만큼 문자가 삭제된 새 문자열을 반환한다 .
Trim() 현재 문자열의 앞/뒤에 있는 공백을 삭제한 새 문자열을 반환한다 .
TrimStart() 현재 문자열의 앞에 있는 공백을 삭제한 새 문자열을 반환한다 .
TrimEnd() 현재 문자열의 뒤에 있는 공백을 삭제한 새 문자열을 반환한다 .
using static System.Console;

namespace StringModify;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        //ToLower() - ToUpper()
        WriteLine("ToLower() : '{0}'","ABC".ToLower());
        WriteLine("ToUpper() : '{0}'", "abc".ToUpper());

        //Insert() - Remove()
        WriteLine("Insert() : '{0}'", "Happy Friday!".Insert(5, " Sunny"));
        WriteLine("Remove() : '{0}'", "I Don't Love You!".Remove( 2, 6));

        //Trim
        WriteLine("Trim() : '{0}'", " No Spaces ".Trim());
        WriteLine("Trim Start() : '{0}'", " No Spaces ".TrimStart());
        WriteLine("TrimEnd() : '{0}'", " No Spaces ".TrimEnd());
    }
}

 


[ 문자열 분할하기 ]

문자열 분할하기

- string 형식은 문자열 분할 메서드를 제공한다 .

메소드 설명
Split() 지정된 문자를 기준으로 현재 문자열을 분리한 다음 분리한 문자열의 배열을 반환한다 .
Substring() 현재 문자열의 지정된 위치로부터 지정된 수만큼의 문자로 이루어진 새 문자열을 반환한다 .
using static System.Console;

namespace StringSlice;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string greeting = "Good Morning";

        //Substring
        WriteLine(greeting.Substring(0, 5));
        WriteLine(greeting.Substring(5));
        WriteLine();

        //Split
        string[] arr = greeting.Split(new string[] { " " }, System.StringSplitOptions.None);
        WriteLine("World Count : {0}", arr.Length);
        foreach(string a in arr)
            WriteLine(a);

    }
}

 


[ 문자열 서식 맞추기 - Format ]

문자열 서식 맞추기

- 서식 : 문자열이 일정한 틀과 모양을 갖추는 것

- string 형식의 Format 메서드 / 문자열 보간 두가지 방식이 존재한다 .

- 문자열 틀을 두고 서식화된 새로운 문자열을 만들어냄 .


Format () 메서드

Console.WirteLine(" 내용 : { 첨자 , 맞춤 : 서식 문자열 }");

 

- 서식 항목 "{ }"에 위와 같이 추가 옵션인 " 첨자 / 맞춤 / 서식 문자열"을 입력하여 다양한 서식화를 수행 가능하다 .


Format () 메서드 - 맞춤

- 해당 서식항목이 차지할 공간의 크기와 방향을 선택 할 수 있다 .

- 왼쪽부터 채울때는 - / 오른쪽부터 채울때는 + 부호를 선택한다 .

using static System.Console;
using System;

namespace StringSlice;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string fmt = "{0,-20 }{1,-15}{2,30}";

        WriteLine(fmt, "Publisher", "Author", "Title");
        WriteLine(fmt, "Marvel", "Stan Lee", "Iron Man");
        WriteLine(fmt, "Hanbit", "Sang Hyun Park", "This Is C#");
        WriteLine(fmt, "Prentice Hall", "K&R", "The C# Programming Language");
    }
}

 


Format () 메서드 - 숫자 서식화

- 숫자 서식화는 서식 문자열에 의해 결정된다 .

- 다음은 서식 문자열에 사용 할 수 있는 서식 지정자이다 .

- 이와 더불어 서식 지정자 뒤에 자릿수 지정자를 사용 할 수 있다. ex)"D5", 23  - 00023

메소드 대상서식 설명
D 10진수 입력된 수를 10진수로 서식화한다 .
X 16진수 입력된 수를 16진수로 서식화한다 .
N 콤마로 묶어
표현한 수
입력된 수를 콤마로 구분하여 출력한다 .
F 고정 소수점 입력된 수를 고정 소수점 형식으로 서식화한다 .
E 지수 입력된 수를 지수 표기로 서식화한다 .
using static System.Console;
using System;

namespace StringFormatNumber;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        //서식 지정자 / 자릿수 지정자
        //D : 10진수
        WriteLine("10진수 : {0:D}", 123);
        WriteLine("10진수 : {0:D5}", 123);

        //X : 16진수
        WriteLine("16진수 : 0x{0:X}",0xFF1234);
        WriteLine("16진수 : 0x{0:X8}", 0xFF1234);

        //N : 콤마로 구분
        WriteLine("숫자 : {0:N}", 123456789);
        WriteLine("숫자 : {0:N0}", 123456789);//자릿수 0은 소수점 이하를 제거한다 .

        //F : 고정 소수점
        WriteLine("고정 소수점 : {0:F}", 123.456);// 뒷자리를 버리는 듯
        WriteLine("고정 소수점 : {0:F5}", 123.456);

        //E : 지수
        WriteLine("공학 : {0:E}", 123.456789);
    }
}

 


Format () 메서드 - 날짜 서식화

DateTime dt = new DateTime(2023,03,04,23,18,22)//2023년 03월 04일 23시 18분 22초
WriteLine("{0}",dt);//국가 및 지역 설정에 따라 다른 결과 출력

- 제어판 국가설정 / System.Globalization.CultureInfo 클래스로 날짜 및 시간 서식을 통제 할수 있다 .

- 해당 클래스는 문화권 정보를 나타낸다 . DateTime.ToString()메서드에 해당 인스턴스 입력시 해당 문화권 정보를 얻는다.

서식 지정자 대상 서식 설명
y 연도 - yy : 두자릿수 연도
-yyyy : 네자릿수 연도
M - M : 한 자릿수 월
- MM : 두 자릿수 월
d - d : 한 자릿수 일
- dd : 두 자릿수 일
h 시(1~12) - h : 한 자릿수 시
- hh : 두 자릿수 시
H 시(0~23) - H : 한 자릿수 시
- HH : 두 자릿수 시
m - m : 한 자릿수 분
- mm : 두 자릿수 분
s - s : 한 자릿수 초
- ss :  두 자릿수 초
tt 오전/오후 - tt : 오전/ 오후
ddd 요일 - ddd: 약식 요일
- dddd :  전체 요일
using static System.Console;
using System;
using System.Globalization;

namespace StringFormatDateTime;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        DateTime dt = new DateTime(2023, 03, 04, 23, 18, 22);

        WriteLine("12시간 형식 : {0:yyyy - MM - dd tt hh:mm:ss (ddd)}", dt);
        WriteLine("24시간 형식 : {0:yyyy - MM - dd HH:mm:ss (ddd)}", dt);

        CultureInfo ciKo = new CultureInfo("ko-KR");
        WriteLine();
        WriteLine(dt.ToString("yyyy - MM - dd tt hh:mm:ss (ddd)", ciKo));
        WriteLine(dt.ToString("yyyy - MM - dd HH:mm:ss (dddd)", ciKo));
        WriteLine(dt.ToString(ciKo));

        CultureInfo ciEn = new CultureInfo("en-US");
        WriteLine();
        WriteLine(dt.ToString("yyyy - MM - dd tt hh:mm:ss (ddd)", ciEn));
        WriteLine(dt.ToString("yyyy - MM - dd HH:mm:ss (dddd)", ciEn));
        WriteLine(dt.ToString(ciEn));
    }
}

 


[ 문자열 서식 맞추기 - 문자열 보간 ]

 

문자열 보간

- 보간 : 낱말의 비거나 누락된 부분을 채운다 .

- Format()메서드와 차이점은 문자열 틀 앞에 $기호를 붙임 / 서식항목에 첨자 대신 식이 들어감

$" 텍스트 { 보간식 , 길이 (맞춤) : 서식 (서식 문자열) }";
string.Format 문자열 보간
WriteLine("{0},{1}",123,"최강 한화"); WriteLine($"{123},{"최강한화"}");
WriteLine("{0,-10:D5}",123) WriteLine($"{123,-10:D5}");
int n=123;
string s="최강 한화";
WriteLine("{0},{1}",n,s);
int n=123;
string s="최강 한화";
WriteLine($"{n},{s}");
int n=123;
WriteLine("{0}",n>100?"큼":"작음");
int n=123;
WriteLine($"{n>100?"큼":"작음"}");
using static System.Console;
using System;
using System.Globalization;

namespace StringInterpolation;

class MainApp
{
    //프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        string name = "김튼튼";
        int age = 23;
        WriteLine($"{name,-10},{age:D3}");

        name = "박날씬";
        age = 30;
        WriteLine($"{name},{age,-10:D3}");

        name = "이비실";
        age = 17;
        WriteLine($"{name},{(age>20?"성인":"미성년자")}");

    }
}