C# 정리

김민구·2025년 5월 18일
0

C#

목록 보기
15/31

C# 코드 개념 및 예제 정리

1. C# 프로그램의 기본 구조

// using 지시문: System 네임스페이스의 클래스를 사용하기 위해 필요
using System;
// using static 지시문: Console 클래스 이름을 생략하고 정적 멤버 사용 가능
using static System.Console; //

// namespace 선언: 코드를 논리적으로 묶는 단위 (C# 10부터 파일 범위 가능)
namespace Hello //
{
    // class 선언: 실제 프로그램 코드가 작성되는 단위
    class MainApp //
    {
        // 프로그램의 진입점: 프로그램이 시작될 때 가장 먼저 실행
        static void Main(string[] args) //
        {
            // 콘솔에 텍스트 출력
            WriteLine("Hello, World!"); //

            // 명령행 인수를 사용하는 예 (책 예제 일부)
            if (args.Length > 0)
            {
                WriteLine($"Hello, {args}!"); //
            }
        }
    }
}
  • using: 다른 네임스페이스에 정의된 형식(클래스, 구조체 등)을 이름 앞에 네임스페이스를 붙이지 않고 사용할 수 있게 해준다.
  • namespace: 관련 있는 코드들을 그룹화하여 이름 충돌을 방지합니다. C# 10부터는 파일 전체에 적용되는 파일 범위 네임스페이스 선언이 가능해졌다.
  • class: C# 코드를 작성하는 기본 단위 중 하나이며, 객체 지향 프로그래밍의 핵심 요소
  • Main 메서드: C# 프로그램의 시작점 static은 객체 생성 없이도 메서드를 호출할 수 있게 하며, void는 반환 값이 없음을 의미 string[] args는 프로그램 실행 시 전달되는 명령행 인수를 받는다.
  • CLR (Common Language Runtime): C#으로 작성된 프로그램은 CLR 위에서 실행 CLR은 Common Language Specification (CLS) 규격을 따르며, 다양한 언어 간의 상호 운용성을 지원

2. 다양한 데이터 형식

C#은 데이터를 저장하고 다루기 위한 다양한 데이터 형식을 제공

  • 정수 형식: byte, short, int, long 등 부호 있는 정수 형식과 uint 등 부호 없는 정수 형식
    • 정수 리터럴은 자릿수 구분자(_)나 2진수(0b), 16진수(0x)로 표현
    • int a = 1_000_000; // 자릿수 구분자
      byte b = 0b1111_0000; // 2진수 리터럴
      uint c = 0xF0_0000; // 16진수 리터럴
  • 실수 형식: float, double 등이 있습니다. float 리터럴에는 f 또는 F를 붙임
    • float f = 3.14f; // float 리터럴
      double d = 3.1415926535; // double 리터럴
  • Decimal 형식: 금융 계산처럼 높은 정밀도가 필요할 때 사용하며, 리터럴에 m 또는 M을 붙임
    • decimal money = 1000.50m; // decimal 리터럴
  • 논리 형식: bool이 있으며, 참/거짓 (true/false) 값을 가지고, 1바이트 크기를 가짐
    • bool isTrue = true; //
      bool isFalse = false; //
  • 문자 형식: char가 있으며, 작은따옴표(')로 하나의 문자를 표현
    • char initial = 'A'; //
  • 문자열 형식: string이 있으며, 큰따옴표(")로 문자의 나열을 표현, 여러 줄에 걸친 문자열은 @"" 또는 """...""" (C# 8 이상) 구문을 사용할 수 있다.
    • string name = "홍길동"; //
      string multiline = """
          첫 번째 줄
          두 번째 줄
          세 번째 줄
          """; //
  • object 형식: C#의 모든 형식의 최상위 기본 형식으로, 어떤 종류의 데이터도 담을 수 있다.
    • object anyData = 123; // int 값을 담음
      anyData = "Hello"; // string 값을 담음

형 변환 (Type Conversion): 데이터를 다른 형식으로 바꾸는 것을 말한다. 작은 형식에서 큰 형식으로 변환 시에는 데이터 손실 위험이 없어 암시적 형 변환이 일어나지만, 큰 형식에서 작은 형식으로 변환 시에는 명시적 형 변환 (Casting)이 필요하며 오버플로가 발생할 수 있다.

  •         int a = 123;
            long b = a; // 암시적 형 변환
    
            byte x = 100;
            int y = x; // 암시적 형 변환
    
            int i = 255;
            // byte j = i; // 오류 발생 (암시적 변환 불가)
            byte j = (byte)i; // 명시적 형 변환 (byte j = 255)
    
            sbyte sb = (sbyte)a; // sbyte의 최대값 127보다 크므로 오버플로 발생
            ```
    문자열과 숫자 형식을 상호 변환할 때는 `Parse`, `TryParse`, `Convert` 메서드를 사용, 특히 `TryParse`는 변환 성공 여부를 bool 값으로 반환하여 예외 발생 없이 안전하게 변환을 시도할 수 있다.
  •     string strNum = "12345";
        int num1 = int.Parse(strNum); //
    
        string strFloat = "3.14f";
        float floatVal;
        if (float.TryParse(strFloat, out floatVal)) // TryParse 사용 예
        {
            WriteLine($"변환 성공: {floatVal}");
        }
    
        int num2 = Convert.ToInt32("999"); //
        string strFromNum = num2.ToString(); // 숫자를 문자열로
        ```

박싱 (Boxing)과 언박싱 (Unboxing): 값 형식(int, float 등)의 데이터를 object 형식으로 변환하는 것을 박싱, object 형식 데이터를 다시 값 형식으로 변환하는 것을 언박싱이라고 한다.

  •     int num = 10;
        object obj = num; // 박싱
    
        int num2 = (int)obj; // 언박싱
        ```
        
  • 박싱(boxing) = 값타입에서 참조타입으로 변환하는 과정

  • 언박싱(un-boxing) = 참조타입에서 값타입으로 변환하는 과정

3. 상수와 열거 형식

  • 상수 (const): 값을 한 번 할당하면 변경할 수 없는 변수, 선언과 동시에 초기화해야 한다.

    • const int MAX_VALUE = 100; //
      const string GREETING = "Hello"; //
      // MAX_VALUE = 200; // 컴파일 오류 발생
  • 열거 형식 (enum): 연관된 정수형 상수들의 집합에 이름을 붙여 관리할 때 사용, 가독성과 유지보수성을 높임

    • enum DialogResult { YES, NO, CANCEL, CONFIRM, OK } //
      
      DialogResult result = DialogResult.YES; //
      WriteLine((int)DialogResult.OK); // 기본값은 0부터 시작하며 정수형으로 변환 가능
      
      enum ErrorCode : short { None = 0, Unknown = 1, Timeout = 50 } // 기반 형식을 short로 지정 및 값 할당

4. Nullable 형식과 var 키워드

  • Nullable 형식 (?): 값 형식 변수는 기본적으로 null 값을 가질 수 없다. Nullable 형식을 사용하면 값 형식 변수도 null을 가질 수 있게 된다.
    데이터 형식 뒤에 ?를 붙여 선언한다. HasValue 속성으로 null 여부를, Value 속성으로 실제 값을 확인한다.
    * ```csharp
    int? nullableInt = null; // null 허용
    // int nonNullableInt = null; // 오류

        if (nullableInt.HasValue) // null인지 확인
        {
            int value = nullableInt.Value; // 값 가져오기
            WriteLine($"Value is: {value}");
        } else {
            WriteLine("nullableInt is null"); //
        }
    
        nullableInt = 100; // 값 할당 가능
        ```
  • var 키워드: 지역 변수를 선언할 때 사용하며, 컴파일러가 초기화 식을 보고 자동으로 데이터 형식을 유추하게 한다. 코드를 간결하게 만들 수 있지만, 가독성을 위해 적절히 사용해야 한다. 반드시 선언과 동시에 초기화해야 한다. 클래스의 필드에는 사용할 수 없다.

    • var age = 30; // 컴파일러가 int로 유추
      var message = "Hello!"; // 컴파일러가 string으로 유추
      var numbers = new int[] { 1, 2, 3 }; // 컴파일러가 int[]로 유추
      
      // var noValue; // 오류: 초기화 필요

5. 연산자

C#은 다양한 연산자를 제공하여 데이터를 조작한다.

  • 산술 연산자: +, -, *, /, % (나머지).

    • int sum = 10 + 5; // 덧셈
      double division = 7.0 / 2.0; // 나눗셈
      int remainder = 7 % 2; // 나머지
  • 증감 연산자: ++ (1 증가), -- (1 감소). 변수 앞/뒤에 따라 연산 시점이 달라진다.

    • int i = 0;
      i++; // i는 1이 됨
      ++i; // i는 2가 됨
      int a = 10;
      int b = a++; // b는 10, a는 11
      int c = --a; // c는 10, a는 10
  • 문자열 결합 연산자: + 연산자를 사용하여 문자열을 연결할 수 있다.

    • string greeting = "Hello" + " " + "World!"; //
  • 관계 연산자: >, <, >=, <=, == (같다), != (다르다). 두 값의 관계를 비교하여 bool 값을 반환한다.

    • bool isEqual = (5 == 5); // true
      bool isGreater = (10 > 20); // false
  • 논리 연산자: && (AND), || (OR), ! (NOT). bool 값을 가지고 논리 연산을 수행한다.

    • bool condition1 = true;
      bool condition2 = false;
      bool resultAnd = condition1 && condition2; // false
      bool resultOr = condition1 || condition2; // true
      bool resultNot = !condition1; // false
  • 조건 연산자 (삼항 연산자): 조건식 ? 참일_때_값 : 거짓일_때_값 형태. 조건에 따라 두 값 중 하나를 선택한다.

    • int age = 20;
      string status = (age >= 19) ? "성인" : "미성년자"; //
      WriteLine($"나이는 {age}세, 상태는 {status}"); //
  • Null 조건 연산자 (?., ?[]): 객체가 null이 아닐 때만 멤버 접근이나 요소 접근을 수행한다. null이면 뒤의 연산을 수행하지 않고 null을 반환한다.

    • int[] numbers = null;
      // int count = numbers.Length; // numbers가 null이면 예외 발생
      int? count = numbers?.Length; // numbers가 null이면 count는 null이 됨
      WriteLine($"Count: {count}"); // null 출력
      
      numbers = new int[] { 1, 2, 3 };
      count = numbers?.Length; // numbers가 null이 아니므로 count는 3이 됨
      WriteLine($"Count: {count}"); // 3 출력
  • Null 병합 연산자 (??): 왼쪽 피연산자가 null이면 오른쪽 피연산자 값을 반환하고, null이 아니면 왼쪽 피연산자 값을 반환한다.

    • string str = null;
      string result = str ?? "기본값"; // str이 null이므로 "기본값"이 result에 할당됨
      WriteLine(result); // 기본값 출력
      
      str = "실제값";
      result = str ?? "기본값"; // str이 null이 아니므로 "실제값"이 result에 할당됨
      WriteLine(result); // 실제값 출력
  • 할당 연산자: = (대입), +=, -=, *=, /=, %= 등. 연산 후 대입을 동시에 수행한다.

    • int x = 10; // 대입
      x += 5; // x = x + 5; (x는 15)
      x *= 2; // x = x * 2; (x는 30)
  • 비트 연산자: &, |, ^, ~, <<, >> 등. 데이터를 비트 단위로 조작한다.

    • int a = 5;  // 0101
      int b = 3;  // 0011
      int resultAnd = a & b; // 0001 (1)
      int resultOr = a | b;  // 0111 (7)
      int resultXor = a ^ b; // 0110 (6)
      int shifted = a << 1; // 1010 (10)

6. 흐름 제어문

프로그램의 실행 흐름을 제어하는 구문입니다.

  • 조건문:

    • if, else if, else: 조건식의 참/거짓 여부에 따라 코드 블록을 실행한다.
      int number = 10;
      if (number > 0) // 조건식
      {
          WriteLine("양수입니다."); // 조건이 참일 때 실행
      } else if (number < 0) //
      {
          WriteLine("음수입니다."); //
      } else
      {
          WriteLine("0입니다."); //
      }
    • switch: 하나의 변수나 식의 값을 여러 case와 비교하여 해당 블록을 실행합니다. 각 case 끝에는 보통 break를 사용하여 switch 문을 빠져나온다.
      string day = "월";
      switch (day) //
      {
          case "월": //
              WriteLine("월요일입니다."); //
              break; //
          case "화": //
              WriteLine("화요일입니다."); //
              break; //
          default: //
              WriteLine("알 수 없는 요일입니다."); //
              break; //
      }
    • switch 식 (C# 7부터): 더 간결하게 값을 반환하는 형태의 switch 문입니다.
      int score = 85;
      string grade = score switch //
      {
          >= 90 => "A", //
          >= 80 => "B", //
          >= 70 => "C", //
          >= 60 => "D", //
          _ => "F" // 그 외의 경우
      };
      WriteLine($"점수: {score}, 학점: {grade}"); //
  • 반복문: 코드 블록을 여러 번 실행할 때 사용

    • while: 조건식이 참인 동안 코드 블록을 반복 실행한다.
      int count = 5;
      while (count > 0) // 조건식
      {
          WriteLine($"Count: {count}"); //
          count--; //
      }
      // 출력: 5, 4, 3, 2, 1
    • do-while: 코드 블록을 먼저 한 번 실행한 후 조건식을 평가하여 반복 여부를 결정, 최소 한 번은 실행된다.
      int i = 0;
      do //
      {
          WriteLine($"i: {i}"); //
          i++; //
      } while (i < 3); // 조건식
      // 출력: 0, 1, 2
    • for: 초기화 식, 조건식, 반복 식을 사용하여 주로 반복 횟수가 명확할 때 사용한다.
      for (int j = 0; j < 5; j++) // 초기화; 조건식; 반복식
      {
          WriteLine($"j: {j}"); //
      }
      // 출력: 0, 1, 2, 3, 4
      무한 반복은 for (;;) 또는 while (true)와 같이 작성한다.
    • foreach: 배열이나 컬렉션에 포함된 모든 요소에 대해 반복 실행한다.
      string[] fruits = { "Apple", "Banana", "Cherry" };
      foreach (string fruit in fruits) //
      {
          WriteLine(fruit); //
      }
      // 출력: Apple, Banana, Cherry
profile
C#, Unity

0개의 댓글