C++ 문법 강의를 들으며 조금 헷갈리는 부분이 있었다.
강사님이 포인터와 레퍼런스를 잠깐 설명해주셨는데 둘의 동작이 비슷해보였다.
- 포인터와 레퍼런스의 차이
: 얼핏 들었을 때 둘이 동작하는 것이 비슷한데 둘이 차이점이 무엇일까 하고 생각하게 되었다.
따라서 차이점을 찾아서 따로 정리해보았다.
| 구분 | 포인터 | 레퍼런스 |
| 의미 | 주소 저장 | 변수의 별명 |
| 문법 | int* p | int& r |
| 재할당 | 가능 | 불가능 |
| NULL | 가능 | 불가능 |
| 사용법 | *p 필요 | 그냥 변수처럼 사용 |
* : 에스테르크, 역참조
이후 강의를 듣고 더 파고 들어가 보았다.
- 포인터 : 주소값을 저장하는 것이다.
포인터 값에 1을 더하면 주소값이 1 더해진다.
말로는 잘 모르겠으니 실습을 해보았다.


뒷자리만 읽어보았을 때 F934 >> F938 가 되었다.
- int 는 4byte 이기에 주소값이 1 더해지면 4byte가 더해지는 것이다.
- 포인터와 변수의 관계를 확실히 알아보았다.


- 그런데 결국 포인터가 주소를 저장하는 것은 알았는데 어디에 사용할 수 있는지를 알아야 했다.
우선 포인트 변수 A가 있을 때,
A를 출력하면 A의 주소값이 나온다. 그리고 *A를 출력하면 해당 메모리에 있는 값이 나온다.
그럼 A의 값을 수정하고 싶다면 *A = 10 이런식으로 수정할 수 있다.
배열 또한 변수와 같은 특성을 가지고 있으며 추가적으로 초기 주소를 가지고 있다.
예를 들어 buf[0] => X 라면 *buf => X 이다. 이는 *(buf + 0) 과 같으니
정리하자면 [중요] buf[k] = *(buf + k) 이다. 중요한 이유는 코드 구현시 혹은 다른 사람의 코드를 분석해야할 때 사용하기 때문이다.
- 결국 포인터와 배열은 동일한 것이 아닌가 싶었지만 결국 다르다.
이유로 가장 큰 것은 배열은 주소값을 변경할 수 없다는 것이다.
또한 변수의 크기가 다르다는 것도 있다.
포인터 변수의 크기는 타입과 무관하게 운영체계에서 관리하는 메모리 주소의 크기이다. 하지만 배열의 크기는 배열 원소 타입의 크기에 갯수를 곱한 것이다.
- 요약하자면, 배열은 여러 개의 데이터를 관리하기 위해 포인터가 가지고 있는 연산이 제공되는 변수 정도라고 생각하면 된다.
포인터를 공부할 때는 꼭 그림을 그려가며 공부해라.

- 배열 포인터와 포인터 배열
배열 포인터 : 배열 전체를 가리키는 포인터이다.
보통 다차원 배열을 제어할 때 많이 사용한다.


포인터 배열 : 포인터를 원소로 갖는 배열이다.
예를 들어, int* ptrArr[4]; 는 크기가 4이고, 각 원소가 int* 인 배열이다.
| * | * | * | * |
이처럼 각 원소가 * (포인터) 인 배열


포인터 배열의 특징 중 하나로는 위의 코드에서 (*ptr)[0] + 1 을 하였을 때 주소가 1 증가하여 20이 되는 것이 아닌 값이 1 증가하여 11 이 된다.
배열 포인터와 포인터 배열의 차이점 확인


이름이 굉장히 헷갈리므로 반드시 구분해서 익혀두어야 한다.
레퍼런스 : 똑같은 사람의 별명이기에 하나의 값이 바뀌면 다른 하나의 값도 똑같이 바뀌는 것.
특정 변수에 레퍼런스를 부여하면 마치 그 변수가 2개의 이름을 갖는 것과 같다.
- 사용 이유 : 포인터를 사용하면 주소값을 직접 다루기에 다소 복잡해질 수 있다. 이 문제를 완화하기 위해 변수에 또 다른 이름을 부여하는 레퍼런스를 사용하는 것이다.


- 상수 레퍼런스
레퍼런스에 상수 제약을 걸어서 읽기 전용으로 사용할 수 있다.
상수 레퍼런스를 사용하면 값을 복사하지 않고도 기존 변수를 보호할 수 있다.
ex) const int& cref = x; 하면 복사 과정 없이 x의 값을 읽을 수는 있지만 x 값을 수정할 수는 없다.
강의를 통해 두 문법의 정확한 의미와 사용법을 알았으니 이제 차이점을 다시 확인해 보겠다.
- 공통점으로는 다른 변수를 제어한다는 점에서 유사하지만 중요한 차이가 있다.
1) 선언과 초기화 시점이 다르다.
포인터는 선언 후 나중에 = 연산자를 통해 가리킬 대상을 변경 할 수 있다.
레퍼런스는 선언과 동시에 초기화 해야한다. 초기화 이후엔 다른 대상에 재연결 할 수 없다.
2) 레퍼런스는 항상 다른 변수와 연결되어 있기 때문에 NULL 이라는 것이 없다.
포인터는 유효한 대상이 없음을 나타내기 위해 NULL 혹은 nullptr 을 가질 수 있다.
3) 간접 창조 문법의 유무이다.
포인터는 주소값을 담으므로 접근할 때 * 연산을 사용하고 주소를 가져올 때 & 연산을 사용한다.
레퍼런스는 변수 자체의 별명이므로 일반 변수와 연산하는 방법이 동일하다.
- 강의를 들으며 제법 재밌었던 코드가 있었다.

랜덤으로 1 ~ 100 까지의 숫자를 저장한 뒤 그 값(랜덤값)을 추측해보는 간단한 시뮬레이션이었다.
먼저 1 ~ 100 중 하나의 숫자를 설정한 뒤 추측 값을 입력한다.
추측값이 랜덤값과 같지 않다면 거짓으로 아래의 if문을 실행한다.
만약 추측값이 랜덤값 보다 작다면 " Too low! Try again "을 출력한 뒤 다시 추측값을 입력한다.
추측값이 랜덤값 보다 작지 않다면 " Too high! Try again "을 출력한 뒤 다시 추측값을 입력한다.
이것을 반복하다 추측값이 랜덤값과 일치한다면 반복문을 빠져나와 정답을 맞췄다고 알려준 뒤 함수를 종료한다.
상단의 #include <cstdlib> 과 #include <ctime> 그리고 srand, rand 의 의미를 모르기에 좀 찾아보았다.
먼저 rand() 와 srand()를 알아보았다.
간단하게 설명하자면,
- rand() : 버튼 눌러서 숫자 뽑기
- srand() : 랜덤 기계 초기 설정
초기 설정을 바꾸지 않는다면 항상 똑같은 결과만 나오게 된다.
srand()는 보통 시간을 이용해서 사용한다.
- srand(time(0)) 현재 시간 0초에 실행 값을 초기화 해주는 것이기에 매번 실행시마다 값이 초기화 된다.
그렇다면 나머지는 간단하다
#include <cstdlib> == rand(), srand() 를 사용하기 위해서 필요
#include <ctime> == time() 을 사용하기 위해서 필요
- 포인터가 제법 헷갈리면서 이해가 잘 되지 않았다. 따라서 다소 많은 시간을 소요했으며 이해를 최대한 하려고 하는데에 중점을 두고 강의를 들으며 실습까지 직접 계속 해보았다. 아직도 완벽하게 이해가 어려운 부분이 배열 포인터와 포인터 배열이었으며 그 차이는 어느정도 감이 왔지만 확실하게 이해했어. 는 아닌 것 같다.
'본캠프 TIL' 카테고리의 다른 글
| 05.06 Unreal 본캠프) Text_RPG 제작 과정 (0) | 2026.05.06 |
|---|---|
| 05.04 Unreal 본캠프) CH2 과제 2번 시작 : Text_RPG 제작 (0) | 2026.05.04 |
| 04.29 Unreal 본캠프) 따라치기 세션 파일 빌드 오류 해결 및 깃 업로드 (1) | 2026.04.29 |
| 04.27 Unreal 본캠프) 배열, 함수 / FPS 완성 (0) | 2026.04.27 |
| 04.24 Unreal 본캠프 5일차) 반복문 정리/FPS만들기 과정 (1) | 2026.04.24 |