📝 구조체란?                                                                                                       

: 데이터와 관련된 기능을 캡슐화할 수 있는 값(Value) 형식

: struct 키워드를 사용해서 정의

 

📝 구조체의 특징                                                                                                     

  • 1. 작은 크기의 데이터에 적합 (16바이트 이하)
  • 2. 복사 시 전체 데이터가 복사됨 (깊은 복사)
    • - 클래스는 복사 시 참조만 복사됨 (얕은 복사)
  • 3. 구조체 내부에 참조 타입의 필드가 있으면 힙 할당 발생
  • 4. 함수에 큰 구조체를 전달하면 저하가 될 수도 있다
    • - ref 매개변수로 값 타입을 참조타입처럼 넘겨줄 수 있음 

 

📝 구조체와 클래스의 차이                                                                                                         

  구조체 (struct) 클래스 (class)
형식 값 형식 (Value Type) 참조 형식 (Reference Type)
메모리 스택 영역 힙 영역
상속 불가능 가능

 

: 클래스를 인스턴스 화 하면 힙에 할당된다.

힙에 할당된 메모리는 가비지 컬렉터가 사용하지 않는 메모리를 정리해 주는데

클래스를 너무 많이 할당하는 등의 처리야이 많으면 시스템 부하가 올 수 있다.

 

그래서 굳이 힙에 할당하지 않아도 되는 데이터는 스택 메모리에 할당되는 구조체를 사용하는 것이 성능적으로 좋아 보인다.

 

📝 구조체와 클래스, 무엇을 선택할까?                                                                                             

https://forum.dotnetdev.kr/t/c-structure/762

 

C# Structure(구조체)는 언제 사용하면 좋은가요?

안녕하세요. 😄 Structure에 대해 질문 드리고자 합니다. 저는 구조체를 단 한번도 사용해 본 적이 없는데요. 책이나 관련 글을 읽더라도 언제 사용해야 하면 좋을지 제대로 이해하지 못했습니다.

forum.dotnetdev.kr

구조체는 임시 객체에 사용하면 좋을 것 같다는 이야기

ex) for문에서 반복적으로 객체를 생성해야 할 때

'용어정리' 카테고리의 다른 글

[Unity] 코루틴  (0) 2025.03.10
[Unity] Monobehavior  (0) 2025.03.07
[c#] Action,Func,Delegate 차이점  (0) 2025.02.28
[c#] call by value, call by reference  (0) 2025.02.27
[c#]static 정적 변수, 정적 메서드 , 정적 클래스  (0) 2025.02.24

코루틴은 동기적인가 비동기적인가 ? 

 

유니티 코루틴 공식문서에서 : 
하지만 코루틴은 스레드가 아니라는 점을 명심해야 합니다. 코루틴의 동기 작업은 여전히 메인 스레드에서 실행됩니다. 메인 스레드에 소요되는 CPU 시간을 줄이려면 다른 스크립트 코드에서와 마찬가지로 코루틴의 작업 차단을 방지하는 것이 중요합니다. Unity 내에서 다중 스레드 코드를 사용하려면 
C# 잡 시스템
을 고려하십시오.

 

코루틴은 "동기적(synchronous)"이면서도 "비동기적인 실행 패턴"을 제공하는 특별한 케이스 이다.

 

동기와 비동기의 의미는 ?

  1. 동기 Synchronous
    1. 말 그래도 동시에 일어난다는 뜻
    2. 요청을 하면 바로 결과가 주어져야함
    3. 여러가지 요청을 동시에 할 수 없다
  2. 비동기 Asynchronous
    1. 말그대로 동시에 일어나지 않는
    2. 요청을 하고 결과과 오지 않아도 대기시간동안 다른 요청을 할 수 있다
    3. 여러개의 요청을 동시에 처리 가능

 

MS의 공식문서에는 아침식사 차리기를 예시로 든다

https://learn.microsoft.com/ko-kr/dotnet/csharp/asynchronous-programming/

 

C#의 비동기 프로그래밍 - C#

async, await 및 Task를 사용하여 비동기 프로그래밍을 지원하는 C# 언어에 대해 간략히 설명합니다.

learn.microsoft.com

 

코루틴의 한계

코루틴은 가비지 컬렉터를 많이 잡아먹는다

 

쓰레드 단일/멀티쓰레드?

유니티에서 스크립트를 생성하면, Monobehavior을 기본적으로 상속받고 있다.

이러한 Monobehavior 클래스는 어떤 역할을 하는 것일까?

 

📝 Monobehavior                                                                                                         

유니티 공식 docs에서는 아래와 같이 설명하고 있다.

MonoBehaviour 클래스는 대규모 이벤트 메시지 컬렉션에 대한 액세스를 제공하며, 이를 통해 현재 프로젝트에서 발생하는 상황에 따라 코드를 실행할 수 있습니다.

 

🔖 Monobehavior의 역할

 

1. 모든 유니티 스크립트가 파생되는 기본 클래스

 

2. 에디터와 스크립트 파일을 연결시켜주는 역할

클래스를 에디터에서 읽고, 컴포넌트로 추가하는 등의 동작을 하기 위해서는 유니티 에디터가 클래스에 대한 정보를 알아야 한다. 이때 Monobehavior이 그 역할을 해준다.

 

3. 시작 및 업데이트 등과 같은 대한 연결을 제공 

Start(), Update(), OnEnable() 등의 콜백 함수를 의미한다.

 

4. 이러한 이벤트 함수들의 생명주기 관리

 

🔖 Monobehavior의 특징

1. 게임오브젝트의 Component로 등록해야 사용가능

반대로, Monobehavior을 상속받지 않는 클래스는 게임오브젝트의 컴포넌트로 등록할 수 없다.

 

2. Monobehavior을 상속받은 클래스를 사용하기 위해서는 GetComponent로 클래스를 가져와야 함

 

3. new로 동적 생성이 불가능 

 

🔖 콜백 함수(생명주기 메서드)는 어떻게 호출되는 것인가?

유니티에는 Messaging System이라는 시스템이 있는데 특정 시점에 유저가 정의한 함수가 동작할 수 있게 해 준다.

Monobehavior 스크립트가 처음으로 이용될 때, 스크립트 내 이러한 함수들이 있다면

이 스크립트는 각 함수와 관련된 List에 저장된다. 

예를 들어서 어떤 스크립트에 Update 함수가 정의되어 있다면 이 스크립트는 Update와 관련된 List에 저장되고,

이 List는 매 프레임마다 Update가 호출되어야 할 시점에 사용된다.

 

사용하지 않는 " 자주 호출되는 메서드(특히 Update, FixedUpdate, LateUpdate) 관련된 함수들은 사용하지 않으면 지우는 것이 성능에 좋다"라는 이야기를 들어보았을 것이다.

이것은 Monobehavior가 이용될 때 해당 메서드를 사용하던 안 하던 실행하기 때문이다.

 

자세한 내용은 공식문서를 참고하자! 

https://unity.com/kr/blog/engine-platform/10000-update-calls

 

10000번의 Update() 호출

void Update() { transform.Translate(0, 0, Time.deltaTime); }하지만 숙련된 개발자는 위의 코드에서 몇몇 의문이 들 수 있습니다. 이 함수는 도대체 언제 호출되지? 만약, 여러개의 스크립트가 있고 그 스크립

unity.com

 

 

내부적으로는 IL2CPP와 같은 Unity의 스크립팅 백엔드에서 MonoBehaviour가 어떻게 처리되는지 알 수 있다.

 

🔖 Monobehavior이 콜백함수를 실행하는 순서, 생명주기

Awake() → OnEnable() → Start() → Update() → LateUpdate() → OnDisable() → OnDestroy() 등의 순서로 호출된다.

자세한 내용은 유니티 생명주기 공식문서를 참고하자

 


유니티 라이프사이클

https://docs.unity3d.com/kr/2019.4/Manual/ExecutionOrder.html

 

이벤트 함수의 실행 순서 - Unity 매뉴얼

Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.

docs.unity3d.com

 

 

유니티 중요 클래스 - Monobehavior

https://docs.unity3d.com/kr/2020.3/Manual/class-MonoBehaviour.html

 

중요 클래스 - MonoBehaviour - Unity 매뉴얼

MonoBehaviour 클래스는 기본적으로 모든 Unity 스크립트가 파생되는 기본 클래스입니다. Unity의 프로젝트 창에서 C# 스크립트를 생성하면 MonoBehaviour에서 자동으로 상속되며, 템플릿 스크립트를 제공

docs.unity3d.com

 

 

Delegate

  • C#에서 메서드를 대신 참조할 수 있는 형식으로, 메서드를 변수처럼 사용할 수 있게 해 준다
  • 사용자가 직접 정의하여 반환 형식과 매개변수를 지정 가능
  • Delegate는 Action과 Func의 기본이 되는 개념

Action

  • 반환 값이 없는(void) 메서드를 참조하는 제네릭 대리자
  • 최대 16개까지 입력 매개변수를 가질 수 있음
  • Action<T1, T2, ...>와 같은 형태로 사용됨

Func

  • 반환 값이 있는 메서드를 참조하는 제네릭 대리자
  • 마지막 타입 매개변수가 항상 반환 타입을 나타냄
  • Func<T1, T2, ..., TResult>와 같은 형태로 사용되며, 최대 16개의 입력 매개변수를 가질 수 있음

(+) microsoft c# 공식문서에 가면 16개의 매개변수를 가지는 Action과 Func 예시를 볼 수 있다.


델리게이트 설명과 예시

2025.02.10 - [c#] - [c#]delegate 이해하기

 

[c#]delegate 이해하기

1. delegate    □ 개념    □ 예시📝 delegate (대리자)1. 개념□ 메서드에 대한 참조를 나타내는 형식 □ C++의 함수 포인터와 비슷하게 동작함!           ■함수포인터?           : 함수의 시

youcheachae.tistory.com

 

📝함수호출                                                                               

: 함수가 인수 (매개변수)를 처리하는 방식에는 두 가지가 있다.

: 첫 번째 값에 의한 호출 (call by value) , 두 번째로 참조에 의한 호출 (call by reference)

 

📝call by value                                                                       

값에 의한 호출

  • 함수에 변수를 전달할 때 값을 복사해서 선달함
  • 함수 내부에서 값을 변경해도 원래의 변수에 영향을 미치지 않는다
  • int, float, string, bool 등의 원시 타입은 값 복사

원시타입을 매개변수로 가지는 예시를 보겠다

static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");

    int a = 10;
    int b = 11;
    CallbyValue(a, b);
}

public static void CallbyValue(int tempA, int tempB) 
{
    tempA++;
    tempB++;
}

  함수에서 매개변수로 들어온 int값이 바뀌었지만, 원래 값은 변경되지 않는다.

 

  main함수가 실행될 때 스택 메모리에 a와 b 변수가 선언된다

CallByValue 메서드가 호출되면 스택에 tempA와 tempB가 할당되고 , a와 b의 값을 복사한다

함수 실행이 종료되면 tempA와 tempB는 스택에서 해제된다

즉, 함수 내에서 복사한 값을 변경하였기 때문에 원본 값은 변경되지 않는다

 

📝call by reference                                                                

참조에 의한 호출

  • 함수에 변수를 전달할 때 값을 참조, 즉 메모리 주소를 전달
  • 원래의 변수는 함수 외부에서도 변경된 값을 유지한다
  • 객체, 배열 같은 참조타입은 참조값(주소)이 복사되어 함수에 전달

클래스를 참조값으로 가지는 예시를 보겠다

 static void Main(string[] args)
 {
     Console.WriteLine("Hello, World!");
     
     Apple test = new Apple();
     CallbyReference(test);
 } 
 
 public static void CallbyReference(Apple test) 
 {
     test.count += 10;
 }
 
 public class Apple
{
    public int count = 1;
}

  함수 내에서 Apple클래스의 count값이 변경되었고, 원래 객체에도 변경이 반영된다

 

  Apple클래스를 인스턴스와 하면 힙 메모리에 할당된다

  apple 변수는 Apple 인스턴스의 찹조값(주소)을 가진다.

CallbyReference 메서드에 참조값(주소)을 전달하면, 해당 주소값이 복사되어 스택에 저장된다.

함수 내에서는 참조값(주소)에 해당하는 객체에 접근하여 값을 변경시킨다

즉, 참조된 객체의 속성을 변경하였기 때문에 원래 객체에도 변경이 반영된다

 

📝공통점 / 차이점                                                                       

  공통점

  • 모두 매개변수로 전달된 값 (값 자체 또는 참조값)을 복사한다
  • 복사된 값은 스택에 저장되고 함수 종료 시 해제된다 (스택프레임과 연관 있음)

  차이점

  • Call by Value : 원시타입 (int 등)의 값 자체가 복사된다
  • Call by Reference : 객체의 참조 주소값이 복사된다

 

(+) 스택프레임

함수가 호출될 때, 스택 영역에 차례대로 저장되는 함수의 호출정보이다.

함수가 호출될 때, 매개변수를 스택에 할당하기 때문에 두 방식 다 매개변수로 전달된 값을 복사한다.

( 참조타입의 경우 객체 자체는 힙에 있고, 참조만 스택에 복사된다! )

또한 함수의 호출이 끝나면 스택메모리에서 해제되기 때문에 복사된 값은 스택에서 해제된다.

 


스택프레임에 대한 자세한 설명은 아래 링크를 참고

 

2025.02.13 - [용어정리] - [용어정리]스택 프레임 (stack frame)

 

[용어정리]스택 프레임 (stack frame)

🔖 메모리 구조에 대해서 잘 모르시는 분들은 이전 글을 참고해 주세요!  2025.02.12 - [c#] - [c#]힙메모리와 스택 메모리 [c#]힙메모리와 스택 메모리메모리의 공간 1. 코드 (code) 영역2. 데이터 (data)

youcheachae.tistory.com

 

static 키워드를 사용하는 객체 처음 사용될 때 한번 할당되고, 프로그램이 끝날 때까지 메모리를 유지한다. 사용할 때 같은 메모리를 참조한다. 즉 정적이다.

반대로 동적인 객체는 사용할 때 마다 메모리를 사용하고, 사용이 끝나면 메모리를 해제한다. 

 

📝 정적 변수

static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");

    // 정적변수
    // 클래스명.변수 < 로 접근
    Cinema.person += 1;

    Cinema cinema = new Cinema();
    
    // 오류 : 인스턴스화 하면 정적 변수가 포함되지 않는다
    // 정적 멤버는 클래스에 속하는 것이지 인스턴스에 속하는 것이 아님
    cinema.person
}

public class Cinema
{
    // 정적 변수
    public static int person = 0;

    public Cinema() { }
}

□ 정적으로 선언된 변수는 클래스명.변수명 으로 접근할 수 있다.

정적 변수가 포함된 클래스를 인스턴스화 하면 정적 변수는 포함되지 않는다.

 

📝 정적 클래스

static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");
    
    // 정적 클래스
    Animal.animalAge += 1;
    Animal.Setting();
}

public static class Animal 
{
    // 오류 : 정적 클래스에 인스턴스 변수를 선언할 수 없다
    public int age = 0;

    // 오류 : 정적 클래스에 인스턴스 메서드를 선언할 수 없다
    public void Func() { }

    // 정적 변수 
    public static int animalAge = 5;
    
    // 정적 메서드
    public static void Setting() { }
}

정적으로 선언한 클래스의 필드와 메서드는 클래스명.변수명/ 클래스명. 함수명으로 접근할 수 있다.

 

🔖 정적선언을 할 때 주의해야할 점

1. 정적 클래스는 인스턴스화 할 수 없다.

2. 정적인 클래스는 정적인 변수와 메서드만 가질 수 있다.

 

📝 정적 메서드 

static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");

    // 정적 메서드
    Food.Eat();
    Food temp = new Food();
    
    // 오류 : 인스턴스화 하면 정적 메서드는 포함되지 않는다
    temp.Eat()
}


public class Food 
{
    static public void Eat() { }
}

 

□ 정적으로 선언된 함수는 클래스명.변수명 으로 접근할 수 있다.

 정적 메서드가 포함된 클래스를 인스턴스화 하면 정적 변수는 포함되지 않는다.

🔖 메모리 구조에 대해서 잘 모르시는 분들은 이전 글을 참고해 주세요!

  2025.02.12 - [c#] - [c#]힙메모리와 스택 메모리

 

[c#]힙메모리와 스택 메모리

메모리의 공간 1. 코드 (code) 영역2. 데이터 (data) 영역3. 스택 (stack) 영역4. 힙 (heap) 영역  □  코드(code) 영역            ■ 실행할 프로그램의 코드가 저장되는 영역            ■ 텍스트

youcheachae.tistory.com

 

📝 스택 프레임

  스택 프레임이란 무엇인가 ? (stack frame)

              스택 영역에 차례대로 저장되는 함수의 호출정보

              함수가 호출될 때 스택에 저장되는 내용 

                        함수의 매개변수

                         호출이 끝난 뒤 돌아갈 반환 주소 값

                         함수에서 선언된 지역변수

              스택에 올라간 함수가 모두 끝난뒤에,

           스택 프레임에 저장된 정보를 바탕으로 함수가 호출되기 이전 상태로 돌아갈 수 있다 

 

📝 스택 프레임의 동작 방식  

public static void Fun1() 
{
    Fun2();     // Fun2() 호출
}

public static void Fun2() 
{

}

static void Main(string[] args)
{

    Fun1();	// Fun1() 호출
}

 

  메서드 호출 시 동작

1. 프로그램이 실행되면, 가장 먼저 main() 함수가 호출되어 main()의 스택 프레임이 스택에 저장됨

2, fun1() 함수를 실행하면, 해당함수의 매개변수, 반환 주소값, 지역 변수 드으이 스택 프레임이 스택에 저장됨

3. fun2() 함수를 실행하면, 해당함수의 매개변수, 반환 주소값, 지역 변수 드으이 스택 프레임이 스택에 저장됨

 

  메서드 완료 시 동작

1. fun2()함수의 모든 작업이 완료되면, fun2()의 스택프레임만이 스택 메모리에서 제거됨

2. fun1()함수의 모든 작업이 완료되면, fun2()의 스택프레임만이 스택 메모리에서 제거됨

3. main()함수의 모든 작업이 완료되면 , main()의 스택프레임만이 스택 메모리에서 제거됨

4. 프로그램이 종료

 


스택프레임

https://www.tcpschool.com/c/c_memory_stackframe

 

메모리의 공간

 

1. 코드 (code) 영역

2. 데이터 (data) 영역

3. 스택 (stack) 영역

4. 힙 (heap) 영역

 

 

  코드(code) 영역 

           실행할 프로그램의 코드가 저장되는 영역 

           텍스트 영역 

 

  데이터(data) 영역 

           프로그램의 전역 변수와 정적 변수가 저장되는 영역 

           프로그램 시작과 함께 할당되며, 프로그램이 종료되면 소멸 

 

  스택 (stack) 영역

           함수의 호출과 관계되는 지역변수와 매개변수가 저장되는 영역

           함수의 호출과 함께 할당, 함수의 호출이 완료되면 소멸

           후입선출(LIFO, Last-In First-Out)

                      □ 푸시 (Push) 동작 : 데이터를 저장

                       팝 (Pop) 동작 : 데이터 인출

                       가장 늦게 저장된 데이터가 가장 먼저 인출됨

            높은 주소에서 낮은 주소의 방향으로 할당

 

  (heap) 영역

            사용자가 직접 관리할 수 있는 , 해야만 하는 영역

            사용자에 의해 메모리 공간이 동적으로 할당되고 해제됨.

            낮은 주소에서 높은 주소의 방향으로 할당

 


 

🔖 static선언을 하면 어느 메모리로 할당될까?

🔖 스택오버플로우라는 단어는?

🔖 스택메모리와 힙 메모리의 차이

🔖 스택프레임이란?

🔖 메서드를 호출할 때 어떤 순서로 메모리에 할당될까?


 

메모리구조

https://www.tcpschool.com/c/c_memory_structure

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com

 

+ Recent posts