코드 및 공부/기타

c# - 변수와 자료형

ekrxjvpvj0110 2024. 9. 23. 20:01

변수


변수란 값을 저장할 수 있는공간입니다

어떠한 값을 사용하고 싶을때마다 그 값을 직접 쓰지 않고, 대신 그 값을 저장한 이름을 사용합니다

 

 

만약 int a = 25; 라는 정수형 변수가 있다고 했을때

25라는 숫자를 b에 더해주고 싶다면 +25가 아니라 +a를 이용하여 동일한 기능을 수행할 수 있습니다

 

 

 

이는 변수를 사용하여 코드의 가독성과 유지보수성을 높이는 방법으로 나중에 A의 값이 27로 바뀌었을때

25를 더해줬던 모든 곳에 찾아가서 27로 수정하는게 아니라 수정된 a(27)를 더해줌으로써 자동적으로 변경된 값을 사용하게 됩니다

 

 

 

여기서 설명을 더하자면 a는 사실 27이라는 값을 갖고있는게 아니라 메모리 주소를 가리키고 있습니다, 해당 메모리 주소에 가야 비로소 실제 데이터에 접근할 수 있습니다, 하지만 C#에서는 메모리 주소를 직접적으로 다루지 않고, 변수 이름으로 값을 간접적으로 다루기 때문에 개발자가 정말 특수한 경우가 아니면 메모리 주소를 명시적으로 신경 쓸 필요는  없습니다

 

정리하자면 변수란 값을 저장하기위한 공간으로써, 저장된 값 대신 변수명을 이용하여 값을 수정, 참조합니다

 

 

 

변수의 선언과 주의사항


변수 선언이란 해당 변수가 어떤 타입의 데이터를 저장할지를 정의하는 과정입니다

 

변수 선언시 변수명 앞에 데이터의 타입을 지정해주어야 합니다, 변수에 값을 넣고싶다면 대입 연산자( = )를 이용합니다

유니티에서는 변수의 선언과 동시에 초기화 하지 않는다면 기본값이 들어가기때문에 반드시 초기화할 필요가 없습니다 

 

 

 

변수 선언시 주의해야 할 사항

 

1. 변수명은 항상 소문자로 시작해야하고 이어지는 단어들의 첫 시작은 대문자로 시작해야합니다, 플레이어의 점수를 변수로 나타낸다면 playerScore와 같이 나타낼수 있습니다, 변수명은 대소문자를 구별합니다

 

2. 변수명은 영문자로 시작해야하하고 변수가 어떤 값을 가지고있는지 명확하게 알 수 있도록 합니다

 

이외에도 여러가지가 있지만 가장 중요하다고 생각하는것은 변수명이 어떤 값을 가지고있는지 명확하게 알 수 있도록 해야하는것 이라고 생각합니다, 그러기 위해서는 변수명을 축약하지않고 의미 있는 단어를 사용해야합니다

 

나머지 규칙은 아래를 참고하거나 ' C# 네이밍'을 검색해보시기 바랍니다

 

 

 

자료형


자료형은 데이터의 종류와 구조를 정의하기 위해 사용됩니다, C#의 변수는 반드시 특정한 자료형을 가져야합니다

 

자료형에는 크게 값 형식과 참조 형식이있습니다, 먼저 값 형식에 대하여 알아보겠습니다 

 

값 형식은 메모리의 스택 영역에 저장됩니다, 이것이 의미하는 것은 int x = 10이 있다고 가정했을때, 10이라는 값은 메모리의 스택 영역의 특정 위치에  기록되고, 변수 x에 접근하고자 할때 곧바로 스택 영역의 주소를 참고하여 그 안에 있는 값을 꺼내 옵니다

 

값 형식의 변수를 다른 변수에 할당할 때 실제 값이 복사되어 다른 메모리 공간에서 독립적으로 존재하게됩니다

자료형의 종류에는 대표적으로 정수형, 실수형, 문자형, 불(참, 거짓)형이 있습니다, 모든 값 타입은 아래를 참고바랍니다

 

 

 

참조 형식

 

처음 값 형식과 참조 형식에 대한 설명을 듣게 된다면 값 형식은 데이터를 직접 저장하고 참조 형식은 메모리 주소를 저장한다고 들었을 것 입니다, 하지만 값타입 변수도 실제 값을 꺼내오기위해서는 스택 메모리의 어딘가에서 그 값을 꺼내와야 하기에 참조 타입에 대한 이해가 어렵다고 느껴질 수 도 있습니다

 

참조 형식은 메모리의 영역에 저장됩니다, 이것이 의미하는 것은 객체를 생성할 때, 그 객체의 데이터는 영역에 할당합니다, 그리고 데이터가 저장되어있는 메모리 주소를 스택 메모리에서 갖고있게됩니다

 

이것을 그림으로 그려서 설명해보겠습니다

참조 형식의 대표적인 것으로는 클래스가 있습니다, 예시로 클래스 A와 B가 있습니다, B클래스가 A클래스를 참조하는 경우입니다, 이러한 경우 서로 다른 스택 메모리를 사용하지만 실제 값을 들여다보면 동일한 힙 메모리주소를 가지고 있습니다

 

그래서 B클래스에서 무엇인가 수정했을때 B클래스의 스택 메모리에 저장된 힙 메모리 주소의 실제 값을 수정하고, A클래스에서 그 값을 확인한다면 A클래스의 스택 메모리에 저장된 힙 메모리 주소의 실제값을 참조하려고 하지만 동일한 힙 메모리 주소를 가지고 있기 때문에 결국 수정된 값을 참조하게됩니다

서로 다른 스택 메모리를 사용하지만, 동일한 힙 메모리 주소를 참조하여 객체의 값을 공유하게 됩니다

 

자료를 찾다보면 B b = A 같은 참조 구조를 많이 사용하고는 하는데 생각해보면 "실제로 이런식의 참조가 있을까?" 라는 생각이 들고 이해하기 어렵게 느껴질 수 도 있습니다

 

 

 

유니티에서 이러한 참조 구조를 가지는 경우를 살펴보겠습니다

DataManager라는 클래스가 있습니다, 그 안에 something이라는 변수도 있습니다

여기서 DataManager 클래스와 맴버 변수 something은 모두 영역에 저장됩니다

 

something은 int형식으로 값 타입인데 왜 스택이 아니라 영역에 저장될까요?

그 이유는 something은 DataManager 클래스의 맴버 변수로써 선언되었기 때문입니다

 

다시 말해 참조 타입인 DataManager 클래스의 객체의 일부분으로써 힙 메모리에 저장됩니다

클래스는 참조 형식이므로 클래스의 하위 모든 맴버 변수(값 and 참조 타입)는 클래스의 일부로써 힙 영역에 존재하게 됩니다

 

 

 

게임이 시작되면 유니티는 자동적으로 스크립트의 인스턴스를 생성하고 데이터를 영역에 올립니다

보라색 선은 Datamanager가 할당받은공간이라고 임시로 정해놓겠습니다

 

 

 

만약 Datamanager클래스 내의 메서드를 이용하여 something의 값을 50으로 바꾸어달라고 한다면 유니티 내부적으로 주소들을 참고하여 바꾸어주기에 그 과정을 알 필요는 없습니다

 

 

 

그리고 test 스크립트를 만들고 new를 이용하여 새로운 인스턴스를 만드려고 한다면 아래의 오류가 발생합니다, MonoBehaviour를 상속받는 클래스는 new 키워드를 이용하여 새로운 인스턴스를 만들 수 없습니다

 

 

 

그렇다면 처음 만들어진 DataManager의 값을 참조하고 싶다면 어떻게해야할까요?

test 스크립트입니다, 여기서 DataManager dataManager을 선언한 후 DataManager의 something 값을 수정해보겠습니다

 

 

 

그러자 오류가 발생했습니다, 스크립트에서 DataManager 변수를 선언만하고 초기화 하지 않는다면 그 내부의 값을 사용할 수 없습니다

 

 

 

그래서 FindAnyObjectByType();을 이용합니다, 그러면 dataManager의 스택 메모리에 이미 존재하던 DataManager의 힙 메모리 주소가 들어가게 됩니다

 

 

 

dataManager = DataManager;를 통하여 DataManager클래스의 힙 메모리 주소가 들어가게되니 결과적으로 위에서 설명했던 B b = A형식의 참조가 이루어지는 것입니다

 

이제 test 스크립트에서 dataManager의 값을 수정하면 동일한 힙 메모리 주소를 참조하여 작업을 수행하게 됩니다

 

이러한 참조는 GetComponent<>()도 마찬가지이고 Instantiate();도 동일합니다

 

참조 형식에는 대표적으로 클래스, 배열, 문자열이 있습니다

 

 

 

 

 

마치며


어쩌다보니 생각했던 자료형에 대한 설명에서 좀 벗어났지만 값 타입과 참조 타입의 차이를 헷갈릴 수 있기때문에 확실하게 알고 넘어가는 것 또한 좋다고 생각합니다

 

변수와 자료형을 알아봤으니 다음번에는 접근 제한자와 키워드에 대하여 알아보도록 하겠습니다 

 

이상입니다.

'코드 및 공부 > 기타' 카테고리의 다른 글

c# - 배열  (2) 2024.09.25
c# - 변수의 종류와 접근 제한자, 키워드  (0) 2024.09.24
속성(Attributes) (1)  (0) 2024.09.19
Git Commit Message Convention  (0) 2024.09.13
브랜치 전략(Git Flow)  (0) 2024.09.12