포인터(pointer)는 실행 중 메모리의 주소 값이다.
포인터를 이용하여 메모리에 직접 값을 쓰거나 해당 메모리의 값을 읽어올 수 있다.
각 변수마다 메모리 공간이 할당된다.
이 메모리 공간은 프로그램을 실행할 때 정해진다.
(실행 전에는 알 수 없음)
정수형 (int) : 4byte
실수형 (float) : 4byte
문자형 (char) : 1byte
printf("정수형 : %d\n", sizeof(int));
printf("실수형 : %d\n", sizeof(float));
printf("문자형 : %d\n", sizeof(char));
정수형 변수 n을 선언하게 되면 이때 n은 정수를 저장할 메모리 공간의 이름이다.
메모리 주소를 몰라도 n이라는 이름으로 변수를 사용할 수 있다.
(변수 이름을 통해 편하게 변수를 사용할 수 있는데 포인터를 사용하는 이유는 뒤에서 다룰 예정)
포인터 변수란 포인터 (주소)를 저장하는 변수이다.
변수의 메모리 주소를 알아내어 포인터 변수에 저장할 수 있다.
int n = 5;
int *p; // 정수를 저장하는 메모리에 대한 포인터 변수 선언
p = &n; // p에 n의 주소를 저장
& 연산자(ampersand)는 변수의 주소 값을 가져온다.
printf("n의 주소 : %p \n", &n);
printf("p에 들어있는 값 : %p \n", p);
// %p: 주소 출력 서식
printf("*p의 값 : %d \n", *p);
// p에는 n의 주소가 들어있기 때문에 n의 값이 출력됨
// 주소를 가리키기 때문에 n의 값이 변경되면 변경된 값이 출력됨
int n;
char c;
double d;
int *p = &n; // 정수형 포인터
char *q = &c; // 문자형 포인터
double *r = &d; // 실수형 포인터
*p = 25; // n에 25 저장
*q = 'A'; // c에 'A' 저장
*r = 3.14; // d에 3.14 저장
*p는 'p가 가리키는 곳' 또는 '값'을 뜻한다.
int m = *p + 10;
// m = 25 + 10
int a = 1;
int b = 2;
int *pa = &a;
int *pb = &b;
int s = *pa + *pb;
// s = 1 + 2;
주소를 이용하는 연산은 다음 포스트에서 다룸
두 개의 정수형 변수 값을 서로 바꾸는 함수
void swap(int a, int b) { // a와 b의 값을 서로 바꾸는 함수
int temp; // a의 값을 잠시 담아둘 변수
temp = a;
a = b;
b = temp;
}
이 과정이 끝나면 함수 안에서 a와 b의 값은 바뀌지만 main( )의 x와 y의 값은 바뀌지 않는다.
-> 이때 포인터를 이용하여 이 문제를 해결할 수 있다.
void p_swap(int *a, int *b) {
// a가 가리키는 주소의 값과 b가 가리키는 주소의 값을 바꿔주는 함수
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 1;
int y = 2;
p_switch(&x, &y); // & 연산자를 이용하여 주소를 넘겨줌
}