1. 상수(Constant)

  • 정의: 값을 절대 변경할 수 없는 메모리 공간.
  • 선언 방법:
const 자료형 상수명 = 값;
  • 예시:
const int a = 30; 
const string greeting = "Hello, World!";

2. 열거 형식(Enum)

  • 정의: 종류는 같지만 서로 다른 값을 가지는 상수의 집합.
  • 기반 자료형: 정수 계열만 사용 가능 (byte, sbyte, short, ushort, int, uint, long, ulong, char). 기본값은 int.

a. 선언 방법

enum 열거형식명 : 기반자료형 { 상수1, 상수2 } 
enum 열거형식명 { 상수1 = 값1, 상수2 = 값2 } 
enum 열거형식명 { 상수1 = 값1, 상수2, 상수3 = 값3 }

b. 예시

enum Color { Red = 1, Green = 2, Blue = 3 } 
enum Status : byte { Active = 1, Inactive = 0 }
 

c. 열거형 활용

  • 값 확인:
Console.WriteLine((int)Color.Red); // 출력: 1
  • 열거형 값을 문자열로 출력:
Console.WriteLine(Color.Green); // 출력: Green

3. Nullable 형식

  • 정의: 값이 없을 수 있는 변수 형식.
  • 선언 방법:
데이터형식? 변수이름;

a. 예시

int? a = null; // Nullable 형식 
if (a.HasValue) // 값이 있는지 확인
{
	Console.WriteLine(a.Value); 
} 
else 
{
	Console.WriteLine("No value"); 
}

b. Nullable 속성

  • HasValue: 값이 있는지 확인 (true 또는 false).
  • Value: 변수에 담긴 값 반환.

4. var 형식

  • 정의: 변수에 담긴 데이터에 따라 컴파일러가 자동으로 형식을 지정.
  • 주의사항:
    • 선언과 동시에 값을 초기화해야 함.
    • 지역 변수로만 사용 가능.

예시

var x = 10;        // 컴파일러가 int로 추론
var y = "Hello";   // 컴파일러가 string으로 추론
// var z;           // 오류: 초기화 필요

 


5. 공용 형식 시스템 (CTS)

  • 정의: .NET 프레임워크의 형식 체계 표준.
  • C#의 모든 데이터 형식은 CTS를 기반으로 하며, 다른 .NET 언어들과의 호환성을 보장.
  • 예시:
    • C#의 int는 CTS의 System.Int32에 매핑.
    • C#의 string은 CTS의 System.String에 매핑.

정리

  • 상수: 변경할 수 없는 고정된 값.
  • 열거형: 특정 그룹의 상수를 관리하기 위한 형식.
  • Nullable: 값이 없음을 표현.
  • var: 데이터 형식을 자동 추론.
  • CTS: .NET에서 데이터 형식의 표준을 정의.

1. 데이터 형식 개요

  • 참조 형식: 문자열(string), 오브젝트(object) 형식으로 구분.
  • 값 형식: 숫자 형식, 논리 형식으로 구분.
    • 숫자 형식: 정수 계열, 부동소수점 계열, 소수 계열로 세분화.

2. 정수 계열

정수 데이터를 다루기 위한 형식이며, 크기와 범위가 다릅니다.
효율적인 메모리 사용을 위해 데이터 범위에 맞는 형식을 선택해야 합니다.

데이터 형식설명크기(Byte)범위

byte 부호 없는 정수 1 0 ~ 255
sbyte 부호 있는 정수 1 -128 ~ 127
ushort 부호 없는 정수 2 0 ~ 65,535
short 부호 있는 정수 2 -32,768 ~ 32,767
uint 부호 없는 정수 4 0 ~ 4,294,967,295
int 부호 있는 정수 4 -2,147,483,648 ~ 2,147,483,647
ulong 부호 없는 정수 8 0 ~ 18,446,744,073,709,551,615
long 부호 있는 정수 8 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

양수와 음수 표현: 최상위 비트를 이용하여 0(양수), 1(음수)로 구분.
음수 표현: 2의 보수법

  1. 비트를 반전.
  2. 1을 더함.

예시: -3

  • 00000011 → 비트 반전 → 11111100 → 1 추가 → 11111101

3. 오버플로우와 언더플로우

  • 오버플로우: 데이터가 최대값을 넘으면 0으로 순환.
  • 언더플로우: 데이터가 최소값을 넘으면 최대값으로 순환.
csharp
코드 복사
byte a = 255; a++; // 0

4. 부동소수점 계열

유리수와 실수를 표현하는 데이터 형식.
정수 계열보다 표현 범위가 넓지만 정확도 손실이 있을 수 있음.

데이터 형식설명크기(Byte)범위

float 단일 정밀도 부동소수점 (7자리) 4 ±3.402823e38
double 복수 정밀도 부동소수점 (15~16자리) 8 ±1.79769313486232e308
decimal 29자리 고정소수점 16 매우 정밀한 소수값 표현

 


5. 논리 형식 계열

참과 거짓을 표현.

데이터 형식설명크기(Byte)범위

bool 논리 값 1 true, false

6. 문자와 문자열 형식

  • 문자(char): 단일 문자, 작은 따옴표 사용.
char c = 'A';
  • 문자열(string): 여러 문자의 집합, 큰따옴표 사용.
string s = "Hello";

7. Object 형식

  • 모든 데이터 형식의 조상.
  • 참조 형식이며, 힙(Heap)에 데이터를 저장.

8. 박싱(Boxing)과 언박싱(Unboxing)

  • 박싱: 값 형식 → 참조 형식(object)로 변환.
int a = 20; 
object o = a; // 박싱
  • 언박싱: 참조 형식(object) → 값 형식으로 변환.
object o = 20; 
int a = (int)o; // 언박싱

9. 데이터 크기

  • bit: 0과 1을 표현하는 최소 단위.
  • 니블: 4비트.
  • 바이트(byte): 8비트.
  • 워드(word): CPU의 데이터 처리 단위(16비트 이상).

10. 데이터 구조

  • 필드: 데이터베이스의 열(Column).
  • 레코드: 데이터베이스의 행(Row).
  • 파일: 레코드의 집합.
  • 데이터베이스: 파일의 집합.

1. 변수란 무엇인가?

  • 코드 관점: 값을 대입하거나 변경할 수 있는 요소.
  • 메모리 관점: 데이터를 담는 일정 크기의 공간. 데이터 형식에 따라 크기가 달라집니다.
  • 수학적 관점: 변하는 값을 가진 요소.

컴퓨터에서 변수를 사용하려면 변수 선언이 필요합니다.
변수 선언은 컴파일러에게 필요한 메모리 공간을 예약하도록 지시하는 과정입니다.

int x; // 변수 선언
x = 100; // 데이터 할당
 

2. 메모리와 변수의 관계

변수를 선언하면 메모리 공간이 할당되고, 값을 대입하면 해당 공간에 데이터가 저장됩니다.

예시:

int x = 100;

위 코드는 선언과 동시에 값을 할당한 경우로, 변수 x의 메모리 공간에 100이 저장됩니다.


3. 값 형식(Value Type)과 참조 형식(Reference Type)

변수는 값 형식참조 형식으로 나뉩니다.

a. 값 형식 (Value Type)

  • 데이터를 스택(Stack) 메모리 영역에 저장.
  • 코드 블록이 끝나면 자동으로 제거됩니다.
  • 저장 및 제거 과정: 위 코드에서 b가 먼저 제거되고, 다음으로 a가 제거됩니다.
  • {
        int a = 100;
        int b = 200;
    }

b. 참조 형식 (Reference Type)

  • 데이터는 힙(Heap)에 저장되고, 스택은 힙의 메모리 주소를 참조합니다.
  • 코드 블록이 끝나도 힙에 데이터는 남아 있습니다.
  • 힙의 데이터를 제거하려면 **가비지 컬렉터(Garbage Collector)**가 필요합니다.

예시:

object a = 10;
  • 스택: 변수 a와 메모리 주소값 (&2000) 저장.
  • : 데이터 10이 주소 2000에 저장.

4. 변수의 종류

a. 전역 변수 (Global Variable)

  • 클래스 내부에서 선언되며, 클래스 객체가 살아있는 동안 참조 가능합니다.
  • 기본값이 자동으로 할당됩니다. (예: int 타입은 0)

예시:

class Example
{
    int globalVar; // 기본값 0 자동 할당
}

b. 지역 변수 (Local Variable)

  • 메서드 내에서 선언되며, 메서드 호출이 끝나면 메모리에서 제거됩니다.
  • 기본값이 자동으로 할당되지 않으므로, 초기화를 해야 사용 가능합니다.

예시:

public void Method()
{
    int localVar;
    localVar = 100; // 초기화 필수
}

5. 메모리 구조 요약

  • 스택(Stack): 값 형식 데이터를 저장하며, 데이터가 코드 블록이 끝나면 제거됩니다.
  • 힙(Heap): 참조 형식 데이터를 저장하며, 데이터가 명시적으로 제거되지 않으면 계속 유지됩니다.

1. 증감 연산자

  • 전위 증가 연산자 (++a):
    변수를 증가시킨 후 해당 구문을 실행.
  • 후위 증가 연산자 (a++):
    해당 구문을 실행한 후 변수를 증가.

예시:

int a = 10; 
Console.WriteLine(a++); // 출력: 10 (증가는 이후에 실행) 
Console.WriteLine(++a); // 출력: 12 (증가는 먼저 실행)

2. 관계 연산자

  • 논리형식(bool) 결과 반환 (true 또는 false).연산자설명 
    == 두 피연산자가 같으면 true.
    != 두 피연산자가 다르면 true.

예시:

int x = 5, y = 10; 
Console.WriteLine(x == y); // 출력: False 
Console.WriteLine(x != y); // 출력: True

3. 논리 연산자

  • AND (&&): 두 조건이 모두 참일 때 true.
  • OR (||): 하나라도 참이면 true.
  • NOT (!): 논리값을 반전.

예시:

bool a = true, b = false; 
Console.WriteLine(a && b); // 출력: False 
Console.WriteLine(a || b); // 출력: True 
Console.WriteLine(!a); // 출력: False

4. 조건 연산자 (?:)

  • 형식: 조건식 ? 참일 때 값 : 거짓일 때 값.
  • 조건식의 결과는 논리값(true 또는 false).

예시:

int a = 30; 
string result = a == 30 ? "삼십" : "삼십 아님"; 
Console.WriteLine(result); // 출력: 삼십

5. Null 조건부 연산자 (?.)

  • 형식: 객체?.멤버 또는 객체?[인덱스].
  • 객체가 null이면 null 반환, 아니면 멤버에 접근.

예시:

class Foo 
{ 
	public int Member { get; set; } 
} 
Foo foo = null; 
int? bar = foo?.Member; // foo가 null이므로 bar는 null

6. Null 병합 연산자 (??)

  • 형식: op1 ?? op2.
  • op1이 null이면 op2 반환, 그렇지 않으면 op1 반환.

예시:

string message = null; 
string result = message ?? "Default message"; 
Console.WriteLine(result); // 출력: Default message​

7. 비트 연산자

  • 왼쪽 시프트 (<<): 비트를 왼쪽으로 이동.
  • 오른쪽 시프트 (>>): 비트를 오른쪽으로 이동.
  • XOR (^): 두 비트가 다를 때 1.
  • NOT (~): 모든 비트를 반전.

시프트 연산 예시:

int a = 240, b = 2; 
Console.WriteLine(a << b); // 출력: 960 (240 * 2^2) 
Console.WriteLine(a >> b); // 출력: 60 (240 / 2^2)​

정리

  • 증감 연산자: 전위와 후위의 차이를 이해.
  • 관계 및 논리 연산자: 분기와 조건 설정에 필수.
  • 조건 연산자: 간단한 조건문 처리에 유용.
  • Null 조건부 연산자: 객체가 null인지 확인 후 멤버 접근.
  • Null 병합 연산자: null 기본값을 처리하는 데 활용.
  • 비트 연산자: 낮은 수준의 데이터 조작에 필수.
 

1. 데이터 형식 변환이란?

  • 정의: 변수를 다른 데이터 형식의 변수로 옮겨 담는 것을 변환이라고 합니다.
  • 변환에는 두 가지 방식이 있습니다:
    1. 암시적 변환: 데이터 손실이 없는 경우 자동으로 수행.
    2. 명시적 변환: 데이터 손실 가능성이 있는 경우 개발자가 명시적으로 수행.

2. 정수 데이터 형식 변환

a. 작은 정수 → 큰 정수
  • 변환 시 문제가 발생하지 않습니다.
  • 예: byte → int
b. 큰 정수 → 작은 정수
  • 데이터가 범위를 초과하면 오버플로우 발생.
  • 예: int → byte 
int a = 256;
byte b = (byte)a; // b = 0 (오버플로우 발생)

c. 부호 있는 정수 → 부호 없는 정수

  • 음수 값을 변환하면 언더플로우가 발생.
  • 예: int → uint
int a = -1;
uint b = (uint)a; // b = 4294967295 (언더플로우)

3. 부동소수점 데이터 형식 변환

a. 부동소수점 → 정수

  • 소수점 이하를 버리고 정수 값만 남습니다. 반올림은 하지 않습니다.
  • 예:
     
double d = 3.9; 
int i = (int)d; // i = 3

b. float ↔ double 변환

  • 부동소수점은 소수를 이진수로 저장하므로 정밀도 손실이 있을 수 있습니다.
  • 예:
float f = 1.123456789f; // 제한된 정밀도 (7자리)
double d = f; // 정밀도가 손상될 수 있음

4. 문자와 숫자 변환

a. 문자 → 숫자

  • Parse() 또는 Convert.ToInt32() 메소드를 사용.
  • 예:
string s = "123"; 
int i = int.Parse(s); // i = 123

b. 숫자 → 문자

  • ToString() 메소드를 사용.
  • 예:
int i = 123; 
string s = i.ToString(); // s = "123"

 


5. 변환의 주의점

  • 정수 변환: 범위 초과 여부 확인 (오버플로우/언더플로우).
  • 부동소수점 변환: 정밀도 손실 가능성 이해.
  • 문자와 숫자 변환: 잘못된 입력 처리 대비 (예외 처리).

1. 메소드란?

  • 정의: 특정 작업을 수행하는 일련의 코드를 하나의 이름으로 묶은 것.
  • 다양한 언어에서의 표현:
    • C++: 함수 (Function)
    • 파스칼: 프로시저 (Procedure)
    • 비주얼 베이직: 서브 루틴 (Subroutine)

2. 메소드 선언 형식

한정자 반환형식 메소드이름(매개변수)
  • 한정자: 메소드의 속성 정의 (예: public, static).
  • 반환형식: 메소드가 반환하는 데이터의 형식.
  • 메소드 이름: 호출 시 사용할 이름.
  • 매개변수: 메소드 실행에 필요한 입력값.

예시:

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

3. return 키워드

  • 프로그램의 흐름을 호출자로 되돌립니다.
  • 반환형식이 존재할 경우 반환값과 반환형식이 일치해야 합니다.

예시 (재귀 호출):

public int Fibonacci(int n)
{
    if (n < 2)
        return n;
    return Fibonacci(n - 1) + Fibonacci(n - 2);
}

4. 매개변수 전달 방식

a. 값에 의한 전달

  • 매개변수로 데이터를 복사하여 전달.
public void Swap(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
}

int x = 3, y = 4;
Swap(x, y);
Console.WriteLine($"{x}, {y}"); // 결과: 3, 4 (값이 변경되지 않음)

b. 참조에 의한 전달 (ref)

  • 매개변수를 참조하여 원본 데이터를 변경.
public void Swap(ref int a, ref int b)
{
    int temp = a;
    a = b;
    b = temp;
}

int x = 3, y = 4;
Swap(ref x, ref y);
Console.WriteLine($"{x}, {y}"); // 결과: 4, 3

c. 출력 전용 매개변수 (out)

  • 메소드에서 결과를 출력하는 용도로 사용.
public void Divide(int a, int b, out int quotient, out int remainder)
{
    quotient = a / b;
    remainder = a % b;
}

int quotient, remainder;
Divide(10, 3, out quotient, out remainder);
Console.WriteLine($"Quotient: {quotient}, Remainder: {remainder}");

5. 메소드 오버로딩

  • 같은 이름의 메소드를 매개변수의 타입, 개수로 구분하여 여러 개 정의.
public int Add(int a, int b)
{
    return a + b;
}

public double Add(double a, double b)
{
    return a + b;
}​

6. 가변 길이 매개변수 (params)

  • 개수가 유동적인 매개변수를 받을 때 사용.
public int Sum(params int[] numbers)
{
    int sum = 0;
    foreach (int num in numbers)
        sum += num;
    return sum;
}

int result = Sum(1, 2, 3, 4);
Console.WriteLine(result); // 출력: 10

7. 명명된 매개변수

  • 매개변수 이름을 명시적으로 지정하여 호출.
public void PrintInfo(string name, int age)
{
    Console.WriteLine($"Name: {name}, Age: {age}");
}

PrintInfo(age: 30, name: "Alice");

8. 선택적 매개변수

  • 기본값을 제공하여 필요에 따라 값을 전달하지 않을 수 있음.
public void PrintMessage(string message = "Hello, World!")
{
    Console.WriteLine(message);
}

PrintMessage(); // 출력: Hello, World!
PrintMessage("Hi!"); // 출력: Hi!

9. 로컬 함수

  • 메소드 내부에 정의된 함수로, 해당 메소드에서만 사용 가능.
public void Calculate()
{
    int counter = 0;

    void LocalFunction(int a, int b)
    {
        counter++;
        Console.WriteLine($"{a} + {b} = {a + b}, Counter: {counter}");
    }

    LocalFunction(1, 2);
    LocalFunction(3, 4);
}

정리

  • 메소드는 코드를 재사용하고 모듈화하기 위한 핵심 도구.
  • 다양한 매개변수 전달 방식 (ref, out, params)과 유연한 호출 방식을 제공.
  • 로컬 함수와 메소드 오버로딩으로 코드의 가독성과 효율성을 높일 수 있음.

1. 객체 지향 프로그래밍 (OOP)

  • 정의: 코드 내의 모든 것을 객체로 표현하는 프로그래밍 패러다임.
  • 객체(Object): 세상의 모든 것을 지칭하며, 속성과 기능으로 이루어집니다.
    • 속성: 데이터를 통해 표현 (예: 다리, 귀).
    • 기능: 메소드를 통해 표현 (예: 뛰기, 듣기).

2. 클래스(Class)

  • 정의: 객체를 생성하기 위한 청사진(모형).
  • 예시:
class Cat
{
    public string Color; // 데이터: 속성
    public void Meow()   // 메소드: 기능
    {
        Console.WriteLine($"{Color} 고양이: 야옹");
    }
}

Cat kitty = new Cat();  // Cat 클래스의 객체 생성

3. 클래스와 객체의 관계

  • 클래스는 복합 데이터 형식의 참조 형식입니다.
  • **객체(Object)**는 클래스의 인스턴스(실체)입니다.
    Cat kitty = new Cat();
    • new: 생성자를 호출해 객체를 힙(Heap)에 생성.
    • kitty: 생성된 객체의 참조를 저장.

4. 생성자(Constructor)와 종료자(Destructor)

a. 생성자

  • 클래스와 같은 이름을 가지며 객체 생성 시 호출됩니다.
  • 객체를 초기화하기 위한 용도로 사용됩니다.
  • 예시:
class Cat
{
    public string Color;

    // 생성자
    public Cat(string color)
    {
        Color = color;
    }

    public void Meow()
    {
        Console.WriteLine($"{Color} 고양이: 야옹");
    }
}

Cat kitty = new Cat("검은색"); // 생성자 호출

b. 종료자

  • 객체가 소멸될 때 호출되는 특별한 메소드.
  • 매개변수나 한정자가 없으며 오버로딩 불가능.
  • CLR의 가비지 컬렉터가 객체의 소멸 시점을 판단해 호출.
  • 예시:
class Cat
{
    ~Cat()
    {
        Console.WriteLine("Cat 객체가 소멸되었습니다.");
    }
}

5. 정적 필드와 메소드 (Static)

  • static 한정자를 사용해 클래스 자체에 소속되는 필드와 메소드.
  • 특징:
    • 클래스의 모든 인스턴스가 공유.
    • 객체를 생성하지 않고 호출 가능.
  • 예시:
class Counter
{
    public static int Count = 0;

    public static void Increment()
    {
        Count++;
    }
}

Counter.Increment(); // 객체 없이 호출
Console.WriteLine(Counter.Count); // 출력: 1

6. 클래스의 기본 구조

class ClassName
{
    // 필드 (Field): 데이터 저장
    public string FieldName;

    // 생성자 (Constructor): 객체 초기화
    public ClassName(string value)
    {
        FieldName = value;
    }

    // 메소드 (Method): 동작 정의
    public void MethodName()
    {
        Console.WriteLine($"Field: {FieldName}");
    }

    // 정적 메소드 (Static Method)
    public static void StaticMethod()
    {
        Console.WriteLine("This is a static method.");
    }
}

정리

  • 클래스는 객체를 생성하기 위한 청사진으로, 속성(필드)과 기능(메소드)을 포함.
  • 객체는 클래스의 인스턴스로, new 키워드를 통해 생성.
  • 생성자는 객체를 초기화하고, 종료자는 객체 소멸 시 호출.
  • 정적 필드/메소드는 클래스 자체에 속하며, 모든 인스턴스가 공유 가능.

1. 객체와 다형성

  • 다형성(Polymorphism): 객체가 여러 형태를 가질 수 있는 성질.
    • 하위 형식 다형성: 파생 클래스가 기반 클래스의 메소드를 재정의하여 다양한 동작을 실행.

a. 예제: 다형성

class ArmorSuite
{
    public virtual void Initialize()
    {
        Console.WriteLine("ArmorSuite: 초기화");
    }
}

class IronMan : ArmorSuite
{
    public override void Initialize()
    {
        base.Initialize(); // 기반 클래스 메소드 호출
        Console.WriteLine("IronMan: 초기화");
    }
}

2. 메소드 오버라이딩

  • 조건:
    • 메소드는 virtual 키워드로 선언되어야 함.
    • override 키워드로 재정의.
    • private 메소드는 오버라이딩 불가.

a. 예제

class BaseClass
{
    public virtual void MyMethod()
    {
        Console.WriteLine("BaseClass: MyMethod");
    }
}

class DerivedClass : BaseClass
{
    public override void MyMethod()
    {
        Console.WriteLine("DerivedClass: MyMethod");
    }
}

b. 메소드 감추기 (new 키워드)

  • 기반 클래스의 메소드를 감추고 파생 클래스 메소드만 표시.
class BaseClass
{
    public void MyMethod()
    {
        Console.WriteLine("BaseClass: MyMethod");
    }
}

class DerivedClass : BaseClass
{
    public new void MyMethod()
    {
        Console.WriteLine("DerivedClass: MyMethod");
    }
}

c. 메소드 봉인 (sealed 키워드)

  • 오버라이딩된 메소드의 추가 재정의를 금지.
class BaseClass
{
    public virtual void MyMethod()
    {
        Console.WriteLine("BaseClass: MyMethod");
    }
}

class DerivedClass : BaseClass
{
    public sealed override void MyMethod()
    {
        Console.WriteLine("DerivedClass: MyMethod");
    }
}

3. 중첩 클래스

  • 클래스 안에 선언된 클래스.
  • 외부 클래스의 모든 멤버(심지어 private)에 접근 가능.

예제

class OuterClass
{
    private int number = 42;

    class NestedClass
    {
        public void DisplayNumber(OuterClass outer)
        {
            Console.WriteLine($"Number: {outer.number}");
        }
    }
}

4. 분할 클래스

  • partial 키워드를 사용하여 여러 파일에 걸쳐 하나의 클래스를 정의.
  • 코드 관리 및 분할 작업에 유용.

예제

partial class MyClass
{
    public void Method1()
    {
        Console.WriteLine("Method1");
    }
}

partial class MyClass
{
    public void Method2()
    {
        Console.WriteLine("Method2");
    }
}

5. 확장 메소드

  • 기존 클래스의 기능을 확장하는 메소드.
  • 정적 클래스와 this 키워드를 활용.

예제

public static class StringExtensions
{
    public static string ToUpperFirst(this string input)
    {
        if (string.IsNullOrEmpty(input)) return input;
        return char.ToUpper(input[0]) + input.Substring(1);
    }
}

// 사용
string name = "john";
Console.WriteLine(name.ToUpperFirst()); // 출력: John

6. 클래스 vs 구조체

특징클래스구조체

키워드 class struct
형식 참조 형식 값 형식
복사 방식 얕은 복사 깊은 복사
생성 방법 new 키워드 필요 선언만으로 생성 가능
생성자 매개변수 없는 생성자 가능 불가능
상속 가능 불가능

예제

struct Point
{
    public int X;
    public int Y;

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

Point p1 = new Point(10, 20);
Console.WriteLine($"X: {p1.X}, Y: {p1.Y}");

7. 튜플 (Tuple)

  • 여러 필드를 담을 수 있는 구조체.
  • 임시적으로 복합 데이터를 다룰 때 사용.

a. 명명되지 않은 튜플

var tuple = (123, 789);
Console.WriteLine(tuple.Item1); // 출력: 123
Console.WriteLine(tuple.Item2); // 출력: 789

b. 명명된 튜플

var person = (Name: "John", Age: 30);
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");

정리

  • 객체는 클래스의 인스턴스이며, 다형성, 오버라이딩, 중첩 클래스, 확장 메소드 등을 통해 강력한 유연성을 제공합니다.
  • 구조체는 값 형식으로 메모리 관리 및 간단한 데이터 저장에 유용.
  • 튜플은 임시적인 복합 데이터를 간단히 표현.

1. 접근 한정자 (Access Modifiers)

C#의 접근 한정자는 클래스, 메소드, 변수 등의 멤버에 대한 접근 범위를 지정합니다.


a. public

  • 정의:
    멤버가 동일한 어셈블리의 모든 코드와 다른 어셈블리를 참조하는 코드에서도 접근 가능.
  • 예시:
public class Example
{
    public int Value = 10;

    public void Display()
    {
        Console.WriteLine($"Value: {Value}");
    }
}

b. private

  • 정의:
    멤버가 선언된 클래스 또는 구조체 내부에서만 접근 가능.
  • 예시:
class Example
{
    private int Value = 10;

    private void Display()
    {
        Console.WriteLine($"Value: {Value}");
    }
}

c. protected

  • 정의:
    멤버가 같은 클래스 및 파생된 클래스에서만 접근 가능.
  • 예시:
class Base
{
    protected int Value = 10;
}

class Derived : Base
{
    public void ShowValue()
    {
        Console.WriteLine($"Value: {Value}");
    }
}

d. internal

  • 정의:
    멤버가 동일한 어셈블리 내에서 접근 가능하며, 다른 어셈블리에서는 불가능.
  • 예시:
     
internal class Example
{
    internal int Value = 10;
}

e. protected internal

  • 정의:
    멤버가 선언된 어셈블리의 모든 코드와 다른 어셈블리의 파생 클래스에서 접근 가능.
  • 예시:
public class Base
{
    protected internal int Value = 10;
}

f. private internal

  • 정의:
    멤버가 선언된 어셈블리 내부의 코드 및 해당 클래스에서 파생된 클래스 내에서만 접근 가능.
  • 예시:
class Example
{
    private protected int Value = 10;
}

2. 메소드 반환 형식

a. int 반환 형식

  • 반환값이 int 타입이어야 함.
  • 예시:
public int Add(int a, int b)
{
    return a + b;
}

b. string 반환 형식

  • 반환값이 string 타입이어야 함.
  • 예시:
public string Greet(string name)
{
    return $"Hello, {name}!";
}

c. void 반환 형식

  • 반환값이 없음을 의미.
  • 예시:
public void PrintMessage(string message)
{
    Console.WriteLine(message);
}

3. 예제 코드: 다양한 접근 한정자와 반환 형식

public class Example
{
    // public 멤버
    public int PublicValue = 10;

    // private 멤버
    private int PrivateValue = 20;

    // protected 멤버
    protected int ProtectedValue = 30;

    // internal 멤버
    internal int InternalValue = 40;

    // protected internal 멤버
    protected internal int ProtectedInternalValue = 50;

    // private protected 멤버
    private protected int PrivateProtectedValue = 60;

    // 메소드 반환 형식 예제
    public int Add(int a, int b) => a + b;
    public string Greet(string name) => $"Hello, {name}!";
    public void PrintMessage(string message) => Console.WriteLine(message);
}

정리

  • 접근 한정자:
    • public: 모든 코드에서 접근 가능.
    • private: 동일 클래스 내에서만 접근 가능.
    • protected: 동일 클래스 및 파생 클래스에서 접근 가능.
    • internal: 동일 어셈블리에서만 접근 가능.
    • protected internal: 어셈블리 내 모든 코드와 다른 어셈블리의 파생 클래스에서 접근 가능.
    • private internal: 어셈블리 및 파생 클래스에서만 접근 가능.
  • 메소드 반환 형식:
    • int, string 등의 반환값 타입에 맞는 값을 반환해야 하며, void는 반환값이 없음.

1. 분기문

  • 정의: 프로그램의 흐름을 조건에 따라 변화시키는 구문.

a. if문

  • 하나의 조건을 평가하여 참/거짓에 따라 실행.
  • 형식:
if (조건식) 
{
	// 조건이 참일 때 실행 
} 
else 
{ 
	// 조건이 거짓일 때 실행 
}
  • else if: 추가적인 조건 평가 가능.
if (조건식1)
{
    // 조건1이 참일 때 실행
}
else if (조건식2)
{
    // 조건2가 참일 때 실행
}
else
{
    // 모든 조건이 거짓일 때 실행
}

b. switch문

  • 하나의 조건식을 다양한 결과와 비교.
  • 형식:
switch (조건식)
{
    case 상수1:
        // 실행 코드
        break;
    case 상수2:
        // 실행 코드
        break;
    default:
        // 모든 조건이 거짓일 때 실행
        break;
}
  • 예시:
object obj = 123;
switch (obj)
{
    case int i:
        Console.WriteLine($"정수: {i}");
        break;
    case string s:
        Console.WriteLine($"문자열: {s}");
        break;
    default:
        Console.WriteLine("알 수 없는 타입");
        break;
}

2. 반복문 (루프문)

  • 정의: 특정 조건을 만족하는 동안 코드 블록을 반복 실행.

a. while문

  • 조건이 참일 때 반복 실행.
while (조건식)
{
    // 반복 실행할 코드
}

b. do-while문

  • 조건에 상관없이 코드 블록을 최소 한 번 실행.
do
{
    // 반복 실행할 코드
}
while (조건식);

c. for문

  • 초기화식, 조건식, 반복식을 사용해 정교하게 제어 가능.
for (초기화식; 조건식; 반복식)
{
    // 반복 실행할 코드
}

d. foreach문

  • 배열이나 컬렉션의 요소를 순회.
  • 형식:
foreach (데이터형식 변수명 in 배열 또는 컬렉션)
{
    // 요소별 실행 코드
}
  • 예시:
int[] numbers = { 1, 2, 3, 4, 5 };

foreach (int num in numbers)
{
    Console.WriteLine(num); // 배열의 각 요소 출력
}

e. 무한 반복

  • for문:
for (;;)
{
    // 무한 반복 코드
}
  • while문:
while (true)
{
    // 무한 반복 코드
}

 


3. 점프문

  • 정의: 실행 흐름을 중단하거나 특정 위치로 이동.

a. break문

  • 현재 실행 중인 반복문 또는 switch문을 중단.
for (int i = 0; i < 10; i++)
{
    if (i == 5) break; // 반복문 중단
    Console.WriteLine(i);
}

b. continue문

  • 현재 반복을 건너뛰고 다음 반복으로 이동.
for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0) continue; // 짝수 건너뛰기
    Console.WriteLine(i);
}

c. goto문

  • 지정된 레이블로 바로 이동.
goto 레이블;

레이블:
    Console.WriteLine("레이블로 이동");

d. return문

  • 메서드를 종료하고 값을 반환.
return 값;

e. throw문

  • 예외를 발생.
throw new Exception("예외 발생");

정리

  • 분기문: if, else, switch를 사용하여 조건에 따른 실행 흐름 제어.
  • 반복문: while, do-while, for, foreach를 활용해 반복 처리.
  • 점프문: break, continue, goto, return, throw를 통해 흐름을 제어.

+ Recent posts