포인터

Yama·2023년 12월 8일
0

어소트락 수업

목록 보기
11/55

포인터

  • 주소를 저장하기 위한 변수
int* p = nullptr;

nullptr

  • nullptr은 0이랑 똑같다.
  • 아무것도 가르키고 있지 않다는 뜻
int i = NULL
  • i라는 변수에 0을 넣겠다.
int i = nullptr; // 오류 발생

  • nullptr은 포인터 변수밖에 초기화를 못해준다.
  • NUll을 쓰지않고 nullptr을 포인터 변수에서 사용하는 이유?
    • nullptr 키워드는 0을 의미하지만 포인터 타입 변수에만 대입이 가능하기 때문이다.
  • nullptr을 사용하는 이유?
    • nullptr을 써주면 명확하게 포인터 변수라고 보여 줄 수 있어서.

포인터의 주소값 의미.

  • SSD,HDD는 데이터들을 영구적으로 들어가있는 대기소(프로그램,원도우운영체제,다운받은게임등등을 저장)
  • 주소란 메모리에서 OS(운영체제)가 개념적으로 주소를 구현해둔것
  • 그래서 포인터 주소는 물리적인 주소가 아니라 OS가 종합적으로 관리해주기 떄문에 가상주소를 기반으로 코딩하면 된다.

포인터 예시

	int test = 0;
	int* p = nullptr;


	p = &test;
	*p = 100; 

	int tset1 = *p;
p = &test;
  • tset의 주소값을 포인터 변수 p 에 알려준것.
*p = 100; 
  • 본인안에 들어있는 데이터로 참조(접근), test변수에 100을 넣겠다는 의미.
int tset1 = *p;
  • test1에 100을 역참조해서 대입하겠다는 의미.

포인터의 특징

  • 포인터 변수의 크기, 타겟 플랫폼에 따라 다르다.
  • 포인터 변수의 크기
    • x64(64비트) 8바이트
    • x86(32비트) 4바이트
  • 따라서 우리가 쓰는 운영체제인 64비트 운영체제에서는 8바이트가 기본이다.

포인터의 자료형

		int* pInt = nullptr;
		char c = 0;
		pInt = &c; // 오류

  • void포인터를 제외하고는 같은 자료형의 주소를 넣어줘야한다.
        void* pVoid = nullptr;
		
        int i = 0;
		short s = 0;

		pVoid = &i;
		pVoid = &s;
  • void 포인터에는 어떤 자료형이던 넣어줄수 있다.
        char* pChar = nullptr; 
  • char타입의 자료형의 주소만 저장하겠다.
	long long* pLL = nullptr;
  • long long타입의 자료형의 주소만 저장하겠다.

포인터 선언시 자료형의 의미

			char		c = 0;
        
			char* pChar = &c; // char타입의 주소만 받겠다고 선언해둔것. 
  • char타입의 주소만 받겠다고 선언해둔것.
			int			i = 0;

			int* pInt = &i;
  • int타입의 주소만 받겠다고 선언해둔것.
			long long	ll = 0;
            
			long long* pLL = ≪
  • longlong타입의 주소만 받겠다고 선언.
			int			i = 0;
           
			char* 	pChar = &i; 

  • 오류 발생 이유
    • int 타입의 주소를 갈려했는데 char형식으로 볼려하니까 1바이트를 봐서 오류가 발생한다.
    • 그래서 char는 int의 4바이트의 주소값을 가져올수 없기 때문에 오류이다.
            char		c = 0;
            int*	pInt = &c;

  • 오류 발생 이유
    • char 타입의 주소를 갈려했는데 int형식으로 볼려하니까 4바이트를 봐야되서 오류가 발생한다.
    • 그래서 int는 char의 1바이트의 주소값을 정확하게 가져올수 없기 때문에 오류가 발생한다.
			void* pVoid = nullptr;
			pVoid = &c;
			pVoid = &i;
			pVoid = ≪
  • void포인터는 모든 자료형을 받을수 있지만 단점이 존재한다.

역참조

  • 포인터 변수가 저장하고있는 주소값 만으로는 해당 주소의 실제 정체(타입)을 정확하게 알 수가 없다.
  • 따라서 포인터를 선언할 때 포인터가 가리킬 자료형을 미리 정해놓고 선언한다.
		char* pChar = nullptr; 
        int* pInt = nullptr;
		long long* pLL = nullptr;

			*pChar;
			*pInt;
			*pLL;
			char ca = 255;

			char* pC = &ca; 
			unsigned char* pUC = (unsigned char*)&ca; 
            			
            int data = *pC; 
			data = *pUC; 

  • 주소값은 같다.
  • *pC 값은
  • *pUC 값은
			float	fTest = 4.f;
            
			int* pData = &fTest;	

  • int포인터로 접근할떄는 int로 볼것이다 근데 크기는 4바이트로 크기는 같지만 float 4.f는 정수형 4랑 비트상태가 다르다. 그래서 저 flaot 4.f는 오류가 발생한다.
			float	fTest = 4.f;
											
			int* pData = (int*)&fTest;
            
            data = *pData;
  • 강제 캐스팅해서 10억대의 이상한 값이 나온다.
  • float의 4.f 비트 상태를 int로 강제로 캐스팅해서 int(정수형)로 해석하였기때문이다.
			float	fTest = 4.f;
            
			float* pFloat = &fTest;
            
			float f = *pFloat;
  • 이렇게 하면 플롯형태로 해석해서 정상적인 flaot 4.f값이 나옴.

포인터 용도

  1. 만들어진 자료형에 접근할때 사용 가능
  2. 빈공간을 내가 원하는 데이터 형으로 사용가능
  • 포인터를 빈공간에 내가 만든 자료형 단위로 내가 원하는 데이터 단위로 입력(용도)로 쓸수 있다.
  • 동적할당을 배우면 내가 빈 메모리를 어떤 목적으로 쓸 지 정해줘야한다.

void포인터

  • 주소연산(접근 및 이동)이 불가능하다
  • 어떠한 타입의 변수의 주소라도 받을 수 있다.
			void* pVoid = nullptr;

			int i = 0;

			pVoid = &i; // int i의 주소값을 쳐넣겠다.
			//*pVoid; // 오류 

  • 오류 이유
    • int면 무슨 자료형을 해석할 떄 포인터를 주소에 넣으면 int로 본다로 정해둔것이다.
    • 근데 void포인터는 주소를 아무것도 다 받을수 있었던게 주소를 들고 있을려고만 하는것이고
    • 접근은 모른다고 해버린것.

강의 코드

#include <iostream>

int main()
{
	int test = 0;
	int* p = nullptr;

	p = &test;
	*p = 100;

	int test1 = *p;

	{
		int* pInt = nullptr;
		char c = 0;
		//pInt = &c;

		void* pVoid = nullptr;

		int i = 0;
		short s = 0;

		pVoid = &i;
		pVoid = &s;
	}

	{
		char		c = 0;
		int			i = 0;
		long long	ll = 0;

		char* pChar = &c;
		int* pInt = &i;
		long long* pLL = &ll;

		void* pVoid = nullptr;
		pVoid = &c;
		pVoid = &i;
		pVoid = &ll;


		*pChar;
		*pInt;
		*pLL;

		char ca = 255;

		char* pC = &ca;
		unsigned char* pUC = (unsigned char*)&ca;

		int data = *pC;
		data = *pUC;

		float	fTest = 4.f;
		int* pData = (int*)&fTest;
		data = *pData;

		float* pFloat = &fTest;
		float f = *pFloat;
	}


	{
		void* pVoid = nullptr;

		int i = 0;

		pVoid = &i;
		// *pVoid; 
	}

	return 0;
}

1차 23.12.08
2차 23.12.11
3차 23.12.12
4차 23.12.14
5차 23.12.17
6차 23.12.25
7차 24.01.01
8차 24.01.23

0개의 댓글