- 포인터 -> 값을 담지 않고 변수의 주소값을 담는다.
- 메모리의 주소값을 알면 해당 공간을 직접 제어한다.
- int *p와 같이 선언된 p는 정수를 가리키는 포인터로서 int 변수의 메모리 주소를 저장한다.
- 포인터는 선언시에 반드시 초기화해주어야한다.
- 포인터 크기는 가리키는 자료형과 상관없이 “컴퓨터 아키텍처(32bit / 64bit)”에 따라 결정된다. 메모리 주소를 저장하기 때문이다.
1️⃣ 포인터 크기
시스템포인터 크기
| 32bit | 4 byte |
| 64bit | 8 byte |
복사를 할 때는 비용이 들기 때문에, 특히 배열을 복사할 때 C++에서는 값을 직접 복사하는 방식 대신 변수의 주소를 가리켜서 동일한 데이터에 접근할 수 있도록 한다.
배열 이름은 배열의 시작주소를 가지고 있다. 배열의 경우 p+1은 배열의 다음 원소 주소이다. 변수 타입에 따라 +1은 자동으로 오프셋처리된다. int* ptr1이 &a라면 int* ptr2[]는 b라고 해도 된다.
- int arr[3]={10, 20, 30};
- int *p = arr;
- cout << "p가 가리키는 값 : " << *p << endl;
- cout << "p+1이 가리키는 값: " << *(p+1) << endl;
- cout << "p+2가 가리키는 값: " << *(p+2) << endl;
문자형 포인터를 출력하려면 (void*)ptr 해줘야한다.
- (void*)ptr 는 ptr을 void* 타입으로 형변환(casting) 한다는 의미
- 어떤 타입의 주소든 저장할 수 있는 포인터
- void*를 generic pointer(범용 포인터)
포인터와 배열의 차이
- 배열의 이름은 사용될 때 포인터로 묵시적 형변환되어 동작
- int arr[4];가 있을 때 arr은 배열 전체를 의미
- 배열 이름은 주소값을 담고 있고, 이 주소값 대신 다른 주소값을 할당할 수 없다.
- 배열의 크기는 배열 길이*자료형 크기지만, 포인터는 시스템에 따른 크기를 가진다.
포인터 배열과 배열 포인터
포인터 배열 선언
- int* ptrArr[3] = {&a, &b, &c};
- 각 원소가 int* 타입
배열 포인터 선언
- int (*ptrArr)[3] = &arr;
- 접근: (*ptr)[0]
배열 포인터는 2차원배열에서 쓴다.
레퍼런스
- 특정 변수에 대한 별명을 부여
- int& ref = var
- 이렇게 하면 ref의 값 변경 시 var의 값도 변경됨
포인터와 레퍼런스 차이
- 선언 시 초기화 시점이 다름
- 레퍼런스는 선언과 동시에 참조할 변수를 정해야 하고, 초기화 이후에는 다른 대상에 재연결 불가능
- 레퍼런스는 항상 다른 변수와 연결되어있기 때문에 NULL이 없다. 반면 포인터는 NULL, nullptr을 가질 수 있다.
상수 레퍼런스
- 레퍼런스에 상수 제약(const)을 걸어서 읽기 전용으로 사용할 수 있다.
- 상수 레퍼런스를 사용하면 값을 복사하지 않고도 기존 변수를 보호할 수 있다.
'코딩 학습 > C와 C++' 카테고리의 다른 글
| C++ 기초 - Vector, Map (0) | 2026.03.09 |
|---|---|
| C++ 기초 - 클래스 (0) | 2026.03.06 |
| C++ 기초 - Visual Studio 실행, 변수, 입출력 (0) | 2026.03.04 |
| C - 배열 (0) | 2026.03.04 |
| C 언어 연습 (0) | 2026.03.03 |