728x90
8. 포인터
포인터란?
포인터(pointer)는 메모리 주소를 저장하는 변수입니다. 즉, 특정 변수의 메모리 주소를 가리키며, 이를 통해 해당 변수의 값을 간접적으로 접근하고 수정할 수 있습니다.
기본 개념
// 포인터 변수 선언 및 초기화
int* pint = nullptr; // nullptr은 0x00000000을 의미하며, 포인터가 아무것도 가리키지 않음을 나타냄
int i = 100;
// & : 변수의 주소값을 가져오는 연산자
int* pint2 = &i; // i의 주소를 pint2에 저장
// 주소를 이용한 값 변경
(*pint2) = 200; // pint2가 가리키는 변수 i의 값을 200으로 변경
// 다른 데이터 타입의 포인터
float f = 3.14f;
float* pf = &f; // f의 주소를 pf에 저장
주소의 단위는 바이트(Byte)
C++에서 메모리 주소는 16진수(HEX)로 표현됩니다. 주소 앞의 0x는 해당 숫자가 16진수임을 나타냅니다.
데이터 타입에 따른 포인터 정리
데이터 타입 | 포인터 타입 | 설명 |
int | int* | 정수형 포인터 |
float | float* | 실수형 포인터 |
double | double* | 배정밀도 실수형 포인터 |
char | char* | 문자형 포인터 (C 스타일 문자열 처리 가능) |
bool | bool* | 불리언형 포인터 |
void | void* | 타입이 지정되지 않은 포인터 (범용 포인터) |
int[] | int* | 정수형 배열 포인터 (배열의 첫 번째 요소 주소) |
float[] | float* | 실수형 배열 포인터 |
double[] | double* | 배정밀도 실수형 배열 포인터 |
char[] | char* | 문자형 배열 포인터 (C 스타일 문자열) |
struct MyStruct | MyStruct* | 구조체 포인터 |
class MyClass | MyClass* | 클래스 객체 포인터 |
int** | int** | 이중 포인터 (포인터를 가리키는 포인터) |
int*& | int*& | 포인터에 대한 참조 (포인터 자체를 변경 가능) |
int* const | int* const | 상수 포인터 (포인터 주소 변경 불가) |
const int* | const int* | 상수 데이터를 가리키는 포인터 (값 변경 불가) |
const int* const | const int* const | 상수 데이터를 가리키는 상수 포인터 (값 및 주소 변경 불가) |
std::unique_ptr<int> | std::unique_ptr<int> | C++ 스마트 포인터 (유일한 소유권) |
std::shared_ptr<int> | std::shared_ptr<int> | C++ 스마트 포인터 (공유 소유권) |
std::weak_ptr<int> | std::weak_ptr<int> | C++ 스마트 포인터 (약한 참조) |
포인터 예제 코드
✅ 코드 설명
- int, double, char 타입의 변수를 선언합니다.
- 각 변수의 주소를 포인터에 저장하여 출력합니다.
#include <iostream>
int main() {
int a = 10;
double b = 3.14;
char c = 'X';
int* ptrA = &a;
double* ptrB = &b;
char* ptrC = &c;
std::cout << "변수 a의 값: " << a << ", 주소: " << ptrA << std::endl;
std::cout << "변수 b의 값: " << b << ", 주소: " << ptrB << std::endl;
std::cout << "변수 c의 값: " << c << ", 주소: " << static_cast<void*>(ptrC) << std::endl;
return 0;
}
🔹 실행 결과 (예시)
※ 주소 값은 실행할 때마다 달라질 수 있음
변수 a의 값: 10, 주소: 0x7ffee9b2a9fc
변수 b의 값: 3.14, 주소: 0x7ffee9b2a9f8
변수 c의 값: X, 주소: 0x7ffee9b2a9f7
✅ 주요 개념 정리
- &변수 → 변수의 주소를 가져옴
- int*, double*, char* → 해당 타입의 포인터 선언
- static_cast<void*>(ptrC) → char*는 std::cout에서 문자열로 해석될 수 있어 void*로 변환 후 출력
🔹 배열과 포인터
📌 포인터 변수란?
C++에서 포인터(pointer) 변수는 메모리 주소를 저장하는 변수입니다. 일반 변수는 값 자체를 저장하지만, 포인터는 그 값을 어디에 저장했는지(주소) 를 저장합니다.
// 일반 변수
int normalInt = 5;
// 포인터 변수
int* pInt = nullptr; // 아무것도 가리키지 않는 포인터
// short형 포인터
short* pShort = nullptr;
👉 nullptr은 해당 포인터가 현재 아무 메모리도 가리키지 않음을 의미합니다.
🔍 포인터 변수의 크기
자료형에 상관없이, 포인터 변수의 크기는 동일합니다. 이는 포인터가 실제로 저장하는 값이 주소(메모리 위치) 이기 때문이며, 주소는 운영체제와 아키텍처(32비트/64비트)에 따라 크기가 결정됩니다.
💻 플랫폼 | 포인터 크기 (byte) | 포인터 크기 (bit) |
32비트 Windows (x86) | 4 | 32 |
64비트 Windows (x64) | 8 | 64 |
32비트 Linux (x86) | 4 | 32 |
64비트 Linux (x86_64) | 8 | 64 |
64비트 macOS (ARM64 등) | 8 | 64 |
32비트 임베디드 (ARMv7 등) | 4 | 32 |
64비트 임베디드 (ARMv8 등) | 8 | 64 |
🧠 참고
- 32비트 시스템: 주소공간 2³² → 약 4GB → 포인터 크기 4byte
- 64비트 시스템: 주소공간 2⁶⁴ → 약 18EB → 포인터 크기 8byte
int iSize = sizeof(int*); // int형 포인터 크기 확인
int sSize = sizeof(pShort); // short형 포인터 크기 확인
📌 둘 다 8 출력됨 (64비트 기준)
✅ sizeof와 strlen의 차이점
명령어 | 설명 | 예시 |
sizeof | 메모리에서 차지하는 크기(byte) 반환 | sizeof(int) → 4 |
strlen | C 문자열의 문자 수(null 제외) | strlen("Hello") → 5 |
sizeof(array) | 배열 전체 메모리 크기 반환 | sizeof(arr) → 20 (int[5]) |
string::length() | 문자열의 길이 반환 | s.length() → 3 |
string::size() | length()과 동일 | s.size() → 3 |
⚠️ 주의
- sizeof(char*)는 포인터 크기
- strlen(char*)은 문자열 길이
- sizeof(arr)/sizeof(arr[0]) → 배열 요소 개수 구할 때 사용
🧪 예시 코드로 확인해보기
#include <iostream>
#include <cstring>
#include <string>
int main() {
int a = 10;
int* p = &a;
char str[] = "Hello";
std::string cppStr = "World";
std::cout << "sizeof(int): " << sizeof(int) << "\n"; // 4
std::cout << "sizeof(p): " << sizeof(p) << "\n"; // 8
std::cout << "strlen(str): " << strlen(str) << "\n"; // 5
std::cout << "sizeof(str): " << sizeof(str) << "\n"; // 6
std::cout << "cppStr.length(): " << cppStr.length() << "\n"; // 5
return 0;
}
🔗 포인터와 주소값
int i = 0;
int* pInt = &i;
- &i는 변수 i의 주소값
- *pInt는 그 주소에 저장된 값
📌 포인터 변수에 +1을 하면?
pInt += 1;
- 주소가 단순히 +1 되는 것이 아니라,
- sizeof(int) 만큼 더해져 다음 int 위치를 가리키게 됩니다.
즉, pInt는 int*이기 때문에 포인터 연산이 해당 자료형 단위로 작동합니다.
📦 포인터와 배열
배열을 이해할 때, 포인터 개념은 필수입니다.
배열의 특징
- 메모리상에 연속된 공간
- 배열 이름 자체가 시작 주소
int iArr[10] = {}; // 모든 값 0 초기화
*iArr = 5; // iArr[0] = 5
*(iArr + 1) = 10; // iArr[1] = 10
iArr[2] = 3; // 배열 인덱스 사용한 일반적 접근
💡 즉, iArr + n → 배열 시작 주소에서 n칸 떨어진 위치
📌 요약 정리
개념 | 설명 |
포인터 | 메모리 주소 저장 |
* 연산자 | 해당 주소의 값 참조 |
& 연산자 | 변수의 주소 반환 |
포인터 연산 | 자료형 크기 단위로 이동 |
배열 이름 | 배열의 시작 주소 |
sizeof | 메모리 크기 확인 |
strlen | 문자열 길이 확인 |
'C++ > 유튜브 어소트락 게임아카데미 C++무료강의' 카테고리의 다른 글
10. 포인터와 const (0) | 2025.04.19 |
---|---|
9. 포인터 변수 문제 풀이 (0) | 2025.04.15 |
7. 지역변수, 전역변수 (0) | 2025.04.02 |
6. 구조체(Structure) (0) | 2025.03.30 |
5. 배열 (0) | 2025.03.26 |