• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

구조체 질문

21.05.11 21:56 작성 조회수 136

1

Flash라는 이름의 구조체가 있다고 했을때

Flash fla = new Flash(); 로 구조체를 만들수 있잖아요?

여기서 선생님은 Flash가 x ,y 를 변수로 가지고 있다면

xIn yIn 이 각각 매개변수라 했을때 이것들의 메모리가 생기고 값을 대입했다가 최종적으로는 x ,y에 대입하고 사라진다고 하셨는데요. 

궁금한점이 선생님께서 new Vector3() 생성자는  Vector3라는 새로운 구조체를 만드는것이 아니라 그냥 위의 과정을 명령하는 것이라 하셨습니다.

여기서 Vector3 구조체를 보시면

Vector3 vec = new Vector3(1,2,5); 이렇게 했을때 

Vector3 anoVec += vec * 3f;  라 한다면 

= 연산자로 구조체의 new는  명령하는것이라 알고있었던 저에게 

+=연산자에다가 3f를 곱하기 까지하는걸 봤을때 "Vector3 구조체를 새로 만든다" 라고 생각하지 않으면 이해가 힘들었습니다. 정확한 원리가 무엇인가요? 자세히 알려주시면 감사하겠습니다.  아니면 제가 아직 강의를 듣고있는중이라 나중에 추가 설명이 나온다면 그렇게 말해주시면 감사하겠습니다. 

답변 2

·

답변을 작성해보세요.

0

아 원하시는 답변이 Vector3 vec; 로 했을때 메모리가 벌써 생겨난다 라고 하면 되지 않나요? 

Vector3 vec ;로 했을때 메모리가 벌써 생겨난다 가 맞습니다. 구조체라서요. 

int x ;할때 벌써 메모리가 생겨나잖아요. 구조체가 기본자료형 타입과 동일하게 동작합니다.

그리고 구조체는 new 의 생성자를 통해서 초기화를 할 수도 있는 것입니다. 

0

안녕하세요. 답변이 늦어서 죄송합니다. 

답변 드리겠습니다. 현재 Part3 를 공부하고 계시는데 혹시 Part2 는 없으시죠? 

거기에 설명이 좀 있는데 이 내용이 조금 방대합니다. 그래도 한번 해보도록 하겠습니다.

우선 말씀하신 내용으로 생각해보면 아래의 anoVec 라는 벡터가 있으면 이게 new 가 없는데 왜 동작할지에 대해서 생각해봐야 합니다. anoVec 라는 것은 vec에 3을 곱해서 받는데 anoVec 의 메모리가 하나 생겨납니다. 

Vector3 anoVec += vec * 3f; 

그런데 anoVec 변수의 메모리가  현재 실행되는 함수 안에 있을 것이기에 현재의 함수안의 스택에 존재했다가 함수가 끝나면 사라지고요.  이게 스택안에 있어서 그렇습니다. 

그래서 다시 돌아가서 질문하신 내용을 말씀드리면요.  이걸 알려면 사실 구조체를 하나 만들어보고 설명을 해야 합니다. 

struct StructPos {

   public int x;, public int y; public int z;

   public void StructPos(int xIn, int yIn, int zIn) {

       x = xIn; y = yIn; z = zIn;

   }

}

실제로 StructPos 라는 구조체를 만들어서 new StructPos(1,2,3) 이라는 생성자를 실행했을때  생성자 안에서 xIn, yIn, zIn  의 변수가 생겨났다가 사라질 것입니다.  그리고 여기에 메모리에 대한 내용은 없는데 C#에서 언어가 만들어질때의 규칙으로 있는게 하나가 있습니다. 구조체는 값타입으로 동작하고 클래스는 레퍼런스 타입으로 동작합니다. 즉 둘다 new 를 한다고 해도 구조체는 값타입의 메모리를 가지고 클래스는 레퍼런스 타입을 가집니다. 

public class TestScript : Monobehaviour{
   struct StructPos {
      public int x;, public int y; public int z;
      public void StructPos(int xIn, int yIn, int zIn) {
          x = xIn; y = yIn; z = zIn;
      }
   }
   void Start() {
      StructPos p1 ;
      StructPos p2 = new StructPos(1,2,3);
       p1 = p2;
       print("대입하고 나서 값들 " + p1.x + " " + p1.y);
       print("대입하고 나서 값들 " + p2.x + " " + p2.y);
       p2.x = 10;
       print("대입하고 나서 값들 " + p1.x + " " + p1.y);
       print("대입하고 나서 값들 " + p2.x + " " + p2.y);
}

위의 코드를 실행했을 경우 p1도 p2 도 서로 다른 값을 가집니다. 값타입이라 서로 대입하면 메모리가 다르기 때문입니다. 

p1 도 p2 도 서로 다른 메모리를 가지고 있습니다(그리고 함수안에 있기 때문에 함수가 끝나면 메모리가 사라집니다)

그런데 클래스로 이걸 실행해보면 내용이다릅니다. 

public class TestScript : Monobehaviour{
   struct ClassPos {
      public int x;, public int y; public int z;
      public void StructPos(int xIn, int yIn, int zIn) {
          x = xIn; y = yIn; z = zIn;
      }
   }

   void Start() {
      ClassPos c1 ;
      ClassPos c2 = new ClassPos(1,2,3);
       c1 = c2;
       print("대입하고 나서 값들 " + c1.x + " " + c1.y);
       print("대입하고 나서 값들 " + c2.x + " " + c2.y);
       c2.x = 10;
       print("대입하고 나서 값들 " + c1.x + " " + c1.y);
       print("대입하고 나서 값들 " + c2.x + " " + c2.y);
}

위의 내용을 실행해보면 c2.x = 10을 실행하고 나면 둘다 같은 값을 가지게 됩니다. 레퍼런스이기 때문에 c1= c2 가 실행되어도 서로 같은 위치를 가르키고 있기 때문입니다. 

구조체가 메모리가 생기는 것은 맞습니다. new 로 실행해서 생기나 그냥 선언해서 생기나 둘다 메모리가 생긴다는 겁니다. 

그런데 이게 값타입이기 때문에 현재 상태의 메모리가 바로 생겨납니다.

Vector3 vec = new Vector3(1,2,5); 

위의 문장이 실행될 경우 구조체의 생성자가 내부적으로 실행될 것입니다. 

그래서 vec 에 값이 대입되고 vec의 메모리가 생겨납니다.

Vector3 anoVec = vec * 3; 

위의 문장을 실행해도 구조체의 메모리가 생겨납니다. 

이게 Part2 C# 강의에서 아마 적어도 10개 정도 분량의 강의로 설명드린 내용입니다.

고민해봐야 할 것이 함수안의 값타입, 멤버변수의 값타입, 함수안의 레퍼런스타입, 멤버변수의 레퍼런스 타입 이 4가지를 자유자재로 이미지가 되어야 이해가 됩니다. 

우선 여기에서 종료하겠습니다.  혹시 연락 가능하시면 더 자세히 알려드릴께요 ^^

문자로 한번 연락 주시면 답변 드리고요. 줌으로 알려드릴께요. 010-8627-5022 입니다. 

감사합니다.