[SKKU DT] 23일차 -유니티 C# 메소드와 매개변수

2023. 11. 29. 17:57SKKU DT

728x90
반응형

Return 문

재귀 호출

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace E0602
{
    public class Return : MonoBehaviour
    {
        void Start()
        {
            Debug.Log($"10번째 피보나치 수 : {Fibonacci(10)}");

            PrintProfile("", "123-4567");
            PrintProfile("하이하이이하이", "456=1230");
        }
        static int Fibonacci(int n)
        {
            if (n < 2) //n이 2거나 2보다 크면 다시 자신의 메소드를 호출한다.(재귀 호출)
            {
                return n;
            }
            else
            {
                return Fibonacci(n - 1) + Fibonacci(n - 2);
            }
        }
        static void PrintProfile(string name, string phone)
        {
            if (name == "")
            {
                Debug.Log("이름을 입력해주세요.");
                return; //빈 문자열이 아니면 if 문이 실행되지 않는다. return은 메소드를 빠져나온다.
            }
            Debug.Log($"Name : {name}, Phone : {phone}"); //값이 있으면 출력된다.
        }
    }
}

메소드 안에 자신의 메소드가 들어있는 재귀 호출이다.

하나씩 대입해서 생각해보면 나중에는 1들의 합이 되는 것을 가지치기 형식을 통해서 그려보면 알 수 있다.

5번째

4번째 + 3번째

3번째+2번째 + 2번째+1번째

2+1 + 1+0 + 1+0 + 1

1+0 + 1 + 1 + 0 + 1 + 0+ 1 = 5

 

 


 

 

값에 의한 매개변수 전달

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwapByValue : MonoBehaviour
{
    void Start()
    {
        int x = 3;
        int y = 4;

        Debug.Log($"x:{x}, y:{y}");

        Swap(x, y);

        Debug.Log($"x:{x}, y:{y}");
    }
    //함수 안에서 바꾼다면 가능하지만, Start 함수에서는 바뀌지 않는다. 값을 복사하기 때문.
    //값을 복사하지 않으면 바뀐 값 적용이 가능하다. 참조 형식으로는 가능.
    public static void Swap(int a, int b) 
    {
        int temp = b;
        b = a;
        a = temp;
    }
}

 

 


 

 

참조에 의한 매개변수 전달

예를 들어, 로그인 화면과 메인 화면에서 사용자의 정보가 필요할 때, 씬이 넘어갈 때마다 복사해서 정보를 주면 불필요하게 많이 복사될 수 있다. 심지어 일부 씬에서 수정된 정보는 다른 씬에서 수정이 되지 않는다. 이런 경우 참조 형식으로 값을 만들어서 메모리 상에 있는 정보의 주소 값을 가져와서 이용한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SwapByValue : MonoBehaviour
{
    void Start()
    {
        int x = 3;
        int y = 4;

        Debug.Log($"x:{x}, y:{y}");

        Swap(ref x, ref y);

        Debug.Log($"x:{x}, y:{y}");
    }
    public static void Swap(ref int a, ref int b) 
    {
        int temp = b;
        b = a;
        a = temp;
    }
}

 

 


 

 

메소드의 결과를 참조로 반환하기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace E0603
{
    public class RefReturn : MonoBehaviour
    {
        void Start()
        {
            Product carrot = new Product(); //객체 생성
            ref int ref_local_price = ref carrot.GetPrice(); //반환 되는 값을 참조 형식으로 받아서 참조 형식의 int 변수에 저장 //ref_local_price를 변경하면 다른 쪽에서도 변경된다.
            int normal_local_price = carrot.GetPrice();

            carrot.PrintPrice();
            Debug.Log($"Ref Local Price : {ref_local_price}");
            Debug.Log($"Normal Local Price : {normal_local_price}");

            ref_local_price = 200;

            carrot.PrintPrice();
            Debug.Log($"Ref Local Price : {ref_local_price}");
            Debug.Log($"Normal Local Price : {normal_local_price}");
        }
    }
    class Product
    {
        private int price = 100; //설계도(Class)에 있는 값

        public ref int GetPrice()
        {
            return ref price; //int 값을 참조 형식으로 반환
        }
        public void PrintPrice()
        {
            Debug.Log($"Price : {price}");
        }
    }
}

 

 


 

 

출력 전용 매개변수

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UsingOut : MonoBehaviour
{
    void Start()
    {
        int a = 20;
        int b = 3;
        //int c; 쓰지 않아도 출력으로는 나타낼 수 있다.
        //int d; 쓰지 않아도 출력으로는 나타낼 수 있다.

        Divide(a, b, out int c, out int d);

        Debug.Log($"a : {a}, b : {b}, a/b : {c}, a%d : {d}");
    }

    static void Divide(int a, int b, out int quotient, out int remainder) //매개변수 out 선언을 하면 호출하는 함수에서도 out으로 호출 가능.
    {
        quotient = a / b;
        remainder = a % b;
    }
}

 

Raycast도 out 변수를 사용한다. Physics.Raycast(ray, out hit) 닿았는지 안닿았는지를 true, false로 반환한다. 어떤 게 닿았느냐도 쓰이기 때문에 out 변수를 사용한다.

 

 


 

 

메소드 오버로딩

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Overloading : MonoBehaviour
{
    void Start()
    {
        Debug.Log(Plus(1, 2));
        Debug.Log(Plus(1, 2, 3));
        Debug.Log(Plus(1.0, 2.0));
        Debug.Log(Plus(1, 2.4));
    }

    static int Plus(int a, int b)
    {
        Debug.Log("Caling int Plus(int, int)");
        return a + b;
    }

    static int Plus(int a, int b, int c)
    {
        Debug.Log("Caling int Plus(int, int, int)");
        return a + b + c;
    }

    static double Plus(double a, double b)
    {
        Debug.Log("Caling double Plus(double, double)");
        return a + b;
    }

    static double Plus(int a, double b)
    {
        Debug.Log("Caling double Plus(int, double)");
        return a + b;
    }
}

각 Plus 함수에서 매개변수에 맞는 함수가 자동으로 불러와지는 것을 볼 수 있다.

 

**오버로딩을 사용하려면 a, b, c로만 이름을 지으면 쓰는 사람이 어떤 값을 입력해야 하는지 모르므로 매개변수의 이름을 명확히 하는 것이 좋다. 순서를 바꿔도 기능한다.

 

 


 

 

로컬 함수

함수 안에 함수를 넣은 형태. ToLowerString 안에 ToLowerChar이 들어있다. 들어있는 함수는 속해 있는 변수에도 접근 가능하다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LocalFunction : MonoBehaviour
{
    void Start()
    {
        Debug.Log(ToLowerString("Hello"));
        Debug.Log(ToLowerString("Good Morning"));
        Debug.Log(ToLowerString("This is never that"));
    }

    static string ToLowerString(string input)
    {
        var arr = input.ToCharArray();
        for(int i = 0; i < arr.Length; i++)
        {
            arr[i] = ToLowerChar(i);
        }

        char ToLowerChar(int i)
        {
            if (arr[i] < 65 || arr[i] > 90)
            {
                return arr[i];
            }
            else
            {
                return (char)(arr[i] + 32);
            }
        }
        return new string(arr);
    }
}
728x90
반응형