Pointer #4

Kimbab1004·2024년 7월 5일
0

CPP

목록 보기
12/27
post-thumbnail

Void Pointer

void 포인터는 C와 C++ 프로그래밍 언어에서 사용되는 특별한 종류의 포인터로, 어떤 데이터 타입도 가리킬 수 있는 포인터입니다. "void"는 본래 "빈" 또는 "비어 있음"을 의미하며, void 포인터는 특정한 데이터 타입을 가리키지 않기 때문에 다양한 용도로 활용될 수 있습니다.

void* pVoid = nullptr;

int a = 0;
char c = 0;
short ss = 0;

pVoid = &a;
pVoid = &c;
pVoid = &ss;


// 메모리 복사 함수
void CopyData(void* _Dest, void* _Src, unsigned int _Size)
{
	unsigned char* pDest = (unsigned char*)_Dest;
	unsigned char* pSrc = (unsigned char*)_Src;	

	for (int i = 0; i < _Size; ++i)
	{
		//*(pDest + i) = *(pSrc + i);
		pDest[i] = pSrc[i];
	}
}

void 포인터 변수에 들어있는 주소값을 다른 일반 포인터에 옮길 수 없다.

현재 Short Type 변수를 void pVoid Pointer에 선언하엿지만 이를 int Type pIntPtr에 선언하면 Short Type 변수의 주소를 Int Type에 선언하는 것이기 대문에 옮길 수 없다.

int* pIntPtr = pVoid;

Struct Pointer

// 포인터와 구조체
MyDataType data = {};
MyDataType* pData = &data;

(*pData).i = 10;
(*pData).f = 1.1f;

pData->i = 10;
pData->f = 1.1f;

data.i = 10;
data.f = 1.1f;

일반적인 구조체에는 Instance.Member Variable 로 접근한다. 하지만 Struct Pointer는 (*pData).i = 10; 와 같은 형식으로 접근하는데 이를 ->로 축약해서 사용 할 수 있다.
이것과 관련된 내용은 저번 Pointer 공부글에서 다양한 예시를 확인 할 수 있다.

//정상
data.i = 10;
//비정상
~~pData.f = 1.1f;~~

Struct Pointer로 일반적인 Struct 접근 방식을 사용하면 오류가 발생한다.

Pointer 문제

Test의 답은 무엇일까?
Pointer에 대해 이해하고 있다면 맞출 수 있는 문제이다. (처음에는 틀렸다.)

short Test()
{
	short arrShort[20] = {};

	for (int i = 0; i < 20; ++i)
	{
		arrShort[i] = i + 1;
	}

	int* pInt = (int*)arrShort;
	pInt += 4;

	//short* pShort = (short*)pInt;
	//return  *pShort;
	return *((short*)pInt);
}

처음에는 해당 문제의 답이 "Compile Error"라고 생각했다. 그 이유는 처음에 short 선언 한 것을 (int*)로 형변환을 했으니 오류가 나지 않았을까? 2비트 -> 4비트 변경이니 이건 return 되지 않고 중간에 오류로 끝나겠다. 라고 생각한 것이 이유였다. 하지만 이건 완전히 잘못된 접근이였다.

첫 번째로 Test문제에서 short Type로 선언된 것은 배열이다. 하지만 한가지 생각해야 할 것은 배열(Array)는 Pointer와 밀접한 관련이 있다는 것이다. 배열은 메모리 주소 체계를 이용하여 데이터를 저장하고 관리한다. 흔히 배열에 접근하는 방식은 메모리 접근과 동일하다.

#include <iostream>

int main() {
    int Array[10] = {0};  // 배열의 모든 요소를 0으로 초기화

    int *p = Array;       // p는 Array의 첫 번째 요소를 가리킵니다

    // 포인터 연산을 사용하여 배열의 5번째 요소(인덱스 4)에 접근하고 값을 더하기
    *(p + 4) += 10;       // Array[4]에 10을 더합니다
    std::cout << "Array[4] after adding 10: " << Array[4] << std::endl;

    // 포인터 연산을 사용하여 배열의 5번째 요소를 특정 값으로 설정하기
    *(p + 4) = 5;         // Array[4]에 5를 대입합니다
    std::cout << "Array[4] after setting to 5: " << Array[4] << std::endl;

    return 0;
}

Test 순서

Short Type의 배열을 선언하고 각 주소에 접근해 i+1의 값을 넣었다. 그렇다면 아래 숫자가 담긴 한칸 한칸은 Short Type의 크기인 2비트이다.

  1. 다음은 Short 타입으로 선언된 배열을 int 타입으로 형변환 해주었는데 이는 오류가 나나?

  2. 주소 크기를 다르게 보는것인데 왜 오류?

  3. Short타입에서 int 타입으로 바꿨으니까 오류가 나지

  4. 그건 short 타입 변수 short i = 2 인 것을 변환할때 오류가 나는 거지 이건 주소 접근 체계이다.

여기서 pInt +=4라는 의미에 대해 해석해보자.
pInt는 포인터로 arrShort라는 배열의 0번째 인덱스를 가르킨다. pInt+=4 라는 의미는
pInt에서 4비트를 증가한 2에 접근하라는 의미가 아니다. <- 처음에 이렇게 생각했다.

포인터 +=4는 배열의 4번째 index에 접근하라는 의미이다. 이건 현재 int Type 배열인 arrShort의 4번째 index인 9에 접근하라는 의미로 해석될 수 있는 것이다.

이것을 마지막에 Short형태로 형변환을 하더라도 이미 접근은 끝마쳤기 때문에 답이 9인것은 변함이 없다.

Const Pointer

자료 출처

상수를 가리키는 포인터 (Pointer to const value)

상수를 가리키는 포인터는 상수 변수의 주소를 가리키는 (non-const) 포인터다.

const int value = 5;
const int* ptr = &value; // this is okay, ptr is a non-const pointer that is pointing to a "const int"
*ptr = 6; // not allowed, we can't change a const value

int value = 5;
const int* ptr1 = &value; // ptr1 points to a "const int", so this is a pointer to a const value.
int* const ptr2 = &value; // ptr2 points to an "int", so this is a const pointer to a non-const value.
const int* const ptr3 = &value; // ptr3 points to a "const int", so this is a const pointer to a const value.

0개의 댓글