게임 개발 공부 기록

6일차 - C# 1 (기본 구조~반복문)

00lwt 2025. 1. 27. 20:56

이번주는 C#에 문법에 대해 학습하는 시간이다.

 

▷▶ 학습 내용

1. 기본 구조

using System;

namespace HelloWorld
{
  class program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Hello World!");
    }
  }
}

// 1번째 줄: 네임스페이스를 사용하기 위한 코드. Console 클래스를 사용하기 위해 필요
// 3번째 줄: 코드를 구성하는 데 사용되며 클래스 및 기타 네임스페이스의 컨테이너
// 5번째 줄: 클래스를 정의하는 키워드. 클래스 이름은 Program으로 지정
// 7번째 줄: 프로그램이 시작할 때 자동으로 호출되는 메서드. 프로그램 실행에 필수
// 9번째 줄: 콘솔에 출력할 내용을 지정하는 코드

 

2. 출력

  • Console.WriteLine(출력값): 줄 바꿈 문자열 추가
  • Console.Write(출력값): 줄 바꿈 없음

 

  • Escape Sequence
\\' 작은따옴표(') 삽입
\\" 큰따옴표(") 삽입
\\\\ 역슬래시() 삽입
\\n 새 줄(줄바꿈) 삽입
\\r 현재 줄 맨 앞으로 이동
\\t 탭 삽입
\\b 백스페이스 삽입

 

3. 주석

코드의 설명이나 개발자간의 의사소통을 위해 사용

(코드를 작성하는 과정에서 중요한 역할을 하며, 코드를 작성하기 전에 설계한 내용을 주석으로 작성하면 나중에 코드를 수정할 때 도움이 된다.)

//: 한 줄 주석. 해당 줄 끝까지 주석 처리

/* */: 여러 줄 주석. 시작과 끝을 명시하여 주석 처리

 

4. 변수

데이터(숫자, 문자 등) 를 저장하고 사용하기 위한 할당받은 공간으로, 필요에 따라 데이터를 저장하거나 수정 가능

(예를 들어 게임을 제작할때 플레이어의 재화나 공격력, HP 같은 정보를 저장하기 위해 사용)

1) 변수 선언

자료형 변수명;

int num1;
int num1, num2, num3; // 여러 개의 변수를 동시에 선언

2) 변수 초기화

변수를 선언한 후에는 변수에 어떤 값을 저장할지 정해야 하는데 이것을 초기화라고 한다.

변수이름 = 값;

int num;     // 변수 선언
num = 10;    // 변수 초기화
int num = 10;   // 변수 선언과 초기화를 한 번에 수행
num1 = num2 = num3 = 10; // 한 번에 여러 개의 변수를 초기화
int num1, num2, num3 = 10; (X)

3) 변수명

1. 키워드

이미 예약된 단어들(키워드)은 변수, 메소드, 클래스 등의 이름으로 사용할 수 없다.

abstract  as  base  bool  break  byte  case  catch  char  checked  class  const  continue decimal  default  delegate  do  double  else  enum  event  explicit  extern  false  finally fixed  float  for  foreach  goto  if  implicit  in  int  interface  internal  is  lock long  namespace  new  null  object  operator  out  override  params  private  protected  public readonly  ref  return  sbyte  sealed  short  sizeof  stackalloc  static  string  struct  switch this  throw  true  try  typeof  uint  ulong  unchecked  unsafe  ushort  using  virtual  void volatile  while

2. 식별자

식별자란 변수, 메서드, 클래스, 인터페이스 등에 사용되는 이름이고 키워드와 동일하게 사용할 수 없다.

식별자 사용 규칙

  • 첫 문자는 알파벳, 언더스코어(_)가 올 수 있다.
  • 두번째 문자부터는 알파벳, 언더스코어, 숫자가 올 수 있다.
  • 대소문자를 구분한다.
  • 키워드와 같은 이름으로 사용할 수 없다.
// 좋은 예시
int playerScore;
string playerName;
float itemPrice;

// 나쁜 예시 (`중요` 의미 있는 변수명 짓기)
int x1;  // 변수명이 의미를 알기 어려움
string a; // 변수명이 명확하지 않음

// 오류 예시
int 1stNumber;  // 변수명은 숫자로 시작할 수 없음
string my-name; // 변수명에 하이픈(-)을 사용할 수 없음
float total$;   // 변수명에 특수문자($)를 사용할 수 없음

 

3. 코드 컨벤션

개발자들 사이에서 약속된 코드 작성 규칙으로, 코드의 가독성을 높이고 유지 보수를 쉽게 하기 위해 사용한다.

식별자 표기법

  • PascalCase: 클래스, 메서드, 프로퍼티 이름 등에 사용. 단어의 첫 글자는 대문자로 시작하며, 이후 단어의 첫 글자도 대문자로 표기. ex) ClassName, MethodName, **PropertyName**
  • camelCase: 변수, 매개변수, 로컬 변수 이름 등에 사용. 단어의 첫 글자는 소문자로 시작하며, 이후 단어의 첫 글자는 대문자로 표기. ex) variableName, parameterName, **localVariableName**
  • 대문자 약어: 예외적으로 전체 글자가 모두 대문자인 식별자 ex)  ID, HTTP, FTP

중괄호 위치

  • 중괄호({})는 항상 새로운 줄에서 시작

빈 줄 사용

  • 관련 없는 코드 사이에는 빈 줄을 사용하여 구분
  • 메서드, 클래스 등의 블록 사이에는 두 줄을 띄어씀
class MyClass
{
    // 필드는 camelCase 표기법을 사용합니다.
    private int myField;

    // 프로퍼티는 PascalCase 표기법을 사용합니다.
    public int MyProperty { get; set; }

    // 메서드는 PascalCase 표기법을 사용합니다.
    public void MyMethod()
    {
        if (true)
        {
            // 중괄호는 새로운 줄에서 시작합니다.
        }

        // 코드 블록은 탭(tab) 또는 스페이스(space) 4칸으로 들여씁니다.

        // 관련 없는 코드 사이에는 빈 줄을 사용하여 구분합니다.
				// 블록 사이에는 두 줄을 띄어씁니다.
				
		    /*
		    여러 줄 주석을 사용할 때는
		     / * 를 새로운 줄에서 시작하고,
		     * / 를 새로운 줄에서 끝내도록 합니다.
		    */
		
		    // 한 줄 주석은 이렇게 사용합니다.
		    int a = 10; // 코드 끝에도 한 줄 주석을 사용할 수 있습니다.
		}
}

 

입력

콘솔 입력을 받을 때는 Console.ReadLine이라는 메소드를 사용하여 사용자가 입력한 값을 문자열로 반환한다.

Console.Write("Enter your name: ");
string name = Console.ReadLine(); // wt 입력
Console.WriteLine("Hello, {0}!", name);

[출력]
Enter your name: wt
Hello, wt!

 

var 키워드

var 키워드를 사용하여 변수를 선언하면 변수의 자료형이 컴파일러에 의해 자동으로 결정된다.

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

타인의 코드를 받아서 사용하는데 자료형이 애매한 경우 사용하면 좋다.

 

연산자

1. 산술연산자

숫자를 대상으로 사용되는 연산자

+ 덧셈
- 뺄셈
* 곱셈
/ 나눗셈
% 나머지

 

2. 관계연산자

두 값을 비교하여 참(True) 또는 거짓(False) 값을 반환하는 연산자

== 같음
!= 다름
>
< 작음
>= 크거나 같음
<= 작거나 같음

 

3. 비트연산자

데이터의 비트(bit) 단위로 연산을 수행하는 연산자

& (AND) 두 비트 값이 모두 1일 때 1을 반환
(OR) 두 비트 값 중 하나라도 1일 때 1을 반환
^ (XOR) 두 비트 값이 서로 다를 때 1을 반환
~ (NOT) 비트 값의 보수(complement)를 반환
<< (왼쪽 시프트) 비트를 왼쪽으로 이동
>> (오른쪽 시프트) 비트를 오른쪽으로 이동
int a = 0b1100; // 12 (2진수)
int b = 0b1010; // 10 (2진수)

int and = a & b; // 0b1000 (8)
int or = a | b; // 0b1110 (14)
int xor = a ^ b; // 0b0110 (6)

int c = 0b1011; // 11 (2진수)
int leftShift = c << 2; // 0b101100 (44)
int rightShift = c >> 1; // 0b0101 (5)

int d = 0b1100; // 12 (2진수)
int bit3 = (d >> 2) & 0b1; // 1 (3번째 비트)
d |= 0b1000; // 0b1100 | 0b1000 = 0b1100 (12)

 

4. 복합 대입 연산자

변수에 연산을 수행한 결과를 저장하는 연산자

+= x += y; x = x + y;
-= x -= y; x = x - y;
*= x *= y; x = x * y;
/= x /= y; x = x / y;
%= x %= y; x = x % y;

 

5. 증감 연산자

변수의 값을 1 증가시키거나 감소시키는 연산자

++ 1 증가
-- 1 감소
x++ 변수 사용 후 값 증가
++x 변수 값 증가 후 사용

 

6. 연산자 우선 순위

  1. 괄호 ()
  2. 단항 연산자 (++, --, +, -, ! 등)
  3. 산술 연산자 (*, /, %, +, -)
  4. 시프트 연산자 (<<, >>)
  5. 관계 연산자 (<, >, <=, >=, ==, !=)
  6. 논리 연산자 (&&, ||)
  7. 할당 연산자 (=, +=, -=, *=, /= 등)

 

문자열

문자열 생성

string str1 = "Hello, World!"; // 리터럴 문자열 사용
string str2 = new string('H', 5); // 문자 'H'를 5개로 구성된 문자열 생성
// 출력: Hello, World! hhhhh

 

연결

string str1 = "Hello";
string str2 = "World";
string str3 = str1 + " " + str2;
// 출력: Hello World

 

검색 (IndexOf)

string str = "Hello, World!";
int index = str.IndexOf("World");
// 출력: 7

 

대체 (Replace)

string str = "Hello, World!";
string newStr = str.Replace("World", "Universe");
// 출력: Hello, Universe!

 

변환 (Parse, ToString)

// 문자열을 숫자로 변환
string str = "123";
int num = int.Parse(str);

// 숫자를 문자열로 변환
int num = 123;
string str = num.ToString();

 

포멧팅

string name = "John";
int age = 30;
string message = string.Format("My name is {0} and I'm {1} years old.", name, age);
// or
string message = $"My name is {name} and I'm {age} years old.";
// 출력: My name is John and I'm 30 years old.

 

조건문

if문: 조건식의 결과에 따라 실행 여부를 결정하는 조건문

# 실행할 코드가 여러줄인 경우
if (조건식)
{
    // 조건식이 참일 경우 실행할 코드
}

# 실행할 코드가 한줄인 경우
if (조건식)
    // 조건식이 참일 경우 실행할 코드

 

else문: if 문에서 조건식이 거짓일 경우 실행할 코드를 지정하는 조건문

if (조건식)
{
    // 조건식이 참일 경우 실행할 코드
}
else
{
    // 조건식이 거짓일 경우 실행할 코드
}

 

else if문: if 문의 조건식이 거짓일 때, 새로운 조건식을 사용하여 실행 여부를 결정하는 조건문

if (조건식1)
{
    // 조건식1이 참일 경우 실행할 코드
}
else if (조건식2)
{
    // 조건식2가 참일 경우 실행할 코드
}
else
{
    // 모든 조건식이 거짓일 경우 실행할 코드
}

 

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

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("잘못된 아이템 종류입니다.");
}

 

switch문: 변수나 식의 결과에 따라 다른 코드 블록을 실행하는 제어문으로, case문을 사용하여 변수나 식의 결과에 따라 실행할 코드를 지정

switch (변수나 식)
{
    case 값1:
        // 값1이 나온 경우 실행되는 코드
        break;
    case 값2:
        // 값2가 나온 경우 실행되는 코드
        break;
    // ...
    default:
        // 모든 case문에 해당하지 않는 경우 실행되는 코드
        break;
}

 

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

(조건식) ? 참일 경우 값 : 거짓일 경우 값;

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

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

 

반복문

for문: 초기식, 조건식, 증감식을 사용하여 반복

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

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

 

while문: 조건식이 참(true)인 동안 코드 블록을 반복

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

 

do-while문: while과 비슷하지만 조건식 검사 전에 무조건 1번은 코드 블록을 실행

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

// ex)
int sum = 0;
int num;

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

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

 

foreach문: 배열이나 컬렉션에 대한 반복

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

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

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

 

중첩 반복문

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

 

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이 출력된 이후에는 반복문을 빠져나감
    }
}

 

▷▶ 실습

이름, 나이 입력 받기

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("이름을 입력하세요: ");
            string name = Console.ReadLine();

            Console.WriteLine("나이를 입력하세요: ");
            string age = Console.ReadLine();

            Console.WriteLine($"이름: {name}, 나이: {age}.");
        }
    }
}

 

간단한 사칙연산 계산기

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("첫번째 수를 입력하세요: ");
            string input1 = Console.ReadLine();


            Console.WriteLine("두번째 수를 입력하세요: ");
            string input2 = Console.ReadLine();

            int num1 = int.Parse(input1);
            int num2 = int.Parse(input2);

            Console.WriteLine($"{num1} + {num2} = " + (num1 + num2));
            Console.WriteLine($"{num1} - {num2} = " + (num1 - num2));
            Console.WriteLine($"{num1} * {num2} = " + (num1 * num2));
            Console.WriteLine($"{num1} / {num2} = " + (num1 / num2));
        }
    }
}

 

섭씨 => 화씨 온도 변환기

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("섭씨 온도를 입력하세요: ");
            string input = Console.ReadLine();
            float deg = float.Parse(input);
                        
            Console.WriteLine("화씨 " + ((deg * 9 / 5) + 32) + "도");
        }
    }
}

 

 BMI 계산

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("키를 입력하세요(m): ");
            string input1 = Console.ReadLine();

            Console.WriteLine("몸무게를 입력하세요: ");
            string input2 = Console.ReadLine();

            float m = float.Parse(input1);
            float kg = float.Parse(input2);
                        
            Console.WriteLine(kg / (m * m));
        }
    }
}

 

가위바위보

namespace ConsoleApp1
{
    internal class RSP
    {
        static void Main(string[] args)
        {
            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("컴퓨터 승리!");
                }
            }
        }
    }
}

 

숫자 맞추기

namespace ConsoleApp2
{
    internal class ChoiceNum
    {
        static void Main(string[] args)
        {
            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);
                }
            }
        }
    }
}

 

오늘의 회고

VS코드만 사용하다가 VisualStudio를 사용하려니 스크립트 추가하는 방법도 몰라서 새로 배워야했고 적응하려면 시간이 좀 걸릴 것 같다. 그래도 자동완성 기능이 잘 되어있어 편한 점도 있는 것 같다.

오늘 막혔던 부분은 사소한 부분들이다. Console.WriteLine을 하면 String 형태로 출력이 되는데 계산기를 만들 때 Parse를 이용해서 문자열을 숫자로 바꿔주는 부분을 자꾸 까먹었으며 이를 수정하고 다시 시도 해보는데도 정상적으로 출력되지 않는 것이었다.

생각해보니 출력하는 부분에서 계산을 하려면 괄호 안에서 진행해야 하는데 그걸 까먹어서 문자열 형태 그대로 출력되는 것이었다. 사소한 부분에서 미스가 생기지 않으려면 눈으로만 보는 것이 아닌 반복 숙달이 답인듯 하다.