티스토리 뷰
저번 포스팅에서는 C#의 Pass by value에 대해 알아보았습니다.
짧은 예제를 통해 value type의 변수와 reference type의 변수를 parameter로 보냈을 때의 동작을 알아보았죠.
그리고 value type과 reference type의 동작 차이에 대해서는 저저번 포스팅에서 설명드렸었습니다.
in, out, ref 키워드
이번 포스팅에서는 Pass by reference에 대해 알아보겠습니다.
먼저 요약해서 말씀드리면 C#에서는 ref, out 혹은 in 이라는 키워드를 통해 Pass by reference를 구현합니다.
이름에서 유추할 수 있듯이 ref는 reference로 보낸다는 것을 뜻하고
in은 입력 용도로, out은 출력 용도로 사용한다는 것을 뜻합니다.
한 가지 기억할 것은 in, out 키워드는 내부적으로 ref 키워드를 붙였을 때의 동작 방식과 같으며
특정 제약 조건이 추가된 것입니다.
가장 먼저 각 키워드의 특징과 사용법을 알아봅시다.
먼저 ref 키워드입니다.
ref 키워드는 함수 선언과 호출에 모두 붙여서 사용해야 합니다. (한 곳에만 붙일 경우 컴파일 에러가 납니다.)
ref로 보내는 변수의 경우 초기화를 생략할 수 없으며 함수 내부에서는 읽기와 쓰기 모두 가능합니다.
단, 읽기와 쓰기가 강제는 아니어서 아무것도 하지 않아도 괜찮습니다.
그리고 가장 중요하게도 함수 내부에서 값을 수정하면 함수 외부에서도 값이 바뀝니다.
다음은 in 키워드 입니다.
in 키워드는 함수 선언과 호출에 모두 붙일 수 있으며 호출에는 안 쓰고 선언에만 쓰는 경우도 가능합니다.
in으로 보내는 변수 역시 초기화를 생략할 수 없으며 함수 내부에서는 읽기만 가능합니다.
읽기가 강제는 아닙니다.
또 쓰기가 불가능하기 때문에 함수가 호출되고 값이 바뀔 수가 없습니다.
마지막으로는 out 키워드 입니다.
out 키워드는 함수 선언과 호출에 모두 붙여서 사용해야 합니다. (한 곳에만 붙일 경우 컴파일 에러가 납니다.)
out으로 보내는 변수는 초기화를 생략할 수 있으며 함수 내부에서는 쓰기만 가능하며 강제됩니다.
쓰기가 강제되기 때문에 함수가 호출되고 나면 무조건 값이 바뀌어 있습니다.
종합해서 보자면 사실 in과 out 키워드는 기본적으로 ref 키워드와 똑같이 동작하지만 특정 제약조건을 준 것입니다.
이런 제약 조건을 주는 이유는 다른 프로그래머들에게 의도를 알리고 잘못된 사용을 막는 것입니다.
대략적으로 보면 ref는 읽기 쓰기 가능, in은 쓰기 금지, out은 읽기 금지인거죠.
지금까지 Pass by reference를 하는 방법에 대해서 알아보았습니다.
이제부터 어떤 상황에서 왜 Pass by reference를 쓰는지
또 Pass by reference를 쓸 경우 어떻게 다르게 동작하는지 알아봅시다.
Pass by reference를 사용하는 상황과 동작 방식
Pass by reference를 사용하는 상황은 크게 3가지가 있습니다.
1. 커다란 Struct 변수를 함수 인자로 보내고 싶은데 메모리 복사하는 연산이 부담스러울 때
2. 어떤 Referece Type 변수의 생성을 함수 안에서 해야할 때 (string 변수에서 특히 많이 발생)
3. 함수로부터 여러 타입의 리턴 값을 받고 싶을 때
왜 이런 상황에서 Pass by reference를 사용하는 것일까요?
간단한 예제를 통해 ref 키워드를 사용했을 때의 동작 방식을 좀 더 알아봅시다.
위와 같은 예제가 있을 때 결과는 어떻게 될까요?
Function4와 Function5 모두 본문은 단순히 새로운 Person 객체를 생성하고
p 변수가 해당 객체를 가리키도록 하고 있습니다.
대체로 눈치 채셨겠지만 결과는 아래와 같습니다.
person1.strength가 0으로 출력되는 이유는 Person Class에 따로 생성자를 두지 않았고
strength는 기본적으로 0으로 초기화되기 때문입니다.
여기서 중요한 것은 person1은 Function4 함수가 호출된 후 함수 본문의 영향을 그대로 받았고
person2는 Function5 함수가 호출된 후 함수 본문의 영향을 받지 않았다는 것이죠.
보시다시피 Pass by reference를 하게 되면
인자로 받은 변수 그 자체를 바로 함수 본문에서 사용하는 것처럼 동작하게 됩니다.
함수 사용 부분에서 우리가 만든 person1과 Function4에서 사용된 p는 프로그래머 눈에만 다르게 보일 뿐
사실 컴퓨터에게는 같은 변수(같은 메모리 공간)으로 취급되는 것이지요.
이전 포스팅에서 소개한 Pass by value가 사실은 변수 선언과 복사를 내포하고 있는 것과 배치됩니다.
Pass by reference의 동작 방식을 이해했다면 앞서 말한 3가지 이유가 어느 정도 설명이 될 것입니다.
1. 커다란 Struct 변수를 함수 인자로 보내고 싶은데 메모리 복사하는 연산이 부담스러울 때
1번의 경우 Pass by reference 방식이 Pass by value와 달리 변수의 선언과 복사가 내포되어 있지 않다는 것을 알게 되면 이해할 수 있습니다.
2. 어떤 Referece Type 변수의 생성을 함수 안에서 해야할 때 (string 변수에서 특히 많이 발생)
2번의 경우 위 예제에서 설명했듯이 Reference Type 변수의 생성을 함수 내부에서 하고 인자를 통해 전달할 경우 ref 키워드를 사용해야 합니다.
물론 return문을 사용하여 말끔히 생성된 객체를 돌려줄 수 있기는 합니다.
3. 함수로부터 여러 타입의 리턴 값을 받고 싶을 때
3번의 경우도 Pass by reference가 인자의 값을 변경할 수 있는 특성을 이해함으로써 알 수 있습니다.
지금까지의 과정을 통해 Value Type, Reference Type, Pass by value, Pass by reference에 대해서 알아보았습니다.
이미 프로그래밍을 많이 해본 사람들이라면 어렵지 않은 내용이겠지만
처음 프로그래밍 언어로 C#을 접한 사람에게는 어려울 수 있을거라 생각합니다.
개인적으로 글을 쓰면서 어떤 사람들을 타겟으로 해야할 지를 순간, 순간 헷갈린거 같아 아쉬움이 좀 남습니다.
어찌되었던 글을 쓰면서 공부를 할 수 있었고 다른 사람들에게 조금이나마 정보를 전달한 것에 의미를 둡니다.
'프로그래밍' 카테고리의 다른 글
로슬린 MakeConst 튜토리얼 (1/2) (0) | 2021.08.27 |
---|---|
C#의 Reflection (0) | 2021.02.27 |
C#의 Pass by value (0) | 2021.02.14 |
C# Value Type과 Reference Type (1) | 2021.02.12 |
닷넷 프레임워크 용어 정리 (0) | 2021.01.31 |
- Total
- Today
- Yesterday
- 참조 형식
- static batching
- 루빅스큐브
- reference type
- 값 형식
- CollisionDetection
- Mesh
- NDC
- C#
- Unreal
- value type
- transform
- RL
- MeshProcessing
- dynamic batching
- opengl
- normalized device coordinate
- Mesh Processing
- SRP
- AABB
- 유니티
- Scriptable Render Pipeline
- RubiksCube
- VTK
- collision detection
- Transformation
- batching
- perspective projection
- Unity
- 강화학습
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |