ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 다시한번 개발자도전! 7일차 (함수,재귀함수,메모리구조,ref,out)
    다시한번 개발자도전! 2026. 1. 12. 15:50

     

    요즘 계속 앉아서 수업을 듣고 공부하니까 아랫배에 살이 찌는 느낌이다..

    공부도 하고 운동도 신경써야 한다니 너모 바쁜 인생..

     


    ‼️C# 메모리 구조 (Memory Layout)

    • Stack (스택): 지역 변수, 매개변수가 저장됨. 함수가 끝나면 바로 날아감. 속도가 매우 빠르지만 용량이 작음 (보통 1MB).
    • Heap (힙): new 키워드로 생성된 객체(참조 타입)가 저장됨. GC(Garbage Collector)가 나중에 치워줌. 용량이 크지만 스택보다 느림.
    • Static (데이터 영역): static 변수나 상수가 저장됨. 프로그램 시작할 때 생기고 끝날 때까지 살아있음.
    • Code (코드 영역): 우리가 짠 프로그램 명령어(IL 코드) 자체가 저장됨. 읽기 전용임.


    지역 변수 vs 전역 변수 (필드)

    메모리 위치가 다르면 수명과 사용 범위도 다름.

    1. 지역 변수 (Local Variable)

    • 위치: Stack 영역.
    • 범위: 함수 { } 안에서 선언되어 그 안에서만 살다가 함수 종료 시 소멸함.
    • 특징: 초기화하지 않고 사용하면 컴파일 에러 발생.

    2. 전역 변수 / 필드 (Global Variable / Field)

    • 위치: 클래스 내부에 선언되며, 객체면 Heap, static이면 Static 영역.
    • 범위: 클래스 전체에서 사용 가능.
    • 특징: 별도 초기화를 안 해도 기본값(0, null 등)으로 자동 세팅됨.

    1. 함수(Method)

    특정 작업을 수행하려고 묶어둔 코드 블록임. 한 번 만들어두면 필요할 때마다 이름만 불러서 재사용할 수 있음.

    • 재사용성: 똑같은 코드 또 쓸 필요 없음.
    • 가독성: 코드가 의미 단위로 끊겨서 보기 편함.
    • 유지보수: 한 곳만 고치면 연결된 곳이 다 바뀜.

    2. 함수의 구조

    반환타입 함수이름(매개변수)
    {
        // 실행할 코드
        return 반환값;  // 반환타입이 void가 아닐 때
    }

     

    • 반환타입: 결과물로 내뱉을 데이터의 종류. 없을 땐 void를 씀.
    • 매개변수(Parameter): 함수 내부로 전달받는 재료임.

    예시

    // 1. 주는 것도 받는 것도 없음
    void SayHi() => Console.WriteLine("안녕");
    
    // 2. 받기만 함 (매개변수 있음)
    void Attack(int damage) => Console.WriteLine($"{damage} 데미지!");
    
    // 3. 받아서 계산 후 돌려줌 (반환값 있음)
    int Add(int a, int b) 
    {
        return a + b; 
    }

     

    🔥실습예제🔥

    더보기

    플레이어이름:

    공격력:

    방어력:

    민첩:

    스피드:

    static void Main(string[] args)
    {
        PlayerInFo("뭉뭉", 100, 50, 70, 100);
    }
    static void PlayerInFo(string name,float atk, float def,float speed,float luk ) 
    {
        Console.WriteLine($"이름: {name}");
        Console.WriteLine($"공격력: {atk}");
        Console.WriteLine($"방어력: {def}");
        Console.WriteLine($"민첩: {speed}");
        Console.WriteLine($"행운: {luk}");
    }

     

    💡 명명된 인수 & 선택적 매개변수

    더보기
    • 매개변수에 기본값을 설정해두면 호출할 때 생략이 가능함. 특정 값만 넣고 싶을 땐 **이름(name:)**을 지정하면 됨.
    static void Main()
    {
        // num은 기본값(100) 쓰고, num2만 10.5f로 지정함
        Fun(num2: 10.5f); 
    }
    
    static void Fun(int num = 100, float num2 = 1.5f) { }

     

    3.함수의 오버로딩

    • "이름은 같지만 매개변수가 다른" 함수들을 만드는 기술임. 비슷한 기능을 하는 함수들을 하나의 이름으로 관리할 수 있어 편리함.
    • 주의: 반환 타입만 다른 것은 오버로딩이 안 됨! 매개변수(개수, 타입)가 반드시 달라야 함.
    static void Main(string[] args)
    {
        Fun();
        Fun(1);
    }
    
    static void Fun() { } //이름은 같지만 매개변수를 다르게 하여 사용가능ㅇ
    static void Fun(int i) { }

    ref 와 out

    • C#에서 값 타입은 함수에 넘길 때 복사본이 전달됨. 함수 안에서 값을 바꿔도 원본은 안 변함. ref와 out을 쓰면 원본을 직접 수정할 수 있음.

    1. ref (Reference: 참조)

    함수 외부에서 이미 초기화된 변수를 함수 안에서 수정하고 싶을 때 씀.

    • 특징: 함수에 넣기 전에 반드시 값이 들어있어야 함.
    • 용도: 기존 데이터의 값을 업데이트할 때.
    internal class Program
    {
        //매개변수 int a 대신받아준다.
        static void Attack(ref int a)
        {
            Console.WriteLine("공격력 : " + a);
            a++;
        }
        static void Main(string[] args)
        {
            //ref 키워드 참조
            //C# 내부적으로 포인터 개발자들이 신경덜쓰게 잘만들어놓음
    
            int a = 10;
    
            Attack(ref a);
    
            Console.WriteLine("a 값 : " + a);
        }
    }

     

    2. out (Output: 출력)

    함수 내부에서 값을 만들어 밖으로 내보낼 때 씀.

    • 특징: 함수 내부에서 반드시 값을 할당해야 함. (안 하면 에러 남)
    • 용도: 한 함수에서 여러 개의 결과값을 반환하고 싶을 때 유용함.
    static void Main()
    {
        int playerHp; // 초기화 안 해도 됨
    
        SetStartStats(out playerHp); 
        Console.WriteLine($"초기 HP: {playerHp}"); // 100
    }
    
    static void SetStartStats(out int hp)
    {
        hp = 100; // 함수 안에서 반드시 값을 채워줘야 함!
    }

     

    3. ref 와 out 의 차이

    구분 ref out
    목적 기존 데이터를 수정함 데이터를 생성해서 내보냄
    초기화 호출 전 반드시 초기화 필요 호출 전 초기화 안 해도 됨
    함수 내부 값을 수정 안 해도 됨 반드시 값을 할당해야 함

     


    재귀함수 (Recursion)

    • **"자기 자신을 다시 호출하는 함수"**
    • 큰 문제를 해결하기 위해 동일한 방식으로 작동하는 더 작은 문제로 쪼개서 푸는 방식임.

    1. 재귀함수의 필수 조건 (중요!)

    1. 기초 케이스 (Base Case): 재귀를 멈추는 조건. (언제 끝날 것인가?)
    2. 재귀 단계 (Recursive Step): 문제를 더 작게 쪼개서 자기 자신을 호출하는 부분.
    static void Main()
    {
        int result = Factorial(5);
        Console.WriteLine(result); // 120
    }
    
    static int Factorial(int n)
    {
        // 1. 기초 케이스: n이 1이면 1을 반환하고 끝냄
        if (n <= 1) return 1;
    
        // 2. 재귀 단계: n과 (n-1)의 팩토리얼을 곱함
        return n * Factorial(n - 1);
    }

     


    이제는 개인프로젝트를 어떤걸 할지 한번 구상해 봐야겠다

    멀티로 만들고 싶긴한데 시간이 오래 걸릴것 같아 고민쑤.. 

    그래도 일단 도전! 아좌조자!

Designed by Tistory.