본문 바로가기

C, C++

포인터

포인터는 변수의 주솟값을 저장하는 변수입니다.

여기서 주솟값은 컴퓨터 메모리 속에 변숫값이 있는 위치를 뜻합니다.

변수의 주솟값을 참조하려면 변수 앞에 &를 붙입니다.

그리고 포인터 변수를 선언하려면 변수 타입 뒤에 *를 붙입니다.

int i;
int* a = &i;//i의 주소를 대입
int j;
a = &j;

 

변수를 선언할 때 컴퓨터 메모리에 값이 저장되는데 이때 저장 위치는 운영체제가 알아서 정하기 때문에 a의 값은 그때그때 다릅니다.

 

1. 포인터 앞에 *을 붙이면 포인터가 참조하는 변숫값을 가져올 수 있습니다.

i = *a;//i=j와 같은 결과

 

 

2. 포인터는 주솟값, 즉, 숫자이므로 다음과 같이 연산이 가능합니다.

a = a + 1;//a의 다음 주소값을 대입

 

 

그런데 a의 타입은 int 포인터이므로 a의 다음 주솟값은 (a + int 크기) 주소 즉, 4바이트를 더한 값이 됩니다. 만약 a의 1바이트 뒤의 주솟값을 참조하고 싶으면 a을 char 포인터로 변환하여 1을 더하고 다시 int 포인터로 변환하여 대입합니다.

a = (int*)((char*)a + 1);

 

사실 일반 int 변수를 참조하는 포인터에 이렇게 1을 더하는 코드를 짜면 a의 값이 프로그램에 할당된 메모리를 벗어나기 때문에 사용하지 않는 것이 좋습니다.

 

3. 배열은 일종의 (요솟값이 아닌 자체) 값이 변경 불가능한 포인터라 생각할 수 있습니다. 다음처럼 포인터에 배열을 대입할 경우 &연산자를 쓰지 않습니다.

int ar[3] = {1, 2, 3};
a = ar;
ar = a;//불가능

int b = *a;//1
b = *(a + 1);//2
b = *(ar + 1);//2

 

4. 포인터는 위에서 숫자라고 했습니다. 그렇다면 포인터를 참조하는 포인터도 만들 수 있습니다. 이를 이중 포인터라고 합니다.

int** aa = &a;//int*의 포인터
b = **aa;//aa가 참조하는 값이 참조하는 값
a = *aa;

 

 

5. 포인터가 쓰이는 대표적인 부분은 바로 함수에 인수를 전달할 때입니다.

void Change(int _a) {
	_a = 2; 
} 

int a = 0; 
Change(a);//a의 값을 _a에 복사합니다. 
//a가 2로 바뀌지 않습니다.

 

 

여기서 a가 2가 되도록 하려면 a의 포인터를 인수로 전달해야 합니다.

void Change2(int* _a) {
	*_a = 2;
} 

int a = 0;
Change2(&a);//a의 주소 값을 _a에 복사합니다.
//a가 2로 바뀝니다.

 

 

6. 아주 큰 값을 전달할 때 그냥 값으로 전달하면 값을 통째로 복사해 실행 속도가 느리므로 포인터를 전달하면 속도가 빠릅니다.

struct ABC {
	int a;
    int b;
    //… 
};

void Change3(ABC _a) {
	_a.a = 2; 
} 

ABC abc;
Change3(abc);//값을 통째로 복사해서 속도가 느리고 abc.a의 값이 2로 바뀌지 않습니다.

void Change4(ABC* _a) {
	_a->a = 2;//또는 (*_a).a=2;와 같습니다. 
}

Change4(&abc);//값의 주소를 복사해서 속도가 빠르고 abc.a의 값이 2로 바뀝니다.

 

7. void*라는 특수 포인터 타입이 있는데 이는 어느 타입에도 귀속되지 않은 포인터입니다.

int i;
float j;
void* a;

a = &i;
a = &j;//어느 타입의 변수 주소도 대입이 가능합니다.

a = a + 1;//불가능. void 포인터는 연산이 안됩니다. 참조하는 대상의 크기를 모르기 때문입니다. 
a = (void*)((float*)a + 1);//float 포인터로 바꾸어 연산을 한 후 다시 void포인터로 바꾸어 대입합니다.

float* b = a;//불가능. float*로 변환해야 합니다. 
j = *a;//불가능. void 포인터는 참조하는 대상의 타입을 모르므로 *의 연산자를 사용할 수 없습니다.
j = *(float*)a;

'C, C++' 카테고리의 다른 글

변수, 함수 선언과 정의  (0) 2019.12.03
변수 종류  (0) 2019.12.03
공용체  (0) 2019.12.02
구조체 정렬 및 원리  (0) 2019.11.29
비트 구조체  (0) 2019.11.28