레퍼런스 질문드립니다
238
작성한 질문수 7
제가 이해하고 있는 레퍼런스를 표현하기 위해
불가피하게 cpp 파일로 코드를 표현했습니다.
(유니티에서는 &(레퍼런스) 표현이 안 되더라구요)
#include <stdio.h>
void St(int& n)
{
printf("%x\n", &n);
printf("%d\n", n);
}
int main()
{
int n = 10;
printf("%x\n", &n);
St(n);
return 0;
}
위 코드에서 레퍼런스 변수 n의 주소와 main함수의
원본 변수 n의 주소가 같게 찍히더라구요.
그래서 레퍼런스는 그냥 원본 변수나 배열의 별명이라
생각했고, St함수에서 레퍼런스 변수 n을 출력하면
n이 값이 출력되기에 레퍼런스 n의 메모리 안에 원본 n의
값이 들어있다고 생각했습니다.
그런데 오늘 설명해주신 레퍼런스 부분은
메모리를 따로 생성해 원본 변수 or 배열과 별도의 주소를
가지고 메모리 안에 원본 메모리 시작주소 갖는
포인터의 개념 같아서요. 포인터는 *로
간접참조값 가져오던데
Player p= new Player();
에서 p가 * 나 & 같은 기호도 없고 레퍼런스라 생각하니 오히려
더 헷갈립니다.
제가 생각했던 레퍼런스=별명이고
레퍼런스 변수 값(주소가 아니라)= 원본 변수 값 이라는
생각도 흔들려서 혼란스럽습니다.
Player p= new Player(); 이 문장 해석을
그냥 타입사이즈 메모리로 객체 생성 하고
객체 멤버변수를 default(0)으로 초기화 한다고 이해하고
넘어갈까요?
답변 2
0
그러고 보니 질문에 대한 대답을 안했네요
Player p= new Player();
new Player()를 통해 생성자를 실행하면서 실제 메모리가 생겨나고 그 레퍼런스를 p에 대입합니다.
그리고 그냥 * 나 & 없이 그대로 사용합니다.
그래서 p변수(레퍼런스변수)가 실제 메모리를 참조한다 이렇게 이야기합니다.
0
안녕하세요. 제가 cpp 는 조금 공부만 해보고 안해봐서 답변을 드리긴 그렇습니다만
n의 주소를 그대로 함수에 넘겨주기때문에 같은 값이 아닐까 싶은 생각이 듭니다. cpp를 공부를 좀 해보고 나중에 이건 생각해볼 문제같고요.
레퍼런스 문제는 C# 에서는 포인터가 없다고 생각하시면 됩니다.
윈도우즈에서 실행할때 unsafe 라는 형태로 포인터를 사용할 수는 있는데요.
무슨 일이 생길지 모르기 때문에 유니티에서는 사용을 안하시는게 좋을 것 같습니다.
나중에 좀 고급문법에 나오는 ref 나 inout 같은 경우 포인터와 비슷하게 사용합니다만
그래도 포인터기호나 별표기호 같은 것을 사용하지는 않습니다.
그래서 초보자들이 접근하기에 더 쉬운 면이 있습니다.
C#에서는 레퍼런스는 기호 없이 그냥 사용합니다.
클래스로 만들어진 변수가 기호 없이도 그대로 접근해도
레퍼런스로 동작하고요.
값타입으로 되어 있는 변수들은 그대로 값으로 동작합니다.
다른 곳에서 보니 2중포인터로 내부적으로는 동작한다고 들었습니다만
그냥 1단 포인터변수의 동작과 동일하다고 생각하시고 별표나 & 연산자 없이 접근하시면 됩니다. (클래스의 경우에요)
레퍼런스 안에는 주소가 있고 실제 메모리가 다른곳에 존재합니다. 단 클래스만 그렇게 동작하고요.
구조체는 변수가 있으면 그대로 가보면 실제 메모리가 있습니다.
언어에 보통 만들어진 이유 같은것이 존재하는데요.
포인터가 초보자가 너무 어려워서 이걸 없애고 접근하려고 만든 것이 C# 언어라고 생각하고 있습니다.
그래도 메모리의 주소는 보고 싶긴하죠 저도 그렇습니다. 그래서 C#에서는 주소는 볼수 없지만 해시코드는 볼수 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ManagerScript : MonoBehaviour
{
public class ClassPos{
public int x; public int y; public int z;
}
public struct StructPos
{
public int x; public int y; public int z;
}
public PlayerScript playerScript;
void Start()
{
MyGameObject m = new MyGameObject();
ClassPos c1 = new ClassPos();
ClassPos c2 = c1;
c1.x = 1;
c2.x = 2;
StructPos s1 = new StructPos();
StructPos s2 = s1;
s1.x = 10;
s2.x = 20;
print(c1.GetHashCode()); // 1
print(c2.GetHashCode()); // 2
print(c1.x.GetHashCode()); //3
print(c2.x.GetHashCode()); //4
print(s1.GetHashCode()); //5
print(s2.GetHashCode()); //6
print(s1.x.GetHashCode()); //7
print(s2.x.GetHashCode()); //8
}
}
이 코드 한번 실행해서 보시면 해시코드가 주소 비슷하게 보입니다.
위에서 c2 = c1 을 실행했으므로 레퍼런스가 같은 메모리를 가르키고 있습니다.
1번 c1.getHashCode() , 2번 c2.getHashCode() 같은 경우 클래스의 동작이므로 c1과 c2의 값이 c 언어 포인터같이 값이 같습니다.
3 4번의 경우도 값이 같습니다. 대입을 통해 레퍼런스가 같은 값이 되었으므로 같은 메모리를 참조 하기 있기 때문입니다.
5번 6번 같은 경우 구조체 같은 경우 값을 대입하고 있지만 다른 메모리에 생겨납니다. 구조체도 메모리이기 때문에 해시코드는 생겨납니다만 (내부적으로 주소는 있을 것입니다 하지만 저희가 사용하지 않습니다.) 구조체는 대입을 하면 서로 다른 메모리에 생겨납니다.
7번8번 같은 경우에 위에서 각각의 x값에 10과 20을 대입했기 때문에 각각 다른 메모리가 있다는 것을 알수 있습니다.

그리고 다른 언어를 같이 적용하려고 하면 더 어려워 지는 것 같습니다. 새로 배운다고 생각하시고 접근하셔야 할 것 같습니다. 그래도 원래 지식이 있으니 도움은 크게 되겠죠. cpp보다 C#이 훨씬 쉽습니다.
감사합니다. 좋은 하루 되세요.
Part4 유니티로 세가지의 게임만들기 강의도 들을 수 있는건가요?
0
263
1
플레이 버튼이 없어요
0
758
1
전체 연습문제 다운방법, 현재 연습문제 파일이 깨져서 열립니다.
0
377
2
연습문제파일
0
262
1
중단점을 찾을수가 없습니다
0
470
1
10분 24초에 만약 b를 0으로 둘시, "나눗셈이 불가능"대신 attempt to divide by zero 오류가 뜹니다.
0
313
1
if문의 비교(10분56초~59초사이)
0
219
1
NullReferenceException을 기대했는데....
0
326
1
C#에서의 메모리 관리
0
273
1
Heap 과 Stack
0
303
1
앞선 강의에서 Instance와 연관 지어서
0
270
3
Instance와 variable
0
243
1
구조체 6번째 강의
0
190
1
제공 함수는 실제 구현하는 몸체가 없다
1
343
1
인자와 매개변수
1
215
1
코드에서 new GameObject를 실행했을 때 유니티 화면상의 상태 문의
2
624
1
유니티 콘솔화면에 나타난 내용 문의
1
353
1
멤버변수를 전역변수라고 생각해도 되는지요?
1
1226
1
출력만 있는 함수 관련 질문
1
422
2
문제 파일은 어디에 있나요?
0
235
1
제 윈도우용 visual studio에서는 코드행 앞에 아무것도 안찍힙니다.
0
321
2
혹 강의내용을 캡쳐해서 블로그에 공개해도 되나요?
0
364
1
비쥬얼 스튜디오에서 강의대로 입력했는데 콘솔창에 아무것도 안나타나네요.
0
263
1
저는 윈도우즈에서 모니터를 두개로 나눠 강의영상과 Unity작업창으로 나눠서 하고 있는데 무슨 얘긴지 하나도 모르겠어요
0
230
2





