TIL

자료형 배열 컬렉션 햇갈리는 부분 정리

박민혁_kog 2023. 8. 14. 20:57

자료형 종류

자료형 크기(바이트) 범위
sbyte 1 -128 ~ 127
byte 1 0 ~ 2555
short 2 -32,768 ~ 32,767
ushort 2 - ~ 65,635
int 4 -2,147,483,648 ~ 2,147,483,647
uint 4 0 ~ 4,294,967,295
long 8 -9,223,372,036, 854,775,808 ~
-9,223,372,036, 854,775,807
ulong 8 0~ 18,446,744,073,709,551,6115
float 4 3.4E–38 ~ 3.4E+38
double 8 1.7E–308 ~ 1.7E+308
decimal 16  
char 2 유니코드 '문자'
string   유니코드 문자열
bool 1 true or false

어? 그러면 long은 int 보다 더 큰데 그냥 편하게 롱을 쓰면 안될까?

1. 메모리의 효율적 사용 =공간 

2. 데이터의 정확한 표현 = 소수점 더블과 플로트 통해 소수점 길이 추측가능 =  자료의 세분화

3. 타입 안정성 = 해당 자료형이 가질수 있는 값의 범위를 벗어날시 오류가 발생하여 문제점 확인 가능

 

식별자 표기법

Pascal class : 클래스 , 메서드 , 프로퍼티 이름등에 사용 단어의 첫글자는 대문자로 이후 단어의 첫글자도 대문자 EX : ClassName , MethodName 

camelCase:변수 매개변수 로컬변수 등 에 사용 단어의 첫글자는 소문자로 시작하며 이후 단어의 첫글자는 대문자로 표기 EX: variableName , parameterName

 

 

데이터 형변환

명시적 형변환 - 지정해주는것 

int num1 = 10;
long num2 = (long)num1;   // int를 long으로 명시적 형변환

암시적 형변환 

작은 데이터 타입에서 큰 데이터 타입으로 변환 

byte num1 = 10;
int num2 = num1;  // byte형에서 int형으로 암시적 형변환

 

C#에서의 입력값 변수에 넣기!####

Console.Write("Enter two numbers: ");
string input = Console.ReadLine();    // "10 20"과 같은 문자열을 입력받음

string[] numbers = input.Split(' ');  // 문자열을 공백으로 구분하여 배열로 만듦

C#의 마법 var 형 변수 

컴파일러가 알아서 해준다 어썸

var num = 10;         // int 자료형으로 결정됨
var name = "kero";   // string 자료형으로 결정됨
var pi = 3.141592;    // double 자료형으로 결정됨

문자열을 숫자로 변환 # 

string str = "123";
int num = int.Parse(str);

숫자를 문자열로 변환#

int num = 123;
string str = num.ToString();

 

삼항 연산자 - 이런게 있다는건 알고 있었지만 이름을 몰라서 검색은 못해보고 써보긴 했었다 이름을 알게됨!

int A = 100;
int B = 1;

# 삼항 연산자
string result = (A >= B) ? "조건이 참!" : "조건이 거짓!";
Console.WriteLine(result);

이것을 if else 문으로 사용한다면 아래와 같다

# if else 문
if (A >= B)
{
    Console.WriteLine("참");
}
else
{
    Console.WriteLine("거짓");
}
코드가 엄청나게 줄어든다 ㄷㄷㄷ

 

다차원 배열 - 일차원 배열은 생략한다.

다차원 배열을 사용하면 효과적으로 데이터를 관리 할수 있다

1차원 2차원 3차원 각각 행  행,열 , 행 열 면 로 구성됨

여러개의 배열을 하나로 묶은것

아래와 같이 이해하면 이해하기 좋다 ( 다만 실제 데이터 내에서는 그림과 같이 저장되지 않으며 처음 이해를 돕기위함)

출처 https://eskeptor.tistory.com/17

 

// 2차원 배열의 선언과 초기화
int[,] array3 = new int[2, 3];  // 2행 3열의 int형 2차원 배열 선언

// 다차원 배열 초기화
array3[0, 0] = 1;
array3[0, 1] = 2;
array3[0, 2] = 3;
array3[1, 0] = 4;
array3[1, 1] = 5;
array3[1, 2] = 6;

// 선언과 함께 초기화
int[,] array2D = new int[3, 4] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };

3차원 배열 -필자는 아직까지 코딩테스트 혹은 구현에 사용해 본적이 없다 3차원 배열은 존재한다 정도로 이해하는중

// 3차원 배열의 선언과 초기화
int[,,] array3D = new int[2, 3, 4] 
{
    { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } },
    { { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } }
};

몇줄 안되지만 봐도 직관적으로 이해가 가지 않는다 보면서 천천히 생각해보면 이해가 가능정도
사용해보기 전까진 이해하기 힘들듯하다

 

@@@컬렉션@@@ -개인적으로 오늘의 핵심이라고 생각됨 

1. 배열과 비슷한 자료 구조 라고 보면 된다. 한번쯤 들어본 큐 와 스택 이 여기에 해당된다 

2. 제공 자료가 위에까진 훌룡했으나 자료구조 부터는 설명이 끔찍하다 

3. 사용하기 위해서는 System.Collections.Generic 네임스페이스를 추가

 

List 리스트 

링크드리스트 

반복문 사용시 count 사용 length x

List<int> numbers = new List<int>(); // 빈 리스트 생성
numbers.Add(1); // 리스트에 데이터 추가
numbers.Add(2);
numbers.Add(3);
numbers.Remove(2); // 리스트에서 데이터 삭제

foreach(int number in numbers) // 리스트 데이터 출력 인트 넘버 값을 넘버스 안에있는값사용
{
    Console.WriteLine(number);
}

Dictionary딕셔너리 

키와 값으로 구성된 데이터 저장 

키와 밸류로 저장된다는것과 대충 어디에 쓰일거 같다 생각은 되지만 불러오는 부분을 이해가 잘안간다 좀 더 찾아볼것

using System.Collections.Generic;

Dictionary<string, int> scores = new Dictionary<string, int>(); // 빈 딕셔너리 생성
scores.Add("Alice", 100); // 딕셔너리에 데이터 추가
scores.Add("Bob", 80);
scores.Add("Charlie", 90);
scores.Remove("Bob"); // 딕셔너리에서 데이터 삭제

foreach(KeyValuePair<string, int> pair in scores) // 딕셔너리 데이터 출력
{
    Console.WriteLine(pair.Key + ": " + pair.Value);
}

Stack 스택

후입 선출 LIFO 구조 

위에만 뚫려있는 바구니 같은 개념 아래 데이터에 접근하기 위해선 위에 다른 데이터가 덮여있다

using System.Collections.Generic;

Dictionary<string, int> scores = new Dictionary<string, int>(); // 빈 딕셔너리 생성
scores.Add("Alice", 100); // 딕셔너리에 데이터 추가
scores.Add("Bob", 80);
scores.Add("Charlie", 90);
scores.Remove("Bob"); // 딕셔너리에서 데이터 삭제

foreach(KeyValuePair<string, int> pair in scores) // 딕셔너리 데이터 출력
{
    Console.WriteLine(pair.Key + ": " + pair.Value);
}

 

Queue 큐 

선입 선출의 파이프 구조 

Queue<int> queue1 = new Queue<int>(); // int형 Queue 선언

// Queue에 요소 추가
queue1.Enqueue(1);
queue1.Enqueue(2);
queue1.Enqueue(3);

// Queue에서 요소 가져오기
int value = queue1.Dequeue(); // value = 1 (가장 먼저 추가된 요소)

 

HashSet

중복되지 않은 요소로만 이루어진 집합

처음 들어봄 잘안쓰일듯함

HashSet<int> set1 = new HashSet<int>();  // int형 HashSet 선언

// HashSet에 요소 추가
set1.Add(1);
set1.Add(2);
set1.Add(3);

// HashSet에서 요소 가져오기
foreach (int element in set1)
{
    Console.WriteLine(element);
}

 

 

리스트와 배열 주의사항

리스트는 동적으로 크기를 조정할 수 있어 배열과는 다르게 유연한 데이터 구조를 구현할 수 있습니다. 하지만, 리스트를 무분별하게 사용하는 것은 좋지 않은 습관입니다.

아래엔 거창하게 적었지만 그냥 사용 할때 배열과 리스트 무엇이 더 유리할지 생각하고 사용하는게 중요하다 정도로 이해하고 넘어간다.

  1. 메모리 사용량 증가: 리스트는 동적으로 크기를 조정할 수 있어 배열보다 많은 메모리를 사용합니다. 따라서, 많은 데이터를 다루는 경우 리스트를 무분별하게 사용하면 메모리 사용량이 급격히 증가하여 성능 저하를 유발할 수 있습니다.
  2. 데이터 접근 시간 증가: 리스트는 연결 리스트(linked list)로 구현되기 때문에, 인덱스를 이용한 데이터 접근이 배열보다 느립니다. 리스트에서 특정 인덱스의 데이터를 찾기 위해서는 연결된 노드를 모두 순회해야 하기 때문입니다. 이러한 이유로, 리스트를 무분별하게 사용하면 데이터 접근 시간이 증가하여 성능이 저하될 수 있습니다.
  3. 코드 복잡도 증가: 리스트는 동적으로 크기를 조정할 수 있기 때문에, 데이터 추가, 삭제 등의 작업이 배열보다 간편합니다. 하지만, 이러한 유연성은 코드 복잡도를 증가시킬 수 있습니다. 리스트를 사용할 때는 데이터 추가, 삭제 등의 작업을 적절히 처리하는 코드를 작성해야 하므로, 코드의 가독성과 유지보수성이 저하될 수 있습니다.