C#문법 - 2

이준호·2023년 11월 7일
0
post-custom-banner

C#문법 종합반 2주차


📌 조건문과 반복문

01.조건문

조건문은 주어진 조건식의 결과에 따라 프로그램의 제어 흐름을 변겅하는 제어문

1) if문, else if문

  • if문은 조건식의 결과에 따라 실행 여부를 결정하는 조건문
  • else문은 if문에서 조건식이 거짓일 경우 실행할 코드를 지정하는 조건문
  • else if문은 if문의 조건식이 거짓일 때, 새로운 조건식을 사용하여 실행 여부를 결정하는 조건문
  • else문은 생략이 가능함.
if (조건식1)
{
    // 조건식1이 참일 경우 실행할 코드
}
else if (조건식2)
{
    // 조건식2가 참일 경우 실행할 코드
}
else
{
    // 모든 조건식이 거짓일 경우 실행할 코드
}

2) 중첩 조건문

하나의 조건문 안에 또 다른 조건문이 포함된 형태의 조건문

int itemLevel = 3; // 아이템 레벨
string itemType = "Weapon"; // 아이템 종류

if (itemType == "Weapon")
{
    if (itemLevel == 1)
    {
        // 레벨 1 무기 효과
        Console.WriteLine("공격력이 10 증가했습니다.");
    }
    else if (itemLevel == 2)
    {
        // 레벨 2 무기 효과
        Console.WriteLine("공격력이 20 증가했습니다.");
    }
    else
    {
        // 그 외 무기 레벨
        Console.WriteLine("잘못된 아이템 레벨입니다.");
    }
}
else if (itemType == "Armor")
{
    if (itemLevel == 1)
    {
        // 레벨 1 방어구 효과
        Console.WriteLine("방어력이 10 증가했습니다.");
    }
    else if (itemLevel == 2)
    {
        // 레벨 2 방어구 효과
        Console.WriteLine("방어력이 20 증가했습니다.");
    }
    else
    {
        // 그 외 방어구 레벨
        Console.WriteLine("잘못된 아이템 레벨입니다.");
    }
}
else
{
    // 그 외 아이템 종류
    Console.WriteLine("잘못된 아이템 종류입니다.");
}

3) switch문

  • switch문은 변수나 식의 결과에 따라 다른 코드 블록을 실행하는 제어문
  • case문을 사용하여 변수나 식의 결과에 따라 실행할 코드를 지정
switch (변수나 식)
{
    case1:
        // 값1이 나온 경우 실행되는 코드
        break;
    case2:
        // 값2가 나온 경우 실행되는 코드
        break;
    // ...
    default:
        // 모든 case문에 해당하지 않는 경우 실행되는 코드
        break;
}

4) 삼항 연산자

3항 연산자는 if문의 간단한 형태로, 조건식의 결과에 따라 두 값을 선택하는 연산자

  • (조건식) ? 참일 경우 값 : 거짓일 경우 값;
int currentExp = 1200;
int requiredExp = 2000;

# 삼항 연산자
string result = (currentExp >= requiredExp) ? "레벨업 가능" : "레벨업 불가능";
Console.WriteLine(result);


# if else 문
if (currentExp >= requiredExp)
{
    Console.WriteLine("레벨업 가능");
}
else
{
    Console.WriteLine("레벨업 불가능");
}





02. 조건문 심화

1) 홀수/짝수 구분하기

Console.Write("번호를 입력하세요: ");
int number = int.Parse(Console.ReadLine());

if (number % 2 == 0)
{
    Console.WriteLine("짝수입니다.");
}
else
{
    Console.WriteLine("홀수입니다.");
}

2) 등급 출력

int playerScore = 100;
string playerRank = "";

switch (playerScore / 10)
{
	case 10:
	case 9:
		playerRank = "Diamond";
		break;
	case 8:
		playerRank = "Platinum";
		break;
	case 7:
		playerRank = "Gold";
		break;
	case 6:
		playerRank = "Silver";
		break;
	default:
		playerRank = "Bronze";
		break;
}

Console.WriteLine("플레이어의 등급은 " + playerRank + "입니다.");

3) 로그인 프로그램

string id = "myid";
string password = "mypassword";

Console.Write("아이디를 입력하세요: ");
string inputId = Console.ReadLine();
Console.Write("비밀번호를 입력하세요: ");
string inputPassword = Console.ReadLine();

if (inputId == id && inputPassword == password)
{
    Console.WriteLine("로그인 성공!");
}
else
{
    Console.WriteLine("로그인 실패...");
}

4) 알파벳 판별 프로그램

Console.Write("문자를 입력하세요: ");
char input = Console.ReadLine()[0];

if (input >= 'a' && input <= 'z' || input >= 'A' && input <= 'Z')
{
    Console.WriteLine("알파벳입니다.");
}
else
{
    Console.WriteLine("알파벳이 아닙니다.");
}





03. 반복문

일련의 명령문을 반복해서 실행하는 제어문

1) for문

  • for문은 초기식, 조건식, 증감식을 사용하여 반복문을 작성
  • 초기식은 반복문이 시작될 때 당 한번 실행
    조건식은 반복문이 실행될 때 마다 평가되며, 참(true)인 경우 반복문이 계속 실행
    증감식은 반복문이 실행될 때마다 실행
for (초기식; 조건식; 증감식)
{
    // 조건식이 참인 경우 실행되는 코드
}

for 문의 예시

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

2) while문

while문은 조건식이 참(true)인 동안 코드블록을 반복적으로 실행

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

while문 예시

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

3) for문 vs while문

  • for문은 반복 횟수를 직관적으로 알 수 있고, 반복 조건을 한 눈에 확인할 수 있어 가독성이 좋다.
  • while문은 반복 조건에 따라 조건문의 실행 횟수가 유동적이며, 이에 따라 코드가 더 간결할 수 있다.
  • 따라서 어떤 반복문을 사용할지는 코드의 흐름에 따라 상황에 맞게 선택해야한다.

4) do-while문

do-while문은 while문과 비슷하지만, 조건식을 검사하기 전에 먼저 코드 블록을 한 번 실행한다.

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

do-while문 예시

int sum = 0;
int num;

do
{
    Console.Write("숫자를 입력하세요 (0 입력 시 종료): ");
    num = int.Parse(Console.ReadLine());
    sum += num;
} while (num != 0);

Console.WriteLine("합계: " + sum);

5) foreach문

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

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

foreach문 예시

string[] inventory = { "검", "방패", "활", "화살", "물약" };

foreach (string item in inventory)
{
    Console.WriteLine(item);
}

6) 중첩반복문

// 이차원 반복문
for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 3; j++)
    {
        Console.WriteLine("i: {0}, j: {1}", i, j);
    }
}

7) Break & Continue

  • break는 반복문을 중지시키는 역할
  • continue는 현재 반복문을 중지하고 다음 반복을 진행하는 역할
for (int i = 1; i <= 10; i++)
{
    if (i % 3 == 0)
    {
        continue; // 3의 배수인 경우 다음 숫자로 넘어감
    }

    Console.WriteLine(i);
    if (i == 7)
    {
        break; // 7이 출력된 이후에는 반복문을 빠져나감
    }
}





04. 반복문 심화

1) 가위바위보

string[] choices = { "가위", "바위", "보" };
string playerChoice = "";
string computerChoice = choices[new Random().Next(0, 3)];

while (playerChoice != computerChoice)
{
    Console.Write("가위, 바위, 보 중 하나를 선택하세요: ");
    playerChoice = Console.ReadLine();

    Console.WriteLine("컴퓨터: " + computerChoice);

    if (playerChoice == computerChoice)
    {
        Console.WriteLine("비겼습니다!");
    }
    else if ((playerChoice == "가위" && computerChoice == "보") ||
             (playerChoice == "바위" && computerChoice == "가위") ||
             (playerChoice == "보" && computerChoice == "바위"))
    {
        Console.WriteLine("플레이어 승리!");
    }
    else
    {
        Console.WriteLine("컴퓨터 승리!");
    }
}

2) 숫자 맞추기

int targetNumber = new Random().Next(1, 101); ;
int guess = 0;
int count = 0;

Console.WriteLine("1부터 100 사이의 숫자를 맞춰보세요.");

while (guess != targetNumber)
{
    Console.Write("추측한 숫자를 입력하세요: ");
    guess = int.Parse(Console.ReadLine());
    count++;

    if (guess < targetNumber)
    {
        Console.WriteLine("좀 더 큰 숫자를 입력하세요.");
    }
    else if (guess > targetNumber)
    {
        Console.WriteLine("좀 더 작은 숫자를 입력하세요.");
    }
    else
    {
        Console.WriteLine("축하합니다! 숫자를 맞추셨습니다.");
        Console.WriteLine("시도한 횟수: " + count);
    }
}





📌 배열과 컬렉션

01. 배열

동일한 자료형의 값들이 연속적으로 저장되는 자료 구조

1) 1차원 배열

  • 동일한 데이터 유형을 가지는 데이터 요소들을 한 번에 모아서 다룰 수 있는 구조
  • 인덱스를 사용하여 요소에 접근 가능
  • 선언된 크기만큼의 공간을 메모리에 할당받음
 // 배열 선언
 데이터_유형[] 배열_이름;
 
 // 배열 초기화
 배열_이름 = new 데이터_유형[크기];
 
 // 배열을 한 줄로 선언 및 초기화
 데이터_유형[] 배열_이름 = new 데이터_유형[크기];
 
 // 배열 요소에 접근
 배열_이름[인덱스] =;= 배열_이름[인덱스];

예시.1

int[] array1 = new int[5];       // 크기가 5인 int형 배열 선언
string[] array2 = new string[3]; // 크기가 3인 string형 배열 선언
int num = 0;

// 배열 초기화
array1[0] = 1;
array1[1] = 2;
array1[2] = 3;
array1[3] = 4;
array1[4] = 5;

num = array1[0];

예시.2

int[] itemPrices = { 100, 200, 300, 400, 500 };
int totalPrice = 0;

for (int i = 0; i < itemPrices.Length; i++)
{
    totalPrice += itemPrices[i];
}

Console.WriteLine("총 아이템 가격: " + totalPrice + " gold");

2) 배열을 활용한 숫자 맞추기 게임

Random random = new Random();  // 랜덤 객체 생성
int[] numbers = new int[3];  // 3개의 숫자를 저장할 배열

// 3개의 랜덤 숫자 생성하여 배열에 저장
for (int i = 0; i < numbers.Length; i++)
{
    numbers[i] = random.Next(1, 10);
}

int attempt = 0;  // 시도 횟수 초기화
while (true)
{
    Console.Write("3개의 숫자를 입력하세요 (1~9): ");
    int[] guesses = new int[3];  // 사용자가 입력한 숫자를 저장할 배열
    
	// 사용자가 입력한 숫자 배열에 저장
    for (int i = 0; i < guesses.Length; i++)
    {
        guesses[i] = int.Parse(Console.ReadLine());
    }
    
	int correct = 0;  // 맞춘 숫자의 개수 초기화
    
    // 숫자 비교 및 맞춘 개수 계산
    for (int i = 0; i < numbers.Length; i++)
    {
        for (int j = 0; j < guesses.Length; j++)
        {
            if (numbers[i] == guesses[j])
            {
                correct++;
                break;
            }
        }
    }
    
	 attempt++;  // 시도 횟수 증가
    Console.WriteLine("시도 #" + attempt + ": " + correct + "개의 숫자를 맞추셨습니다.");
    
	 // 모든 숫자를 맞춘 경우 게임 종료
    if (correct == 3)
    {
        Console.WriteLine("축하합니다! 모든 숫자를 맞추셨습니다.");
        break;
    }
}

3) 다차원 배열

  • 여러 개의 배열을 하나로 묶어 놓은 배열
  • 행과 열로 이루어진 표 형태와 같은 구조
  • 2차원, 3차원 등의 형태의 배열을 의미
  • C#에서는 다차원 배열을 선언할 때 각 차원의 크기를 지정하여 생성

2차원 배열 선언과 초기화

/* 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차원 배열의 선언과 초기화 */
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 } }
};

4) 2차원 배열을 사용하여 게임 맵 구현

int[,] map = new int[5, 5] 
{ 
    { 1, 1, 1, 1, 1 }, 
    { 1, 0, 0, 0, 1 }, 
    { 1, 0, 1, 0, 1 }, 
    { 1, 0, 0, 0, 1 }, 
    { 1, 1, 1, 1, 1 } 
};

for (int i = 0; i < 5; i++)
{
    for (int j = 0; j < 5; j++)
    {
        if (map[i, j] == 1)
        {
            Console.Write("■ ");
        }
        else
        {
            Console.Write("□ ");
        }
    }
    Console.WriteLine();
}





02. 컬렉션

컬렉션(Collection)은 자료를 모아 놓은 데이터의 구조

  • 컬렉션은 배열과 비슷한 자료 구조
  • 배열과는 다르게 크기가 가변적
  • C#에서는 다양한 종류의 컬렉션을 제공
  • 사용하기 위해서는 System.Collections.Generic 네임스페이스 추가

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

2) Dictionary

  • 딕셔너리(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);
}

3) 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 (마지막에 추가된 요소)

4) Queue

Queue는 선입선출(FIFO)구조를 가진 자료 구조

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

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





03. 배열과 리스트

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

  • 메모리 사용량 증가
    리스트는 동적으로 크기를 조정할 수 있어 배열보다 많은 메모리를 사용한다. 따라서, 많은 데이터를 다루는 경우 리스트를 무분별하게 사용하면 메모리 사용량이 급격히 증가하여 성능 저하를 유발할 수 있다.

  • 데이터 접근 시간 증가
    리스트는 연결 리스트(linked list)로 구현되기 때문에, 인덱스를 이용한 데이터 접근이 배열보다 느리다. 리스트에서 특정 인덱스의 데이터를 찾기 위해서는 연결된 노드를 모두 순회해야 하기 때문이다. 이런 이유로, 리스트를 무분별하게 사용하면 데이터 접근 시간이 증가하여 성능이 저하 될 수 있다.

  • 코드 복잡도 증가
    리스트는 동적으로 크기를 조정할 수 있기 때문에, 데이터 추가, 삭제 등의 작업이 배열보다 간편하다. 하지만, 이러한 유연성은 코드 복잡도를 증가시킬 수 있다. 리스트를 사용할 때는 데이터 추가, 삭제 등의 작업을 적절히 처리하는 코드를 작성해야 하므로, 코드의 가독성과 유지보수성이 저하될 수 있다.

리스트를 무분별하게 사용하는 것은 좋지 않은 습관이다. 데이터 구조를 선택할 때는, 데이터의 크기와 사용 목적을 고려하여 배열과 리스트 중 적절한 것을 선택해야 한다.






📌 메서드와 구조체

01. 메서드

  • 메서드(Method)는 일련의 코드 블록으로, 특정한 작업을 수행하기 위해 사용되는 독립적인 기능 단위
  • 코드의 재사용성과 모듈화를 위해 사용되며, 필요할 때 호출하여 실행

메서드의 역할과 중요성

  • 코드의 재사용성 : 메서드를 사용하면 동일한 작업을 반복해서 구현하지 않아도 된다. 필요할 때 메서드를 호출하여 작업을 수행할 수 있다.

  • 모듈화 : 메서드를 사용하여 코드를 작은 단위로 분리하고 관리할 수 있다. 각 메서드는 특정한 기능을 수행하므로 코드의 구조가 더욱 명확해진다.

  • 가독성과 유지보수성 : 메서드를 사용하면 코드가 간결해지고 가독성이 좋아진다. 또한, 코드 수정이 필요한 경우 해당 메서드만 수정하면 되므로 유지보수가 용이하다.

  • 코드의 중복 제거 : 반복적인 작업을 메서드로 묶어서 사용하면 코드 중복을 방지할 수 있다.

  • 코드의 추상화 : 메서드를 통해 작업 단위를 추상화하고, 메서드 이름을 통해 해당 작업이 어떤 역할을 하는지 파악할 수 있다.






02. 메서드 선언과 호출

1) 메서드의 구조&문법

[접근 제한자] [리턴 타입] [메서드 이름]([매개변수])
{
    // 메서드 실행 코드
}
  • 접근 제한자(Access Modifier): 메서드에 접근할 수 있는 범위를 지정한다. 주로 public, private, protected 등을 사용한다.
  • 리턴 타입(Return Type): 메서드가 반환하는 값의 데이터 타입을 지정한다. 반환 값이 없을 경우 void를 사용한다.
  • 메서드 이름(Method Name): 메서드를 호출하기 위해 사용하는 이름이다. 호출할 때 이 이름을 사용한다.
  • 매개변수(Parameters): 메서드에 전달되는 입력 값으로, 필요한 경우 0개 이상의 매개변수를 정의할 수 있다.
  • 메서드 실행에 코드(Method Body): 중괄호({}) 안에 메서드가 수행하는 작업을 구현하는 코드를 작성한다.

예시

// 예시 1: 반환 값이 없는 메서드
public void SayHello()
{
    Console.WriteLine("안녕하세요!");
}

// 예시 2: 매개변수가 있는 메서드
public void GreetPerson(string name)
{
    Console.WriteLine("안녕하세요, " + name + "님!");
}

// 예시 3: 반환 값이 있는 메서드
public int AddNumbers(int a, int b)
{
    int sum = a + b;
    return sum;
}

2) 메서드의 호출 방법

  • 메서드를 호출하기 위해서는 메서드 이름과 필요한 매개변수를 전달하여 호출한다.
  • 호출 시 전달되는 배개변수는 메서드의 매개변수와 순서와 타입이 일치해야 한다.
  • 메서드는 호출되면 해당 메서드의 실행 코드를 수행하고, 필요한 경우 리턴값이 있다면 반환한다.





03. 매개변수와 반환값

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

void PrintLine2(int count)
{
    for (int i = 0; i < count; i++)
    {
        Console.Write("=");
    }
    Console.WriteLine();
}

int Add(int a, int b)
{
    return a + b;
}


[사용 예시]
PrintLine();
PrintLine2(20);

int result = Add(10, 20);
Console.WriteLine(result);





04. 메서드 오버로딩

  • 메서드 오버로딩은 동일한 이름의 메서드를 다양한 매개변수 목록으로 다중 정의하는 개념이다.
  • 매개변수의 개수, 타입, 순서가 다른 여러 메서드를 동일한 이름으로 정의하여 메서드 호출 시 매개변수의 형태에 따라 적절한 메서드가 선택되도록 할 수 있다.
  • 오버로딩은 메서드의 기능이나 작업은 동일하지만 입력값에 따라 다르게 동작해야 할 때 사용된다.
void PrintMessage(string message)
{
    Console.WriteLine("Message: " + message);
}

void PrintMessage(int number)
{
    Console.WriteLine("Number: " + number);
}

// 메서드 호출
PrintMessage("Hello, World!");  // 문자열 매개변수를 가진 메서드 호출
PrintMessage(10);  // 정수 매개변수를 가진 메서드 호출





05. 재귀 호출

  • 재귀 호출은 메서드가 자기 자신을 호출하는 것을 의미한다.
  • 재귀 호출은 문제를 작은 부분으로 분할하여 해결하는 방법 중 하나로, 작은 부분의 해결 방법이 큰 문제의 해결 방법과 동일한 구조를 갖고 있는 경우 적합.
  • 재귀 호출은 호출 스택에 호출된 메서드의 정보를 순차적으로 쌓고, 메서드가 반환되면서 스택에서 순차적으로 제거되는 방식으로 동작
  • 재귀 호출은 복잡한 문제를 단순한 방식으로 해결 가능한 장점
  • 재귀 호출을 사용할 때 주의해야 할 점은 종료 조건을 명확히 정의해야 하며, 종료 조건을 만족하지 못하면 무한히 재귀 호출이 반복되어 스택 오버플로우 등의 오류가 발생할 수 있다.
  • 귀 호출은 메모리 사용량이 더 크고 실행 속도가 드릴 수 있다, 필요한 경우만 적절히 사용하자
void CountDown(int n)
{
    if (n <= 0)
    {
        Console.WriteLine("Done");
    }
    else
    {
        Console.WriteLine(n);
        CountDown(n - 1);  // 자기 자신을 호출
    }
}

// 메서드 호출
CountDown(5);





06. 메서드 활용

1) 메서드를 사용한 코드의 재사용성

  • 메서드는 일련의 작업을 수행하는 코드 블록으로, 반복적으로 사용되는 코드를 메서드로 분리함으로써 코드의 재사용성을 높인다.
  • 동일한 작업을 수행하는 코드를 여러 곳에서 사용해야 할 때, 해당 작업을 메서드로 정의하고 필요한 곳에서 메서드를 호출하여 재사용 할 수 있다.
  • 이를 통해 중복 코드를 제거하고, 코드의 길이를 줄이고, 코드의 가독성유지보수성을 향상 시킨다.

2) 메서드를 활요한 가독성과 유지보수성 개선

  • 메서드는 코드의 일부분을 의미 있는 이름으로 추상화하고, 해당 메서드를 호출함으로써 코드의 의도를 명확히 전달할 수 있다.
  • 긴 코드를 작은 단위로 분리하여 메서드로 정의하면, 코드가 간결해지고 가독성이 향상
  • 코드를 작은 단위로 분히라여 메서드로 관리하면, 유지보수가 용이하다. 특정 기능을 수정하거나 추가해야 할 때, 해당 메서드만 수정하면 되기 때문에 다른 부분에 영향을 주지 않고로 유지보수가 가능.
// 원의 넓이를 계산하는 메서드
double CalculateCircleArea(double radius)
{
    double area = Math.PI * radius * radius;
    return area;
}

// 사각형의 넓이를 계산하는 메서드
double CalculateRectangleArea(double width, double height)
{
    double area = width * height;
    return area;
}

// 메서드 활용
double circleArea = CalculateCircleArea(5.0);
double rectangleArea = CalculateRectangleArea(3.0, 4.0);

Console.WriteLine("원의 넓이: " + circleArea);
Console.WriteLine("사각형의 넓이: " + rectangleArea);





07. 구조체

  • 여러 개의 데이터를 묶어서 하나의 사용자 정의 형식으로 만들기 위한 방법.
  • 구조체는 값 형식(Value Type)으로 분류되며, 데이터를 저장하고 필요한 기능을 제공할 수 있다.
  • 구조체는 struct키워드를 사용하여 선언
  • 구조체의 멤버는 변수와 메서브로 구성될 수 있다.
struct Person
{
    public string Name;
    public int Age;

    public void PrintInfo()
    {
        Console.WriteLine($"Name: {Name}, Age: {Age}");
    }
}

구조체의 사용

  • 구조체는 변수를 선언하여 사용 가능
  • 구조체의 멤버에 접근할 때 . 연산자를 사용
Person person1;
person1.Name = "John";
person1.Age = 25;
person1.PrintInfo();

📌2주차 숙제 : 콘솔 게임 만들기

숫자 맞추기 게임 만들기

    internal class Program
    {
        static void Main()
        {
            Console.Write("숫자 맞추기 게임을 시작합니다. 1에서 100까지의 숫자 중 하나를 맞춰보세요. \n");
            Random random = new Random();
            int randomNumber = random.Next(1, 101);
            int playerNumber = 0;
            int tryCount = 0;

            while(randomNumber != playerNumber)
            {
                Console.Write("숫자를 입력하세요 : ");
                playerNumber = int.Parse(Console.ReadLine());
                tryCount++;

                if (playerNumber < randomNumber) Console.WriteLine("숫자가 작습니다!");
                else if (playerNumber > randomNumber) Console.WriteLine("숫자가 큽니다!");
            }
            Console.WriteLine("축하합니다! {0}번 만에 숫자를 맞추었습니다.", tryCount);
        }
    }

틱택토 게임 만들기

    internal class Program
    {
        static char[] arr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        static int player = 1;
        static int choice;
        static int flag = 0;

        static void Main(string[] args)
        {
            do
            {
                Console.Clear();    // 초기화
                Console.WriteLine("플레이어 1: X   플레이어 2 : O\n");

                if (player % 2 == 0) Console.WriteLine("플레이어 2의 차례\n");
                else Console.WriteLine("플레이어 1의 차례\n");

                Board();    // 판 그리기

                string line = Console.ReadLine();
                bool identify = int.TryParse(line, out choice);

                // 입력값이 제대로 된 값(정수)이라면?
                if (identify == true)
                {
                    // 입력한 숫자의 배열이 O && X로 할당되지 않은 상태라면?
                    if (arr[choice] != 'O' && arr[choice] != 'X')
                    {
                        // 플레이어 순서에 따라 할당.
                        if (player % 2 == 0) arr[choice] = 'O';
                        else arr[choice] = 'X';
                    }
                    else Console.WriteLine("이미 골랐던 숫자 입니다.");
                }
                else Console.WriteLine("제대로 된 수를 입력해 주십시오.");

                flag = CheckWin();  // 승리 조건 체크
                player++;   // 플레이어 순서 변경
            }
            while (flag != 1 && flag != -1);
            {
                if (flag == 1) Console.WriteLine("{0}플레이어 승리!", (player % 2) + 1);
                else Console.WriteLine("비겼습니다!");
            }
        }

        // 보드 그리기
        static void Board()
        {
            Console.Write("     l     l     \n");
            Console.Write("  {0}  l  {1}  l  {2}  \n", arr[1], arr[2], arr[3]);
            Console.Write("_____l_____l_____\n");
            Console.Write("     l     l     \n");
            Console.Write("  {0}  l  {1}  l  {2}  \n", arr[4], arr[5], arr[6]);
            Console.Write("_____l_____l_____\n");
            Console.Write("     l     l     \n");
            Console.Write("  {0}  l  {1}  l  {2}  \n", arr[7], arr[8], arr[9]);
            Console.Write("     l     l     \n");
        }

        // 승리 조건
        static int CheckWin()
        {
            if ((arr[1] == arr[2]) && (arr[2] == arr[3])) return 1;
            else if ((arr[4] == arr[5]) && (arr[5] == arr[6])) return 1;
            else if ((arr[7] == arr[8]) && (arr[8] == arr[9])) return 1;
            else if ((arr[1] == arr[4]) && (arr[4] == arr[7])) return 1;
            else if ((arr[2] == arr[5]) && (arr[5] == arr[8])) return 1;
            else if ((arr[3] == arr[6]) && (arr[6] == arr[9])) return 1;
            else if ((arr[1] == arr[5]) && (arr[5] == arr[9])) return 1;
            else if ((arr[3] == arr[5]) && (arr[5] == arr[7])) return 1;
            else if (arr[1] != '1' && arr[2] != '2' && arr[3] != '3' && arr[4] != '4' && arr[5] != '5'
               && arr[6] != '6' && arr[7] != '7' && arr[8] != '8' && arr[9] != '9') return -1;
            else return 0;
        }

    }
profile
No Easy Day
post-custom-banner

2개의 댓글

comment-user-thumbnail
2024년 5월 14일

블로그 글 잘봤습니다.
질문 한개가 있는데, 부트캠프 참여전에 개발쪽 일을 하셨었나요? 퀄리티가 굉장히 높네요 ..ㄷㄷ

1개의 답글