개요
프로그램을 작성할 때 변수를 선언하면 컴파일러는 그 변수 값을 저장하기 위해 그 변수의 자료형에 따른 적당한 크기의 공간(space)을 메모리(주기억장치)에 확보한다. 메모리는 8 bit로 된 하나의 덩어리를 byte라 하고 byte 단위로 주소(번지, address)를 가지고 있다. 주기억장치는 0번지부터 byte단위로 주소가 붙여저 있다. 따라서 모든 변수는 자신이 저장되는 메모리의 주소를 가지고 있다.
변수의 주소를 알기 위해서는 변수 이름 앞에 주소 연산자 & 기호를 사용한다.
#include <stdio.h>
void(main)
{
char c = 'A';
int n = 25;
printf("c의 주소 : %u\n", &c);
printf("n의 주소 : %u\n", &n);
}
포인터 변수
포인터 변수란 메모리의 주소를 저장하는 4 bytes로 된 변수이며, 메모리의 주소를 저장하고 저장된 주소의 메모리를 가리키는 역할을 한다.
- 특성 : 메모리의 주소를 저장할 수 있는 변수
- 역할 : 포인터 변수에 저장된 주소를 찾아 해당 메모를 가리킨다.
포인터 변수 선언
자료형 *변수명
: 자료형 : 포인터 변수가 가리킬 메모리의 자료형
: 변수명 : * 기호는 선언되는 변수가 포인터 변수라는 의미
자료형 *변수명 = 초기화;
포인터 변수의 사용을 위해서는 다른 변수와 마찬가지로 포인터 변수가 참조할(가리키는) 자료형을 지정해서 선언해야 한다. 포인터 변수를 선언하면 메모리를 저장할 수 있는 4 bytes 크기의 메모리가 할당된다.
선언과 동시에 초기화 할 수 있고, null 로 초기화 할 수 있다.
예
int *ptr;
int* ptr;
포인터 변수의 자료형이 의미하는 것은 해당 포인터 변수가 가리키는 메모리의 자료형을 의미한다.
즉, 포인터 변수 선언을 int로 할 경우, 포인터 변수는 int형 데이터가 저장된 메모리를 가리킨다는 것을 의미한다.
포인터 변수 선언시, * (Asterisk, 애스터리스크) 기호는 선언되는 변수가 포인터 변수임을 나타내는 것으로, 변수이름 바로 앞에 붙이거나 자료형 바로 뒤에 붙여서 사용할 수 있다. *의 위치에 따른 차이는 없다.
주소 연산자
변수의 주소를 알려면 변수 이름앞에 &를 붙이면 된다. 이 때 &는 주소연산자(address operator) 라고 한다.
간접 연산자
포인터가 가리키는 객체의 값을 알려면 포인터 이름 앞에 *를 붙여주면 된다. 이 때 *는 간접연산자(dereference operator)라고 한다. 한편 포인터 변수를 선언할 떄의 *와는 의미가 다르다. 포인터 변수의 자료형과 포인터가 가리키는 변수의 자료형은 반드시 일치해야 한다.
#include <stdio.h>
int main()
{
int inum = 100, m;
int *iptr; //포인터 변수 선언
double fnum = 12.5, g;
double *fptr;
iptr = &inum; //포인터 변수 iptr은 inum의 주소를 참조
printf("inum의 주소 = %p\n", &inum);
printf("iptr이 가리키는 기억장소의 값 = %d\n", *iptr); //값 출력
m = *iptr; //int형 변수 m에 포인터 변수 iptr이 가리키는 곳의 값을 대입
printf("m의 값 = %d\n\n", m);
fptr = &fnum; //포인터 변수 fptr은 fnum의 주소를 참조
printf("fnum의 주소 = %p\n", &fnum);
printf("iptr이 가리키는 기억장소의 값 = %lf\n", *fptr);
g = *fptr;
printf("g의 값 = %lf\n\n", g);
}
결과
inum의 주소 = 0x7ffdf2e596ac
iptr이 가리키는 기억장소의 값 = 100
m의 값 = 100
fnum의 주소 = 0x7ffdf2e596b0
iptr이 가리키는 기억장소의 값 = 12.500000
g의 값 = 12.500000
사용 예
#include <iostream>
using namespace std;
int main()
{
int num;
int *ptr; //포인터 변수 선언
num = 10;
ptr = # //포인터 변수에 num 주소 대입
printf("num의 주소는 %u, ptr에 저장되어 있는 값은 %u\n", &num, ptr);
printf("num = %d, *ptr = %d\n", num, *ptr);
*ptr = 30; //포인터 변수 ptr이 참조하는 값을 30으로 함
printf("num = %d, *ptr = %d\n", num, *ptr); //num 변수 값과 포인터 변수 ptr이 참조하는 값이 모두 30으로 변경
}
결과
num의 주소는 180979476, ptr에 저장되어 있는 값은 180979476
num = 10, *ptr = 10
num = 30, *ptr = 30
웹 환경에서 C언어 컴파일, 실행하기