[ 포인터 ] : 포인터 변수

근본 자체는 주소를 저장하는 것

주소를 저장하는 변수의 크기는 동일

- 32 bit -> 4 btye : 4 GB

  >> 이래서 32 bit를 사용하는 컴퓨터에선, 4 GB 이상의 RAM을 장착하여도 성능 개선이 없음

- 64 bit -> 8 byte : 4 GB * 4 GB 

  >> 근래 대부분의 컴퓨터의 경우, 64 bit 지원

  >> 포인터 변수의 크기는 8 byte

 

// 포인터 설명
#include <iostream>

using namespace std;

int main(){
	// 자료형* 변수명
    int* pInt = nullptr;
    	// nullptr : 0, 아무것도 가리키지 않는 상태
	
    // 포인터 변수의 메모리
    int iSize = sizeof(pInt);
    	// 포인터 변수의 크기는 8 Byte
        // iSize = 8
    
    // 포인터 변수에서 +1은 자기한테의 저장된 전체의 주소를 +1만큼 이동한 것
    int i=0;
    pInt = &i;
    pInt += 1;
    	// pInt는 Int형 포인터
        // 즉, 4 Byte 만큼의 주소를 가리킨다.
        // pInt += 1 일 경우, 4 Byte 만큼 이동한 다음의 주소를 가르킨다
        
// 포인터와 배열
    // 배열
    // 1. 열 묶음의 메모리로, 주소가 연속적
    // 2. 배열의 이름은 배열의 시작 주소, 즉 포인터
    int iArr[10] = {};
    iArr;
    	// 배열의 시작 주소, iArr[0]의 메모리 주소
    *(iArr +1);
    	// iArr의 포인터에서 +1
        // Int 메모리의 크기만큼 이동
        // 즉, 다음 주소인 iArr[1]을 가리킨다
        
    int* pInt = iArr;
    cout << pInt << endl;
    	// pInt는 iArr의 시작주소, iArr[0]을 호출
    cout << pInt[0] << endl;
    	// pInt[0]은 iArr[0]의 주소를 호출
    cout << *(pInt + 1) << endl;
    	// *(pInt+1)은 iArr의 시작 주소, iArr[0]에서 int값만큼 이전한
        // iArr[1]을 호출
    cout << pInt[1] << endl;
    	// 위와 동일,
        // 즉, 다음은 동일한 형태
        // *(pInt + 1 ) : pInt[1]

	return 0;
}

 

[ const ] : r-value ( 상수 )

주어진 값을 상수화로 시켜준다.

그리고, 이 값은 CPU에서 상수로 인식하기에,

저장된 공간에서 값이 변하더라도, 기존에 인식된 상수값들 CPU 연산 과정에서 사용

- r-value ( 상수 )

- l-value ( 변수 )

 

// const
#include <stdio.h>

int main(){
	// const
    // 값을 상수화
    const int cint = 100;
    	// 상수화
        // r-value : 상수
        // l-value : 변수
        
    cint = 300;
    	// error
        // 상수로 되었기에 변경될 수 없다.
        
	return 0;
}

 

[ const 와 포인터 ]

#include <stdio.h>

int main(){
	// 상수화
    const int cint = 100;
    	// cint의 상수화
        
// 포인터를 활용한 cint 변경
    pInt = (int*)&cint; 
    	// 상수를 int로 바꾸기 위한 명시적 형변환 후, 주소 값 가져오기
    *pInt = 300;
    printf("%d",cint);
    	// cint가 저장된 메모리는 300으로 바뀜
        // CPU 상에선, 사전에 제시된 cint의 상수값 100을 사용
        // const이기에, 직접 cint로 접근하여 데이터 사용 X
        // 사전에 제시된 cint 값을 사용
        
        // 포인터로 물리적 메모리 공간에 저장된 값을 변경하여도
        // CPU에선, const로 처음에 제시된 값만 연산 중에 사용
        
// 포인터를 활용하여 변경할수 있는 것
	int a = 0;
    int* pInt = &a;
    
    *pInt = 1;
    	// 1. 포인터가 가리키는 대상을 변경 가능
    pInt = nullptr;
    	// 2. 포인터가 가리키는 주소를 변경 가능
        
// const 포인터
	const int* pConstint = &a; 
    	// 포인터가 가리키는 대상이 const
        // 같은 형식
        // int const* pConstint = &a;
    *pConstint = 100;
    	// error
    pConstint = nullptr;
    	// 가능
        
// 포인터 const
	int* const pIntConst = &a;
    	// 포인터가 가리키는 주소를 const
    *pIntConst = 100;
    	// 가능
    pIntConst = nullptr;
    	// error
        
// 간단한 문제
	int a = 0;
    const int* pInt = &a;
    
    a = 100;
    	// 가능
        // const가 제한하는 것은 pInt에서 근본 값을 변경하지 못하게 하는것
        // 근본 값 자체가 변하지 못하게 제한을 둘 수 있는 것은 아님
        
// const & 포인터가 같이 사용 될 때
	void Output(const int* pInt)
    	// 함수에서 변수를 입력 받을 때
        // 변수의 주소를 가져오면 메모리 측면에서 이점 有
        // 하지만, 포인터의 형식으로 가져오게 되면 변수 수정될 가능성 有
        // const를 사용하여 변경이 되지 못하도록 함
        
        // 억지로 메모리값에 접근하여 바꿀 수는 있지만,
        // 작성자의 의도를 const로 보여줄 수 있음


	return 0;
}

'C++ > 기본 문법' 카테고리의 다른 글

동적할당 && 가변배열  (0) 2022.07.01
void 포인터  (0) 2022.06.30
배열 && 구조체  (0) 2022.06.30

+ Recent posts