공부/C#

[C#] 예외처리 try-catch의 이용과 자료구조 Array, List, ArrayList 차이

굴러다니다니 2023. 3. 24. 17:33
728x90

예외처리

if / switch : 값의 예외

try - catch : 흐름의 예외 => 버그가 터져도 코드가 계속 이어져야 될 때 사용

 

try - catch

try { 정상 실행할 코드 }

catch (예외) { 예외 발생시 처리 }

catch (예외2) { 예외2 발생시 처리 }

finally {try든 catch든 꼭 마지막에 실행}

 

try내의 코드에서 예외가 발생할 시 catch에서 처리하고 다시 try가 감싸는 코드를 실행한다.

 

catch절은 try절에서 던질 예외 객체와 같은 형식이어야 한다.

예외를 던질 때는 throw를 사용하기도 한다.

예를 들어 array등의 초기값이 설정이 안되어있으면 비어있는 Null값이 들어있는데 이에 접근하려하면 Null관련 예외처리 많이 발생한다.

string은 null로 선언 안함 (”” Null 둘 다로 되어있을 수도 있어서 그러면 두가지 경우 다 || 걸면서 해야됨 → 귀찮기때문~)


ArrayList : 크기에 상관없이 사용, 동적 할당 가능, 추가 및 삭제도 자유로움, 여러 타입을 동시에 가지고 있을 수 있음 (박싱 / 언박싱) → 여러 데이터 타입을 받는 만큼 느리다

object사용 → 형식 지정 X (var도 형식 지정 X) 랜덤하거나 오브젝트 타입도 랜덤으로 받는 그럴 때나 사용

박싱: 자료형이 정해지지 않은 상황으로 돌아가는거 → 까보고 타입 아는거

 

언박싱: 자료형을 정해주는 걸

값 타입으로 변환

int / string

굳이 자료형 지정해주지 않아도 되는 상황에서는 object 사용 가능

근데 너무 많이 사용하면 박싱 / 언박싱의 반복으로 메모리 효율 구려짐

 

Array: 고정된 배열 크기를 가지며, 같은 타입만 원소로 가진다 - stack (값이 정해져있는건 스택으로 감)

array[0] → 원소값

 

List: 크기가 동적이며, 같은 타입만 원소로 가진다. - heap (값이 정해져있지 않은건 힙에) (힙은 다른 공간이 사용하고 남은 공간에 할당되는 공간인데, 그러면 메인 돌릴 시간이 느려지고 효율 구리니까 배열을 많이 쓰자)

List<type> 변수이름 = new List<type>(); → 리스트의 초반 길이는 0

변수이름.Add(추가); 의 코드로 배열의 뒤에 값을 추가 가능

변수이름.Insert(몇 번째, 추가); 기존에 존재하는 데이터는 뒤로 하나씩 밀려난다

추가 / 삭제가 편하다 (다음 데이터의 포인터를 가지고 있음)

list[0] → 주소값

 


try - catch문을 사용한 예제를 살펴보자.

void try_catch()
        {
            int[] arr = new int[5];
            Random ran = new Random();
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = ran.Next(5);
            }

            try
            {
                for (int i = 0; i < 8; i++)
                {
                    Console.WriteLine(arr[i]);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine("여기도 출력된다. 에러가 나도 try - catch에서 잡고 계속 이어서 진행");
        }

배열의 크기를 5로 선언하고, 랜덤한 값을 넣어주었다.

try내의 문장을 실행하고 여기서 크기를 넘는 값을 출력하라고 했다.

이렇다면 예외가 발생하는데, 이를 catch문에서 ex로 잡고 ex.Message로 예외 오류문을 콘솔창에 출력한다.

catch가 마무리되면 마지막줄 Console 출력 문장도 나온다.

 

*try-catch를 사용하면 에러가 발생되어도 다음 로직으로 넘어갈 수 있다.

 

array와 list를 직접 사용해보자.

static void Main(string[] args)
        {
            string[] array = new string[10];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = "1";
            }
            array = new string[11]; //-> new때문에 안에 넣어놨던 값은 없어짐

            List<string> list = new List<string>();
            for (int i = 0; i < array.Length; i++)
            {
                list.Add("1");
            }
            list.Add("s"); //list는 value를 call하는게 아닌 주소값을 call하는것
            list.Remove("s");
            list.RemoveAt(5); //5번째 인덱스 삭제
            //list.RemoveAll();
            for (int i = 0; i < list.Count; i++)
            {
                Console.WriteLine(list[i]);
            }
        }

string의 배열에 1을 모두 넣어줬다.

만약 array의 크기를 늘리고 싶다면, new로 다시 실행해주며 이는 초기의 값을 모두 재설정하기에 담아두었던 1의 내용이 없어진다.

List의 경우 string타입으로 선언해준뒤, for문을 돌려 Add로 1을 넣어주었다.

추가로 넣고싶다면 동적할당이 가능하기 때문에, list.Add로 넣어줄 수 있고, 지워줄때도 Remove를 사용하면 괄호내의 내용을 찾아서 지운다. (하나만)

RemoveAt을 쓴다면 해당 자리의 원소를 삭제한다.

RemoveAll을 쓰려면 람다의 식을 사용해야 한다.

이를 다시 출력해보면 s가 사라진 것을 확인할 수 있다.

728x90