ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TIL] 2주차 2일 C# 문법 입문 ( 조건문, 반복문, 배열과 컬렉션 )
    개발일지/스파르타 코딩클럽 부트캠프 2024. 4. 23. 22:30

    오늘 배운 내용

    • 조건문과 반복문
    • 배열과 컬렉션
    • 메서드와 구조체
    • 여러 간단한 콘솔 게임 제작

    반복문


    for문

    for (초기식; 조건식; 증감식)
    {
        // 조건식이 참인 경우 실행되는 코드
    }

    for문은 어떻게보면 반복문 중에 가장 많이 쓸텐데

    약간 풀이를 해보자면

    초기식 : 반복문이 시작될 때 한 번만 실행

    조건식 : 조건식이 참(ture)일 경우 반복문 계속 실행

    증감식 : 반복문이 실행될 때마다 실행되는 식

    for (int i = 0; i < 10; i++) 
    {
      Console.WriteLine(i);
    }

    위 코드의 경우에는

    반복문의 첫 실행 때 int i = 0 변수를 만들고

    i 가 10 보다 작을 때마다 반복하며

    반복할 때마다 i 는 1씩 커진다

    따라서 위 코드를 실행해보면

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    가 출력된다.

     

    while문

    while (조건식)
    {
        // 조건식이 참인 경우 실행되는 코드
    }

    while문은 보이는대로 조건식밖에 없어서

    괄호 안의 조건식이 참(true)일 경우 계속해서 실행된다.

    따라서

    while(true)
    {
      //
    }

    이렇게 무한루프도 가능하다.

    while문으로 위 for문의 예시 코드를 똑같이 써보면

    int i = 0;
    while (i < 10)
    {
        Console.WriteLine(i);
        i++;
    }

    이렇게 된다

    먼저 변수 i를 만들어주고

    while문은 i가 10보다 작을때 무한반복 한다.

    코드가 실행할 때마다 i를 출력하며 i는 1씩 증가한다.

     

    for문과 while문의 장단점

     

    for문은 반복 횟수가 직관적으로 보이고, 조건도 한번에 확인되어 가독성이 좋다.

    while문은 반복 조건에 따라서 조건문의 실행 횟수가 유동적이고, 코드가 더 간결할 수 있다.

     

    do-while 문

    do
    {
        // 조건식이 참인 경우 실행되는 코드
    }
    while (조건식);

    do-while문은 while문과 비슷하지만, 조건식을 검사 하기 전에

    코드 블록을 한번 실행하는 반복문이다.

     

    쉽게 말하면 while문의 조건식이 거짓이어도 한 번은 실행된다.

     

    foreach문

     

    foreach문은 배열이나 컬렉션에 대해서 반복문을 작성할 때 사용한다.

    foreach (자료형 변수 in 배열 또는 컬렉션)
    {
        // 배열 또는 컬렉션의 모든 요소에 대해 반복적으로 실행되는 코드
    }

    이건 예시문을 보는게 더 이해가 잘될 것 같다.

    string[] inventory = { "검", "방패", "활", "화살", "물약" };
    
    foreach (string item in inventory)
    {
        Console.WriteLine(item);
    }

    강의자료의 예시문인데 보면

    inventory배열이 있고 검, 방패 등 5가지 아이템이 있다.

    그리고 foreach(string item in inventory) 는

    말 그대로 인벤토리에서 하나씩 꺼내와서 앞의 자료형 변수를 반복한다.

    foreach문은 배열을 하나씩 꺼내서 쓰고 다 쓰면 반복이 종료된다.

    위 코드를 실행시키면

    방패

    화살

    물약

    으로 출력된다.

     

    이차원 반복문

    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            Console.WriteLine("i: {0}, j: {1}", i, j);
        }
    }

    개인적으로 쓸 때마다 헷갈리는 것 같은데

    말 그대로 반복문 안에 반복문을 사용하는 방법이다.

    사용할 때마다 바깥 반복문과 상속된 반복문의 내용이 머릿속에서 뒤죽박죽이 된다..

     

    Break 와 Continue

    for (int i = 1; i <= 10; i++)
    {
        if (i % 3 == 0)
        {
            continue; // 3의 배수인 경우 다음 숫자로 넘어감
        }
    
        Console.WriteLine(i);
        if (i == 7)
        {
            break; // 7이 출력된 이후에는 반복문을 빠져나감
        }
    }

    말 그대로 Continue는 현재 반복만 중지하고 다음 반복으로 넘어간다.

    Break는 반복문 자체를 중지시키고 아예 다음 코드로 넘어간다.

     

    실습으로 가위바위보 게임과 숫자 맞추기 게임을 만들어봤는데

    숫자 맞추기는 과제에도 있었는데 강의를 따라서 만들 때는 쉬웠지만

    역시나 백지 상태에서 혼자 만들려니 고생좀 했다..

    내가 만든 숫자맞추기 게임 코드

    int guess = 0;
    int number = new Random().Next(1, 101); 
    
    Console.WriteLine("1과 100 사이의 숫자를 맞추시오");
    
    while (guess != number)
    {
        Console.Write("정답을 입력하세요: ");
        guess = int.Parse(Console.ReadLine());
    
        if (guess > number)
        {
            Console.WriteLine("Down");
        }
        else if (guess < number)
        {
            Console.WriteLine("up");
        }
        else
        {
            Console.WriteLine("정답!!");
            break;
        }
    }

    조금 더 간략하게 Up Down게임으로 만들어봤다.

     

    배열과 컬렉션


    1차원 배열

     

    먼저 1차원 배열은 동일한 데이터 유형을 가지는 데이터 요소를 한 번에 모아서 다룰 수 있는 구조이다.

    인덱스로 요소에 접근 가능하며, 선언된 크기만큼 공간을 메모리에 할당받는다.

    // 배열 선언
    데이터_유형[] 배열_이름;
    
    // 배열 초기화
    배열_이름 = new 데이터_유형[크기];
    
    // 배열을 한 줄로 선언 및 초기화
    데이터_유형[] 배열_이름 = new 데이터_유형[크기];
    
    // 배열 요소에 접근
    배열_이름[인덱스] = 값;
    값 = 배열_이름[인덱스];

    처음에는 이게 List랑 같은건줄 알았는데 조금 다른 개념이었고

     

    배열도 예시를 보는 편이 이해가 빠른데 내가 가장 이해하기 좋았던 예시는 다음과 같았다.

    // 플레이어의 공격력, 방어력, 체력, 스피드를 저장할 배열
    int[] playerStats = new int[4]; 
    
    // 능력치를 랜덤으로 생성하여 배열에 저장
    Random rand = new Random();
    for (int i = 0; i < playerStats.Length; i++)
    {
        playerStats[i] = rand.Next(1, 11);
    }
    
    // 능력치 출력
    Console.WriteLine("플레이어의 공격력: "  + playerStats[0]);
    Console.WriteLine("플레이어의 방어력: "  + playerStats[1]);
    Console.WriteLine("플레이어의 체력: "    + playerStats[2]);
    Console.WriteLine("플레이어의 스피드: "  + playerStats[3]);

    역시 게임 관련되야지만 이해가 잘 되는건가..?

     

    컬렉션


     

    아까 내가 배열과 헷갈린 List는 컬렉션에 포함되어 있는데

    컬렉션은 배열과 비슷한 자료 구조를 가지며

    배열과는 다르게 크기가 가변적이다.

    C#에서는 다양한 종류의 컬렉션을 제공하며, 사용하려면

    System.Collections.Generic 네임스페이스를 추가해야한다.

    그럼 하나씩 살펴보자

     

    List 

     

    먼저 List는 가변적인 크기를 갖는 배열이고 List를 생성할 때는 List에 담을 자료형을 지정해야한다.

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

    보면 그냥 배열을 만들 때와 조금 다르게

    List<int>로 자료형을 지정해주는 것을 볼 수 있다.

     

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

    먼저 Dictionary<string, int> 식으로 string 키와 int 벨류를 가진 빈 딕셔너리를 생성하고

    그에 맞게 문자 키와 숫자 벨류를 맞춰서 쌍으로 데이터를 저장하는 모습을 볼 수 있다.

     

    Stack

     

    Stack은 후입선출(LIFO) 구조를 가진 자료구조이다.

    Stack<int> stack1 = new Stack<int>();  // int형 Stack 선언
    
    // Stack에 요소 추가
    stack1.Push(1);
    stack1.Push(2);
    stack1.Push(3);
    
    // Stack에서 요소 가져오기
    int value = stack1.Pop(); // value = 3 (마지막에 추가된 요소)

    이게 이해가 잘 안될 수 있는데

    fps게임을 좋아해서 혹시 총에 대해서 좀 안다면

    탄창과 똑같이 생각하면 될 것 같다.

    하나씩 데이터가 쌓이고 맨 마지막에 넣은 데이터부터 나온다.

     

    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 (가장 먼저 추가된 요소)

    Queue는 Stack과 반대로 선입선출이다.

    먼저 넣은 데이터가 먼저 나온다.

     

    HashSet

     

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

     

    배열과 리스트의 차이점

     

    그럼 배열을 왜 사용하지? 무조건 리스트만 사용하면 되는거 아닌가?

    라고 생각할 수 있다.

     

    하지만 리스트는 동적으로 크기를 조정할 수 있어서 배열과는 다르게

    유연한 데이터 구조를 구현할 수 있는 장점이 있지만 너무 무분별하게 사용하면

    배열에 비해서 메모리 사용량이 증가하여 성능 저하를 유발할 수 있고

    데이터 접근시간이 많이 차이나는건 아니지만 배열에 비해서 느리다고 한다.

    그리고 아무래도 코드의 길이도 더 길어지다보니 코드의 복잡도가 증가한다.

     

     

    메서드부터는 내일 TIL에.. 과제하면서 어려웠던 점도 적어야 하는데

    배운점들을 적다보니 너무 내용이 많아졌다..

     

Designed by Tistory.