[C++] 참조 기초
참조 기초
인프런 Rookiss님의 'Part1: C++ 프로그래밍 입문' 강의를 기반으로 정리한 필기입니다.
😎[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part1: C++ 프로그래밍 입문 강의 들으러 가기!
전달 방식들
1. 값 전달 방식
- 임시적으로 매개변수에 복사받은 구조체에 접근해서 꺼내쓰는 방식
- 원본 정보는 건드리지 않는다.
- 아래의 경우, 원본의 정보는 건드리지 않고 임시값만 수정하고 함수가 호출되었을때 스택영역은 더 이상 유효하지 않아 날라가기 때문에 아무런 변화도 일어나지 않는다.
[매개변수][RET][지역변수(info)] [매개변수(info(100, 8, 5)][RET][지역변수]
[매개변수][RET][지역변수(info)]
void CreateMonster(StatInfo info)
{
info.hp = 100;
info.attack = 8;
info.defence = 5;
}
[매개변수][RET][지역변수(info)] [매개변수(info)][RET][지역변수]
void PrintInfoByCopy(StatInfo info)
{
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
}
2. 주소 전달 방식
- 원본(지역변수)에 접근해서 꺼내쓰는 방식
[매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void CreateMonster(StatInfo* info)
{
info->hp = 100;
info->attack = 8;
info->defence = 5;
}
[매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void PrintInfoByPtr(StatInfo* info)
{
cout << "HP: " << info->hp << endl;
cout << "ATT: " << info->attack << endl;
cout << "DEF: " << info->defence << endl;
}
3. 참조 전달 방식
- 값 전달처럼 편리하게 사용하고!
- 주소 전달처럼 주소값을 이용해 진퉁을 건드리는 일석이조의 방식!
void PrintInfoByRef(StatInfo& info)
{
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
}
StatInfo 구조체가 1000바이트 짜리 대형 구조체라면?
- (값 전달) StatInfo로 넘기면 1000바이트가 복사됨
- (주소 전달) StatInfo*는 8바이트
- (참조 전달) StatInf&*는 8바이트
4바이트 정수형 바구니를 사용할거야. 앞으로 그 바구니 이름을 number라고 할게.
그러니까 number에서 뭘 꺼내거나, number에 뭘 넣는다고 하면 찰떡같이 알아듣고 해당 주소(dat, stack, heap)에 1을 넣어주면 된다!
int number = 1;
* 주소를 담는 바구니
int 그 바구니를 따라가면 int 데이터(바구니)가 있음
int* pointer = &number;
pointer 바구니에 있는 주소를 타고 이동해서, 그 멀리 있는 바구니에 2를 넣는다
*pointer = 2;
로우레벨(어셈블리) 관점에서 실제 작동 방식은 int*와 똑같음
실제로 실행해보면 포인터랑 100% 똑같다.
int& reference = number;
C++ 관점에서는 number라는 바구니에 또 다른 이름을 부여한 것
number라는 바구니에 reference라는 다른 이름을 지어줄게~
앞으로 reference 바구니에다가 뭘 꺼내거나 넣으면,
실제 number 바구니(진짜에다가) 그 값을 꺼내거나 넣으면 됨!
reference = 3;
그런데 귀찮게 또 다른 이름을 짓는 이유는?
- 그냥 number = 3이라고 해도 똑같지만 참조 전달 때문!
int main()
{
StatInfo info;
CreateMonster(&info);
PrintInfoByCopy(info);
PrintInfoByPtr(&info);
PrintInfoByRef(info);
return 0;
}
코드
#include <iostream>
using namespace std;
// 참조
struct StatInfo
{
int hp; // +0
int attack; // +4
int defence; // +8
};
// [매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void CreateMonster(StatInfo* info)
{
info->hp = 100;
info->attack = 8;
info->defence = 5;
}
// [매개변수][RET][지역변수(info)] [매개변수(info(100, 8, 5)][RET][지역변수]
// [매개변수][RET][지역변수(info)]
void CreateMonster(StatInfo info)
{
info.hp = 100;
info.attack = 8;
info.defence = 5;
}
//값을 수정하지 않는다면, 양쪽 다 일단 문제 없음
// 1) 값 전달 방식
// 임시적으로 매개변수에 복사받은 구조체에 접근해서 꺼내쓰는 방식
// [매개변수][RET][지역변수(info)] [매개변수(info )][RET][지역변수]
void PrintInfoByCopy(StatInfo info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
cout << "-------------------- " << endl;
}
// 2) 주소 전달 방식
// 원본(지역변수)에 접근해서 꺼내쓰는 방식
// [매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void PrintInfoByPtr(StatInfo* info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info->hp << endl;
cout << "ATT: " << info->attack << endl;
cout << "DEF: " << info->defence << endl;
cout << "-------------------- " << endl;
}
// 3) 참조 전달 방식
// 값 전달처럼 편리하게 사용하고!
// 주소 전달처럼 주소값을 이용해 진퉁을 건드리는
// 일석이조의 방식!
void PrintInfoByRef(StatInfo& info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
cout << "-------------------- " << endl;
}
// StatInfo 구조체가 1000바이트 짜리 대형 구조체라면?
// - (값 전달) StatInfo로 넘기면 1000바이트가 복사됨
// - (주소 전달) StatInfo*는 8바이트
// - (참조 전달) StatInf&*는 8바이트
int main()
{
// 4바이트 정수형 바구니를 사용할거야
// 앞으로 그 바구니 이름을 number라고 할게
// 그러니까 number에서 뭘 꺼내거나, number에 뭘 넣는다고 하면
// 찰떡같이 알아듣고 해당 주소(dat, stack, heap)에 1을 넣어주면 된다!
int number = 1;
// * 주소를 담는 바구니
// int 그 바구니를 따라가면 int 데이터(바구니)가 있음
int* pointer = &number;
// pointer 바구니에 있는 주소를 타고 이동해서, 그 멀리 있는 바구니에 2를 넣는다
*pointer = 2;
// 로우레벨(어셈블리) 관점에서 실제 작동 방식은 int*와 똑같음
// 실제로 실행해보면 포인터랑 100% 똑같다
int& reference = number;
// C++ 관점에서는 number라는 바구니에 또 다른 이름을 부여한 것
// number라는 바구니에 reference라는 다른 이름을 지어줄게~
// 앞으로 reference 바구니에다가 뭘 꺼내거나 넣으면,
// 실제 number 바구니(진짜에다가) 그 값을 꺼내거나 넣으면 됨!
reference = 3;
// 그런데 귀찮게 또 다른 이름을 짓는 이유는?
// 그냥 number = 3이라고 해도 똑같지만
// 참조 전달 때문!
StatInfo info;
CreateMonster(&info);
PrintInfoByCopy(info);
PrintInfoByPtr(&info);
PrintInfoByRef(info);
return 0;
}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include <iostream>
using namespace std;
// 참조
struct StatInfo
{
int hp; // +0
int attack; // +4
int defence; // +8
};
// [매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void CreateMonster(StatInfo* info)
{
info->hp = 100;
info->attack = 8;
info->defence = 5;
}
// [매개변수][RET][지역변수(info)] [매개변수(info(100, 8, 5)][RET][지역변수]
// [매개변수][RET][지역변수(info)]
void CreateMonster(StatInfo info)
{
info.hp = 100;
info.attack = 8;
info.defence = 5;
}
//값을 수정하지 않는다면, 양쪽 다 일단 문제 없음
// 1) 값 전달 방식
// 임시적으로 매개변수에 복사받은 구조체에 접근해서 꺼내쓰는 방식
// [매개변수][RET][지역변수(info)] [매개변수(info )][RET][지역변수]
void PrintInfoByCopy(StatInfo info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
cout << "-------------------- " << endl;
}
// 2) 주소 전달 방식
// 원본(지역변수)에 접근해서 꺼내쓰는 방식
// [매개변수][RET][지역변수(info)] [매개변수(&info)][RET][지역변수]
void PrintInfoByPtr(StatInfo* info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info->hp << endl;
cout << "ATT: " << info->attack << endl;
cout << "DEF: " << info->defence << endl;
cout << "-------------------- " << endl;
}
// 3) 참조 전달 방식
// 값 전달처럼 편리하게 사용하고!
// 주소 전달처럼 주소값을 이용해 진퉁을 건드리는
// 일석이조의 방식!
void PrintInfoByRef(StatInfo& info)
{
cout << "-------------------- " << endl;
cout << "HP: " << info.hp << endl;
cout << "ATT: " << info.attack << endl;
cout << "DEF: " << info.defence << endl;
cout << "-------------------- " << endl;
}
// StatInfo 구조체가 1000바이트 짜리 대형 구조체라면?
// - (값 전달) StatInfo로 넘기면 1000바이트가 복사됨
// - (주소 전달) StatInfo*는 8바이트
// - (참조 전달) StatInf&*는 8바이트
int main()
{
// 4바이트 정수형 바구니를 사용할거야
// 앞으로 그 바구니 이름을 number라고 할게
// 그러니까 number에서 뭘 꺼내거나, number에 뭘 넣는다고 하면
// 찰떡같이 알아듣고 해당 주소(dat, stack, heap)에 1을 넣어주면 된다!
int number = 1;
// * 주소를 담는 바구니
// int 그 바구니를 따라가면 int 데이터(바구니)가 있음
int* pointer = &number;
// pointer 바구니에 있는 주소를 타고 이동해서, 그 멀리 있는 바구니에 2를 넣는다
*pointer = 2;
// 로우레벨(어셈블리) 관점에서 실제 작동 방식은 int*와 똑같음
// 실제로 실행해보면 포인터랑 100% 똑같다
int& reference = number;
// C++ 관점에서는 number라는 바구니에 또 다른 이름을 부여한 것
// number라는 바구니에 reference라는 다른 이름을 지어줄게~
// 앞으로 reference 바구니에다가 뭘 꺼내거나 넣으면,
// 실제 number 바구니(진짜에다가) 그 값을 꺼내거나 넣으면 됨!
reference = 3;
// 그런데 귀찮게 또 다른 이름을 짓는 이유는?
// 그냥 number = 3이라고 해도 똑같지만
// 참조 전달 때문!
StatInfo info;
CreateMonster(&info);
PrintInfoByCopy(info);
PrintInfoByPtr(&info);
PrintInfoByRef(info);
return 0;
}
|
cs |
'값 전달' 방식 보다는 '주소 전달' 또는 '참조 전달' 방식 위주로 사용하자.
pointer 사용방식이랑 reference 사용방식이랑 동일하다.
'⭐ Programming > C++' 카테고리의 다른 글
[C++] 배열 기초 (0) | 2022.03.26 |
---|---|
[C++] 포인터 vs 참조, const (0) | 2022.03.26 |
[C++] 포인터 실습 (0) | 2022.03.26 |
[C++] 포인터 연산 (0) | 2022.03.25 |
[C++] 포인터 #2 (0) | 2022.03.25 |
댓글
이 글 공유하기
다른 글
-
[C++] 배열 기초
[C++] 배열 기초
2022.03.26 -
[C++] 포인터 vs 참조, const
[C++] 포인터 vs 참조, const
2022.03.26 -
[C++] 포인터 실습
[C++] 포인터 실습
2022.03.26 -
[C++] 포인터 연산
[C++] 포인터 연산
2022.03.25