728x90
최근 python을 많이 사용하다 보니 함수 만들때 자꾸 def를 하질 않나.. object return 할때 여러개를 던지려고 하질 않나... 그래서 정리해본다 🙂
함수 값을 전달할 때 몇 가지 방법이 있는데,
정리하자면 Call by ( value, reference, address ) 가 있다.
그전에 *과 &에 대해서 간단하게 설명하자면
0. *과 &
*와 & 는 변수에 대해서 "연산"할 때 사용하기도 "선언", "구문"에서 사용하기도 한다.
1) "연산"으로 써 두 변수의 의미는 다음과 같음
c = a * b // a 와 b를 곱하여 c에 저장
a = 3 & 4 // 비트 연산 (AND) 011 & 100 = a에 0 저장
b = 6 & 10 // 110 & 1010 = b에 2 저장
2) "선언" 에서의 의미
* 가 선언문에서 변수 타입 뒤에 붙으면 "포인터형 변수"를 선언한다는 뜻이 된다.
& 가 선언문에서 붙으면 "별칭" 참조자를 의미함
int* x; // x 라는 정수형 포인터를 선언함.
int *x; // 동일함.
int * x; // 동일함.
int z;
int &a = z;
a = 3;
// a는 z의 aliasing이 됨 a == z
cout << "z : " << z << " " <<&z << " a : " << a << " " << &a << endl;
// z : 3 0x7ffcf586f4fc a : 3 0x7ffcf586f4fc
3) "구문" 에서의 의미
- *역참조, & 주소
int i = 3; // 정수형 변수 i 를 선언하고 3으로 초기화한다.
cout << "1) i : " << i << " " << &i << endl;
int *j = &i; // 정수 포인터형 변수 j 를 선언하고 i의 주소값을 넣는다.
cout << "2) i : " << i << " " << &i << endl;
cout << "2) j : " << j << " "<< *j <<" " << &j << endl;
*j = 4; // j의 역참조값에 4를 넣는다. 즉 여기서 i는 4가 된다.
cout << "3) i : " << i << " " << &i << endl;
cout << "3) j : " << j << " "<< *j <<" " << &j << endl;
/*
j : &i
*j : i
1) i : 3 0x7ffe7413b004
2) i : 3 0x7ffe7413b004
2) j : 0x7ffe7413b004 3 0x7ffe7413b008
3) i : 4 0x7ffe7413b004
3) j : 0x7ffe7413b004 4 0x7ffe7413b008
*/
1. 값에 의한 전달( call by value )
- 함수의 지역변수이자 매개 변수인 int y에 의해 x의 값이 복사 됨
- 함수 내에서 y 값을 변경하더라도 x에 영향을 주지 않음
// 함수 내에서 y 값을 변경하더라도 x에 영향을 주지 않음 (복사되기 때문에)
void foo(int y){
cout << "func Address : " << &y << endl;
}
int main()
{
foo(5); // foo -> int y 선언 -> y = 5 & 인자 복사
int x = 6;
cout << "main Address : " << x << " , "<< &x << endl;
foo(x); // 실제 전달 되는것은 a의 6이라는 값이 argument로 param으로 전달 되는 것
foo(x+1);
}
/*
func, main의 주소 값이 다른 걸 알 수 있음
*/
- 함수로 전달된 인수 값이 복사 되어 매개변수에 넘겨짐
2. 참조에 의한 인수 전달
- 값이 참조 되는 것 복사가 일어나지 않음
void addOne(int &y) // 보통 이렇게 안하고 함수 내에서 바뀌지 않는다면 const int &y로 인수 받음
{
y = y+1;
cout << "y: " << y << " " << &y << endl;
}
int main()
{
int x = 5;
cout << "x: " << x << " " << &x << endl;
addOne(x); // x라는 변수 자체가 전달 되는 것 값의 복사가 일어나지 않고 아예 전달하는 것
cout << "x: " << x << " " << &x << endl;
}
3. 주소에 의한 전달
- 주소에 의한 전달도 주소 값을 가진 변수를 하나 더 복사함
- 결국에 함수안에 작업이 있으면 바깥에 있는 넣어준 변수 값도 바뀌지만 그 이유는 함수에 연결할 때 넣어주는 value 변수를 가르치는 ptr(주소값을 가진 변수)가 하나더 "복사" 되기 때문에 최종적으로 value 값을 가르치는 주소를 가진 변수들이 2개가 생기게 되는 것!!! 그래서 value 값에도 변경이 있지만 변수가 늘어남!
// pointer에 의한 호출은 주소 값을 복사하는 특수한 값을 가지고 있는 변수다! 라는 것을 알아야함
// 복사가 이루어지고 있습니다 하지만 참조연산 처럼 외부변수에도 영향을 줄 수 있음 output 처럼 쓸 수 있음
void foo(int *ptr){
cout << *ptr << " " << ptr << " " << &ptr<< endl;
}
int main(){
int value = 5;
cout << "value : "<< value << " " << &value << endl;
int *ptr = &value;
cout << "ptr address : " << &ptr << " ptr : " << ptr << endl;
// foo(4); 불가능 , 앞에서 addOne(3)도 불가능
foo(ptr);
foo(&value);
}
/*
value : 5 0x7fff4f4c534c
ptr address : 0x7fff4f4c5350 ptr(= &value) : 0x7fff4f4c534c
ptr : 5(*ptr==value) 0x7fff4f4c534c (ptr == &value) 0x7fff4f4c5328(copy new)
ptr : 5 0x7fff4f4c534c 0x7fff4f4c5328
*/
// 한번 더 확인
void foo(int *ptr){
*ptr += 1;
cout << "in ptr : " << *ptr << " in_ptr point " << ptr << " in_ptr add " << &ptr<< endl;
}
int value = 5;
cout << "value : "<< value << " " << &value << endl;
int *ptr = &value;
cout << "ptr address : " << &ptr << " ptr : " << ptr << endl;
foo(ptr);
cout << "out value : "<< value << " " << &value << endl;
cout << "out ptr address : " << &ptr << " ptr : " << ptr << endl;
foo(&value);
cout << "out value : "<< value << " " << &value << endl;
cout << "out ptr address : " << &ptr << " ptr : " << ptr << endl;
/*
value : 5 0x7ffdd8b5066c
ptr address : 0x7ffdd8b50670 ptr : 0x7ffdd8b5066c
in ptr : 6 in_ptr point 0x7ffdd8b5066c in_ptr add 0x7ffdd8b50648
out value : 6 0x7ffdd8b5066c
out ptr address : 0x7ffdd8b50670 ptr : 0x7ffdd8b5066c
in ptr : 7 in_ptr point 0x7ffdd8b5066c in_ptr add 0x7ffdd8b50648
out value : 7 0x7ffdd8b5066c
out ptr address : 0x7ffdd8b50670 ptr : 0x7ffdd8b5066c
*/
728x90
'Done > C++_Python' 카테고리의 다른 글
[Deep learning] Pytorch 처음부터 KITTI dataset을 이용한 object detection - [1] (0) | 2023.06.09 |
---|---|
[Deep learning] Pytorch 처음부터 KITTI dataset을 이용한 object detection - [0] (0) | 2023.06.09 |
[Python] 지정 경로에 경로 존재 여부 확인, 디렉토리 생성 (0) | 2023.06.01 |
[OpenCV python]컨투어 찾기 ( cv2.findContours ) (0) | 2023.06.01 |
[Ubuntu CMake] OpenCV 원하는 폴더에 build & Install (0) | 2023.06.01 |