Anna belly belly hard/C#

[C# 개념] 3.4 기본 데이터 형식

bibiana 각선행 2023. 6. 26. 14:16
반응형

-  값 형식 : 숫자 형식 ,논리 형식

-  참조 형식: 문자열 형식, 오브젝트 형식

 

3.4.1.숫자 데이터 형식

- c#은 15가지 기본 데이터 형식중 12가지를 숫자데이터 형식으로 제공

- 12가지 형식은 다시 정수 계열, 부동 소수 계열, 소수 계열 으로 나눠진다.

 

1) 정수 계열 형식

- 정수 데이터를 담기 위해 사용

- 12가지 형식중 9가지가 정수 계열 형식

- c# 은 pc나 대형 서버와 같이 메모리가 풍부한 컴퓨터를 위한 소프트웨어 뿐 아니라 휴대 전화기 같은 메모리가 아주 귀한 스마트 디바이스용 소프트웨어를 만드는 데도 쓰는 언어.

 

2) 정수 형식 예제 프로그램

using System;
using System.Formats.Asn1;

namespace IntegralTypes
{
    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}");
        }
    }
}

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

- C# 은 2진수 리터럴을 위해 0b, 16진수 리터럴을 위해 0X 접두사를 제공합니다.

using System;

namespace IntegerLiterals
{
    class MainApp
    {
        static void Main(string[] args)
        {
            byte a = 240;
            Console.WriteLine($"a={a}");

            byte b = 0b1111_0000;
            Console.WriteLine($"b={b}");

            byte c = 0XF0;
            Console.WriteLine($"c={c}");

            uint d = 0x1234_abcd;
            Console.WriteLine($"d={d}");
        }
    }
}

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

- 부호 있는 정수 : sbyte,short,int,long

- 부호 없는 정수 : byte, ushort,uint,ulong

 

-  byte 는 비트 8개 모두를 수 표현에 사용하는 반면 sbyte는 8개중 7개 비트만 수표현에 사용하고 첫번째 비트는 부호 비트로 사용한다.

- 정답은 3번

- 부호 비트를 순수하게 음과 양을 나타내는 데 사용하고 나머지 비트도 순수하게 수를 나타내는 데만 사용하면 -127인데 이러한 방식을 부호와 절댓값 방식 => 0을 표현할때 +0(0000 0000) 과 -0(1000 0000) 두가지가 존재하는 문제가 발생

- 그리하여 sbyte는 2의 보수법으로 음수를 표현

- 2의 보수법은 +0  과 -0 혼돈에서 벗어나게 해주며 오늘날 대부분의 컴퓨터 시스템에서 음수를 표현하는 방식

- sbyte 형식 변수에 담긴 -1의 비트가 정말 1111 1111 인지 확인

using System;

namespace SignedUnsigned
{
    class MainApp
    {
        static void Main(string[] args)
        {

            byte a = 255;
            sbyte b = (sbyte)a;
            Console.WriteLine(a);
            Console.WriteLine(b);
        }
    }

}

5) 데이터가 넘쳐 흘러요

- 오버플로(Overflow)

using System;

namespace Overflow
{

    class MainApp
    {
        static void Main(string[] args)
        {

            uint a = uint.MaxValue; // unit의 최대값. 4294967295

            Console.WriteLine(a);

            a = a + 1;
            
            Console.WriteLine(a);
        }

    }
}

- 최저값 보다 작은 데이터를 저장 : 언더플로 (Underflow)

 

6) char

- 정수 계열 형식

 

3.4.2 부동 소수점 형식

- 소수점이 고정 되어 있지 않고 움직이면서 수를 표현한다. -> 더 제한된 비트를 이용해서 훨씬 넓은 범위의 값을 표현할수 있기 때문

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

- 단일 정밀도(Single Precision)

- 복수 정밀도(Double Precision)

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

- IEEE754에 따르면 4바이트 크기의 float 형식은 수를 표현할때 1비트를 부호 전용으로, 가수부 23비트를 수를 표현하는데 사용, 나머지 지수부 8비트를 소수점의 위치를 나타내기위해 사용

- float 는 굉장히 넓은 범위의 수를 다루는데, float 형식이 가진 유효 숫자는 딱 7자리 빡에 없으니 7자리 이상의 수는 대략적으로 표현해야한다. -> '한정된 정밀도'

- float에 비해 두배의 메모리를 사용하는 double 형식을 복수정밀도를 가진 부동 소수점 형식

using System;

namespace FloatingPoint
{
    class MainApp
    {
        static void Main(string[] args)
        {
            float a = 3.1415_9265_3589_7932_3846f; //float 형식 변수에 값을 직접 할당하려면 숫자 뒤에 f 를 붙여줘야 합니다.
            Console.WriteLine(a);

            double b = 3.1415_9265_3589_7932_3846;
            Console.WriteLine(b);   
        }
    }
}

- 정밀도 면에서 한계를 가지므로 float 보다는 double 사용을 권한다. 메모리가 2배로 사용하지만 그만큼 데이터 손실이 적기 때문

- decimal 형식 : double 보다 데이터 손실이 적은 형식

 

1) decimal

 

using System;

namespace Decimal
{
    class MainApp
    {
        static void Main(string[] args)
        {
            float a = 3.1415_9265_3589_7932_3846_2643_3832_79f; // 숫자 뒤에 f를 붙이면 float 형으로 간주
            double b = 3.1415_9265_3589_7932_3846_2643_3832_79; // 아무것도 없으면 double
            decimal c = 3.1415_9265_3589_7932_3846_2643_3832_79m; // m 을 붙이면 decimal

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

        }
    }
}

- 회계 프로그램이나 계산기를 프로그래밍해야 한다면 float 나 double 보다는 decimal이 더 적합한 선택!

 

3.4.3 문자 형식과 문자열 형식

 - char : 정수를 다루는 데이터형식 출신이지만 수가 아닌 '가','나','a','b','c' 와 같은 문자 데이터를 다룬다.

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() 메소드는 데이터를 출력한 후 줄을 바꾸지 않습니다.
            Console.Write(b);
            Console.Write(c);
            Console.Write(d);
            Console.Write(e);
            Console.WriteLine();
        }
    }
}

 

- string 형식 : 여러개의 문자 형식을 하나의 실로 주르륵 묶어 처리

- string 은 정해진 크기나 담을수 있는 데이터 범위가 따로 정해져 있지 않다. 변수가 담는 텍스트의 양에 따라 그 크기가 달라지기 때문입니다.

 

namespace String
{
    class MainApp
    {
        static void Main(string[] args)
        {
            string a = "안녕하세요?";
            string b = "저는 ... 입니다...";
            Console.WriteLine(a);
            Console.WriteLine(b);
        }
    }
}

- 문자열 하나에 여러줄을 담으려면 이스케이프 문자(Escape sequence)를 이용

- \n : 줄바꿈(New Line) 을 나타내느 이스케이프 문자.

using System;

namespace Multiline
{
    class MainApp
    {
        static void Main(string[] args)
        {
            string multiline = """
                별 하나에 추억과
                별 하나에 사랑과
                별 하나에 쓸쓸함과
                별 하나에 동경과
                별 하나에 시와
                별 하나에 어머니, 어머니
                """;
            Console.WriteLine(multiline);
        }
    }
}

 

 

 

3.4.4 논리 형식

using System;

namespace Bool
{
    class MainApp
    {
        static void Main(string[] args)
        {
            bool a = true;
            bool b = false;

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

        }
    }
}

 

 

 

3.4.5 object 형식

- object 는 물체, 객체 . 그러니 어떤 데이터 이든지 다룰수 있는 데이터 형식

- 상속 : 부모 데이터 형식의 유산을 자식이 물려받는 것, 부모로부터 데이터와 메소드를 물려받은 자식은 부모와 똑같이 동작할수 있다. 컴파일러는 자식을 부모로 간주 할 수 있게 된다!

- C#은 object 가 모든 데이터를 다룰수 있도록 모든 데이터 형식이 자동으로 object 형식으로 부터 상속 받게 했다.

- 컴파일러는 어떤 형식의 데이터라도 object 에 담아 처리할 수 있다!

using System;

namespace Object
{
    class Program
    {
        static void Main(string[] args)
        {
            object a = 123;
            object b = 3.141592745790784384934839m;
            object c = true;
            object d = "안녕하세용.";

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

        }
    }
}

- 이러한 메커니즘을 박싱과 언박식이라고 합니다!

 

3.4.6 박싱과 언박싱

- object 형식은 참조 형식이기 때문에 힙에 데이터를 할당

- int,double 형식은 값형식이기 때문에 스택에 데이터를 할당

- object형식에 값형식의 데이터를 힙에 할당하기 위한 '박싱'(Boxing) 기능

- object 형식에 값형식의 데이터를 할당하려는 시도가 이루어지면 object 형식은 박싱을 수행해서 해당 데이터를 힙에 할당합니다.

 

<박싱>

object a = 20;

- 20은 그림에서 처럼 박스에 담겨 힙에 할당되고, a 는 그 주소를 참조.

 

<언박싱>

object a = 20;
int b = (int)a;

- a : 20이 박싱되어 저장된 힙을 참조

- b : a가 참조하고 있는 메모리로 부터 값을 복사

- 박싱된 값을 꺼내 값 형식 변수에 저장하는 과정 = 언박싱

using System;

namespace BoxingUnboxing
{
    internal class MainApp
    {
        static void Main(string[] args)
        {
            int a = 123;
            object b = (object)a;
            int c = (int)b;

            Console.WriteLine(a);
            Console.WriteLine(b);   // a에 담긴 값을 박싱 해서 힙에 저장
            Console.WriteLine(c);   // b에 담긴 값을 언박싱해서 스택에 저장

            double x = 3.1414213;
            object y = x;           // x에 담긴 값을 박싱해서 힙에 저장
            double z = (double)y;   // y에 담긴 값을 언박싱 해서 스택에 저장

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

        }
    }
}

 

 

3.4.7 데이터 형식 바꾸기

- 형식 변환(Type Conversion) : 변수를 다른 데이터 형식의 변수에 옮겨 담는 것

 

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; // sbyte의 최대값 127보다 1 큰수
            Console.WriteLine(x);

            sbyte y = (sbyte)x; // 오버플로가 발생
            Console.WriteLine(y);
        }
    }
}

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

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

using System;

namespace FloatConversion
{
    internal 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);
        }
    }
}

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

using System;

namespace SingnedUnsignedConversion
{
    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);
        }
    }
}

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

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

- 0.1 을 정수형식으로 변환하면 0 , 0.9 도 정수형식으로 변환하면 0

 

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);
        }
    }
}

 

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

- C# 은 정수 계열 형식, 부동 소수점 형식 모두에게 'Parse()' 라는 메소드 존재

int a = int.Parse("12345");
float b = float.Parse("123.45");

- 숫자 데이터 형식을 문자열로 바꾸는 방법: 정수 계열 데이터 형식이나 부동 소수점 데이터 형식은 자신이 가진 숫자를 문자열로 변환 하도록 object 로부터 물려받은 'ToString()' 메소드를 재정의했다.(오버라이드Override)

int c = 12345;
string d = c.ToString();

float e = 123.45;
string f = e.ToString();

 

using System;
using System.ComponentModel;

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 = "123456";
            int f = Convert.ToInt32(e);
            Console.WriteLine(f);

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

        }
    }
}

 

 

 

반응형