Doby's Lab

[C++] 포인터 개념, 백준 1838번: 버블 정렬 (2) 본문

C++

[C++] 포인터 개념, 백준 1838번: 버블 정렬 (2)

도비(Doby) 2021. 10. 1. 23:23

1838번 풀이 글과 이어진다.

[이전 포스팅 링크]

https://draw-code-boy.tistory.com/38

 

[알고리즘] 백준 1838번: 버블 정렬 (C++), 더 논리적인 감각을 만들어내야 한다

https://www.acmicpc.net/problem/1838 1838번: 버블 정렬 버블 정렬이란 배열에서 서로 인접해 있는 값을 비교해서 작은 값이 더 뒤에 있을 때 두 값을 바꾸어 주는 과정을 계속 반복하는 정렬 방법이다. N개

draw-code-boy.tistory.com

 

[주소 연산자]

포인터에 바로 들어가기 전에 주소 연산자(&)를 알아보자

주소 연산자는 말 그대로 어떤 한 변수의 주소를 가져와주는 연산자이다.

예를 들어

#include <stdio.h>

int main() {
	char a = 'i';
	int b = 1;
	double c = 3.14;

	printf("%d\n", &a);
	printf("%d\n", &b);
	printf("%d\n", &c);
	return 0;
}

(cout으로 출력했을 때는 예상치 못한 값이 나와 stdio.h에 있는 printf를 사용했다.)

이러한 코드(각 자료형)가 있으면 출력이 이렇게 된다.

즉, 각 변수의 주소 값을 가져왔다는 소리다.

정확히 말하면 각 변수가 메모리에 할당하는 가장 첫 번째 주소 값이다.

하지만, 한 번 더 출력했을 때는 다른 값이 나왔다. 크게 신경 쓸 것은 없다. (컴파일될 때마다 할당되는 메모리의 주소 값이 랜덤으로 달라지나 보다.)

 

[포인터]

포인터는 다른 변수의 주소 값을 저장하는 변수이다.

즉, 일반적인 변수에는 주소 값을 담을 수 없었다.

다른 자료형의 포인터에도 주소 값을 담을 수 없었다.

다음 코드로 실험을 해보았다.

#include <stdio.h>

int main() {
	char a = 'i';

	char a2 = &a;
	char* a3 = &a;
	int* a4 = &a;

	return 0;
}

a2는 같은 char(1바이트) 자료형이기는 하지만 포인터 변수가 아닌 일반적인 변수이기 때문에 주소 값을 담을 수 없다.

a3는 같은 char형에 포인터 변수라서 a3에는 a의 주소 값을 담을 수 있었다.

a4는 다른 int형의 포인터 변수라서 다른 자료형이라 담을 수 없었다.

 

포인터는 변수라는 것을 잊지 말자.

 

[간접 참조 연산자]

아마 이 부분 때문에 내가 포인터를 포기했었던 기억이 난다.

포인터를 선언할 때 쓰는 *와 간접적으로 참조할 때 쓰는 *는 다르게 생각해야 한다.

 

선언할 때 쓰는 포인터 변수는 알아보았으니 간접적으로 참조할 때 쓰는 변수에 대해 알아보자.

여기서 *는 이 포인터 변수가 가리키는 주소로 가서 이 주소에 해당하는 데이터를 읽어오거나 변경, 연산 등 마음대로 할 수 있다.

 

[변경 및 연산]

[읽기]

직접적으로 a를 건드려서 연산을 하거나 읽어오거나 여러 가지를 할 수 있지만 a를 건드리지 않고도 주소 값이라는 경로를 통해 데이터를 조정할 수 있다.

 


기본 개념 정리

여기까지가 포인터의 기본 개념의 정리다. 포인터의 연산, 배열과의 관계, 함수 인자 등 더 공부해야 할 것이 많고, 여러 곳에서 많이 사용된다.


버블 정렬 문제

포인터 기본 개념을 알았지만 문제를 해결할 수는 없었다.

int BS(vector<int> arr2, int low, int high, int findIdx)

이 두 코드의 차이점은 벡터 int형 배열에 &가 있고 없고 차이다.

int BS(vector<int> &arr2, int low, int high, int findIdx)

그래서 찾아본 결과 Call-By-Value, Call-By-Address, Call-By-Reference 개념이 나오는데 다 알아보지는 않겠다. 여기서 사용된 것이 Call-By-Reference라고 한다.

 

아무래도 Call-By-reference가 Call-By-Value보다 빠르다고 말하는 곳은 많이 없었지만 몇몇 군데에서 찾을 수 있었다.

https://oojjrs.tistory.com/22

 

값에 의한 호출과 참조 호출의 비교

서적 Effective C++ 은 개발자에게 널리 알려진 좋은 책이다. 그 중 개정 3판의 20항목에 다음과 같은 이야기가 나온다. "값에 의한 호출보다는 상수 객체 참조에 의한 호출이 대개의 경우 낫다" 물론

oojjrs.tistory.com

https://boycoding.tistory.com/217

 

C++ 08.03 - 참조로 전달 (Pass by reference)

08.03 - 참조로 전달 (Pass by reference) 값으로 전달은 두 가지 한계가 있다. 첫째, 큰 구조체 또는 클래스를 함수에 전달할 때 값으로 전달은 인수의 복사본을 함수 매개 변수로 만든다. 이 경우 복사

boycoding.tistory.com

(참조로 전달의 장점 부분에서 이야기한다.)

 

우선은 함수에 매개변수를 쓸 때, Call-By-Reference형식으로 하고 관련 지식이 필요해진다면 이와 관련해 포스팅하겠다.

(C언어는 Call-By-Reference를 지원하지 않는 듯하다.)


포인터 지식 참고

https://m.blog.naver.com/sharonichoya/220483089874

 

C언어 포인터 기본개념

* C언어에서 포인터(pointer)는 가장 강력한 기능이라 말할 수 있다. 이유인즉 개발자가 메모리의 일부를 ...

blog.naver.com

 

728x90