c++의 algorithm 헤더에는, 두 변수를 바꾸는 swap 메서드가 있습니다. 두 수를 바꾸는 swap 함수를, 구현해 봅시다. 저번 시간에 배운 포인터도 복습해 볼 겸 말입니다.
Main 함수에 a와 b가 할당되어 있습니다. 우리는 함수를 통해서 이 둘을 바꿔보려고 합니다. 그런데, 함수로 이 둘을 깡으로 넘기기에는, 힘들어 보입니다. 왜냐하면, 정수형으로 그냥 복사해 버리면, 다음과 같이 별개의 공간에 매개 변수가 생성이 되기 때문입니다.
그러면 우리는, Main에 있는 a의 주솟값과, b의 주솟값을 넘기자는 생각을 할 수 있습니다. 이 둘의 주솟값을 각각 0x80번지, 0x84번지라고 한다면, 다음과 같이 복사하면 됩니다.
이러한 주솟값을 저장할 수 있는 변수는 포인터 변수입니다. 정수형 포인터 변수를 매개 변수로 받으면 되겠네요.
대충 이렇게 작성하시면 됩니다. 그런데, 이렇게 해서 어떻게 swap 함수에서, main 함수에 있는 a와 b의 값을 바꿀까요?
먼저, swap 안에 temp 임시 변수를 생성합니다. 그리고 이 temp에 (*b)의 값을 넣습니다. b의 값이 0x84라면, 주솟값을 토대로, 참조한 실값은 b, 즉 3이 될 겁니다. 따라서, temp에는 3이 들어갑니다. 이를 그림으로 다시 표현해 보겠습니다.
당연하게도, (*b)의 값은 3이니, temp = (*b);를 수행하면, temp 변수에 3이 들어갈 겁니다. 그 다음에, 어떻게 하면 좋을까요? 3을 temp에 저장해 두었으니까, Main에 있는 a의 값을 Main에 있는 b에다 넣으면 좋을 거에요. a의 실 값은 어떻게 얻어오면 되나요? (*a). 0x80 번지에 있는 Main에 있는, a의 실값인 2를 얻어오는 문장입니다.
이것을 어디에 넣으면 좋을까요? Main의 b에다 넣으면 될 거에요. 그러면, 어떻게 해야 하나요? swap에 있는 매개변수 b는, Main의 b를 참조하고 있습니다. 즉, swap에서, (*b) 문장은, Main의 b에 접근한다는 소리가 됩니다. 그러면 (*b) = (*a)는 무엇을 의미할까요? Main의 b에 2를 넣는다는 이야기가 됩니다.
(*b) = (*a)를 다시 해석해 봅시다. 대입 연산은 우에서 좌로 결합합니다. 그러면 먼저 (*a)를 수행할 겁니다. rvalue가 2입니다. 대입을 하는 것은 어떠한 값을 어디에 넣느냐가 중요합니다. 예를 들어서, 3이라는 값을 c에 넣는다고 해 봅시다. c가 할당된 위치가 0x88번지라고 해 봅시다.
그러면 c = 3; 이라는 것은 c가 할당된 곳에, 3이라는 값을 넣으라는 것입니다. 0x84에 3을 넣으라는 게 아닙니다. 그러면 (*b) = (*a);는 무엇을 의미하나요? (*a)가 2였습니다. 그러면 (*b) = 2; 일 겁니다. swap의 b가 역참조 하고 있는 곳에 2를 넣으라는 말인데요. 이는 main의 b에 2를 넣으라는 말입니다. 따라서, Main에 있는 a와 b의 값이 2가 됩니다.
조금 설명이 긴 거 같네요. 두 줄 설명하느라. temp에는 3이 저장이 되어 있었습니다. 그러면 이것을 어디에 넣어야 하나요?
Main의 a에 넣어야 합니다. 이것을 누가 참조하고 있나요? 함수 내의 a가 참조하고 있습니다. 따라서 (*a) = temp;를 15번째 줄에 작성해 주시면 됩니다.
최종적으로 완성된 함수입니다. C언어에서는 call by value밖에 없기 때문에, Main에서 a와 b의 주솟값을 넘겼습니다. 그리고 * 연산자로 역참조 해서 swap 내에서 Main 안에 있는 변수들을 가지고 놀았다는 것이 중요합니다.
'코딩 > C' 카테고리의 다른 글
c언어 포인터 증감 연산 : 기준점으로부터 얼마만큼 이동하는가? (5) | 2019.10.29 |
---|---|
구조체 포인터 변수 : pointer만 알면 다른 건 똑같다. (7) | 2019.10.24 |
c언어 포인터 변수 : 주솟값을 저장한다. (11) | 2019.10.11 |
c언어 enum : 의미를 명확하게 해 보자. (6) | 2019.10.04 |
c언어 구조체 : 데이터들을 하나로 묶는다. (12) | 2019.10.01 |
최근댓글