주소는 변수가 할당된 메모리 공간의 시작 주소를 의미한다. 시작 주소를 알면 그 위치부터 변수의 크기만큼 메모리를 사용할 수 있다. 주소는 주소 연산자 &
를 사용해서 구한다.
포인터는 변수의 메모리 주소를 저장하는 변수다. 선언할 때는 변수 앞에 간접 참조 연산자(=포인트 연산자) *
를 붙인다.
포인터를 선언할 때 주소 위치에 있는 변수의 자료형으로 선언해야 한다.
#include <stdio.h>
int main(void)
{
int a; // 일반 변수 선언
int *pa; // 포인터 선언
pa = &a; // 포인터에 a의 주소 대입
*pa = 10; // 포인터로 변수 a에 10 대입
printf("포인터로 a 값 출력: %d\n", *pa); // 포인터로 a 값 출력: 10
printf("변수명으로 a 값 출력: %d\n", a); // 변수명으로 a 값 출력: 10
return 0;
}
포인터 pa
는 변수 a
가 메모리 어디에 할당되었는지 그 주소를 저장하는데, 이때 pa가 a를 가리킨다
고 표현한다.
pa → a // 포인터 pa는 변수 a를 가리킨다!
따라서 특정 변수의 주소 값은 바뀌지 않지만, 포인터는 다른 주소를 대입해 그 값을 바꿀 수 있다. 즉 주소는 상수고 포인트는 변수다.
포인터의 크기는 주소의 크기와 같다.
모든 주소와 포인터는 가리키는 자료형과 상관없이 그 크기가 같다.
sizeof
연산자를 이용해서 주소와 포인터의 크기를 확인할 수 있다.
#include <stdio.h>
int main(void)
{
char ch;
int in;
double db;
char *pc = &ch;
int *pi = ∈
double *pd = &db;
printf("char형 변수의 주소 크기: %lu\n", sizeof(&ch)); // 8
printf("int형 변수의 주소 크기: %lu\n", sizeof(&in)); // 8
printf("double형 변수의 주소 크기: %lu\n", sizeof(&db)); // 8
printf("char형 *포인터의 크기: %lu\n", sizeof(pc)); // 8
printf("int형 *포인터의 크기: %lu\n", sizeof(pi)); // 8
printf("double형 *포인터의 크기: %lu\n", sizeof(pd)); // 8
printf("char형 *포인터가 가리키는 변수의 크기: %lu\n", sizeof(*pc)); // 1
printf("int형 *포인터가 가리키는 변수의 크기: %lu\n", sizeof(*pi)); // 4
printf("double형 *포인터가 가리키는 변수의 크기: %lu\n", sizeof(*pd)); // 8
return 0;
}
포인터를 사용하면 함수 간에 효과적으로 데이터를 공유할 수 있다.
다음 경우에는 포인터가 반드시 필요하다.
키보드로 실수 3개를 입력한 후 큰 숫자부터 작은 숫자로 정렬한 뒤 출력하는 프로그램을 작성합니다. 다음 코드와 출력 결과를 참고해 line_up
함수를 작성하세요. line_up
함수에는 이미 정의된 swap
함수를 호출해 구현하세요.
실수값 3개 입력: 2.7 1.5 3.4
정렬된 값 출력: 3.4, 2.7, 1.5
#include <stdio.h>
void swap(double *pa, double *pb);
void line_up(double *maxp, double *midp, double *minp);
int main(void)
{
double max, mid, min;
printf("실수값 3개 입력: ");
scanf("%lf%lf%lf", &max, &mid, &min);
line_up(&max, &mid, &min);
printf("정렬된 값 출력: %.1lf, %.1lf, %.1lf\n", max, mid, min);
return 0;
}
void swap(double *pa, double *pb)
{
double temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
void line_up(double *maxp, double *midp, double *minp)
{
// 구현한 부분 - 다 한 번씩 비교하기!
if (*maxp < *midp) swap(maxp, midp);
if (*midp < *minp) swap(midp, minp);
if (*maxp < *midp) swap(maxp, midp);
}