포인터의 개념
- 지금까지의 변수는 그 자체로 자신의 자료형에 맞는 값을 저장함
- 포인터(Pointer) 변수는 특이한 변수로, 메모리 주소를 저장함
- 포인터는 *표시를 이용해 나타낼 수 있음
- 포인터는 특정한 변수 자체가 존재하는 메모리 주소의 값을 가짐
- 따라서 다음 예제에서는 기존에 a를 이용해서도 5라는 값을 찾을 수 있지만 포인터 변수인 b를 이용해서도 5라는 값을 찾을 수 있음
- int *b = &a;처럼 '선언할 때' 쓰는 *는 포인터 변수임을 알려주기 위한 목적을 가짐
- 이후에 *b라고 쓰게 되면, 이것은 포인터 변수 b가 가리키는 주소의 값을 의미
- 다시 말해서 아래 예제에서 5라는 값 자체가 됨
int a = 5; int *b = &a;
5 < 0xAFB03954
주소 : 0xAFB03954 0xCA29839F
포인터 관련 연산자
- 주소 연산자(&) : 변수 앞에 붙어서 변수의 메모리 시작 주소 값을 구함
- 포인터(*) : 포인터 변수를 선언할 때 사용함
- 간접 참조 연산자(*) : 선언된 포인터 변수가 가리키는 변수를 구함
* 선언할 때와 선언 이후의 포인터 연산자(*)는 생긴 것만 같지 기능은 다름
#include<stdio.h>
#include<cstdlib>
int main(void) {
int a = 5;
int* b = &a; // 포인터 변수 b가 변수 a를 가리킴
printf("%d\n", *b);
system("pause");
return 0;
}
- 실제로 int a = 5; 와 같이 변수를 할당하면 메모리 주소상에서는 다음과 같이 기록됨
- int형은 4바이트를 차지하므로 메모리 주소를 1바이트씩 표현할 때 4칸을 차지함
* 배열 각 원소의 주소 값 출력
#include<stdio.h>
#include<cstdlib>
int main(void) {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", &a[i]);
}
system("pause");
return 0;
}
포인터의 강력한 기능
1.
- 포인터는 컴퓨터 시스템의 특정한 메모리에 바로 접근할 수 있음
- 따라서 기존에 존재하던 중요한 메모리 영역에 접근하지 않도록 해야 함
- 다음과 같은 코드는 굉장히 위험한 코드임
int *a = 0x33484735;
*a = 0;
* 포인터는 다중으로 사용할 수 있음
#include<stdio.h>
#include<cstdlib>
int main(void) {
int a = 5;
int *b = &a;
int **c = &b;
printf("%d\n", **c);
system("pause");
return 0;
}
2.
- 배열과 포인터는 사실 내부적으로 거의 동일함
- 배열을 선언한 이후에는 그 이름 자체를 포인터 변수처럼 쓸 수 있음
#include<stdio.h>
#include<cstdlib>
int main(void) {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *b = a;
printf("%d\n", b[2]);
system("pause");
return 0;
}
- 포인터는 특정한 변수가 메모리 상에 존재하는 위치 주소를 저장함
- 포인터는 특정한 메모리 주소에 바로 접근할 수 있으므로 조심스럽게 사용해야 함