본문 바로가기
C++/유튜브 어소트락 게임아카데미 C++무료강의

8. 포인터

by GREEN나무 2025. 4. 15.
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++ 스마트 포인터 (약한 참조)

 

포인터 예제 코드

✅ 코드 설명

  1. int, double, char 타입의 변수를 선언합니다.
  2. 각 변수의 주소를 포인터에 저장하여 출력합니다.
#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

✅ 주요 개념 정리

  1. &변수 → 변수의 주소를 가져옴
  2. int*, double*, char* → 해당 타입의 포인터 선언
  3. 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*이기 때문에 포인터 연산이 해당 자료형 단위로 작동합니다.


📦 포인터와 배열

배열을 이해할 때, 포인터 개념은 필수입니다.

배열의 특징

  1. 메모리상에 연속된 공간
  2. 배열 이름 자체가 시작 주소
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