포인터(Pointer)란?
메모리 주소를 값으로 가지는 변수
포인터 변수의 선언
타입명 * 변수명;
* : 뒤에 오는 변수가 포인터임을 알려주는 기호
ex. int * ptr;
▷ ptr은 포인터 변수이기 때문에 메모리 주소를 저장한다. 그 메모리 주소에 저장되는 타입이 int 타입이다.
연산자 &
변수로부터 그 변수의 주소를 추출하는 연산자
ex)
int c = 5; //정수형 변수 c는 12의 값을 가진다
int *ptr; //ptr은 정수형 포인터 변수이다
ptr = &c; //ptr에는 c의 주소값이 저장된다
Q. 주소는 왜 4씩 차이 날까?
A. 변수를 int형으로 설정했기 때문에 하나의 변수 당 4 byte씩 공간을 차지하게 되기 때문이다.
포인터 변수 치환
int x = 1, y = 2;
int * p;
p = &x;
y = *p;
▷ *가 변수를 선언 할 때는 포인터 변수라는 것을 알려주기 위한 기호
▷ 선언 이외에 사용될 때는 뒤에 오는 포인터 변수가 저장하고 있는 주소의 저장된 값 또는 그 주소가 참조하는 자리를 의미한다
위 상황에서는 선언이 끝난 후 치환이 이루어지는 상황으로 후자의 경우에 속한다. 따라서 y는 포인터 변수 p가 저장하고 있는 주소인 x의 값을 가지게 된다.
*p = 0;
▷ 포인터 변수가 가리키는 자리의 값에 0을 쓰라는 의미이다
따라서, 메모리 1000번지에 0을 쓰라는 의미로 x = 0이 된다.
배열
배열의 이름 = 배열의 시작 주소(첫 번째 주소)를 저장하는 포인터 변수 (단, 그 값을 변경할 수 없다)
*a와 a[0]은 동일한 의미
▷ a[1]은 *(a+1)과 동일하고, a[i]는 *(a+i)와 동일하다
포인터 arithmetic: 포인터 변수에 더하기 연산을 하는 것
▷ 하나의 정수가 4byte로 표현되는 경우, +1을 한다는 것의 의미는 4를 더해준다는 의미가 된다.
즉, 그 다음 정수의 주소가 되도록 (1000 → 1004) 한다.
ex. *(a+1)
+plus)
char 1byte
int 4byte
long long 8byte
동적 메모리 할당 (Dynamic Memory Allocation)
일반적으로 데이터를 저장하기 위한 메모리 공간이 필요하면 변수를 선언해서 그 변수에 데이터를 저장하는 것이 가장 일반적인 방식이다.
malloc 함수를 호출하여 동적 메모리 할당을 요청 → 요구한 크기의 메모리를 할당 → 해당 메모리의 시작 주소 반환
int * p;
//malloc으로 주소를 받아올 건데 그것을 사용하려면 주소를 보관해둘 곳이 필요하므로 변수에 대입.주소이므로 포인터 사용
p = (int *)malloc(40);
//int의 사이즈가 4라고 가정하고 계산하여 malloc하는 것보다는 10*sizeof(int)가 더 바람직
//malloc이 반환하는 주소는 타입이 없는 주소(void *) 정수들을 저장하기 위해 int *로 변환함 (필수X)
if (p==NULL) {
/* 동적 메모리 할당이 실패 */
/* 적절한 조치를 취한다. */
}
//malloc으로 할당받은 메모리는 배열처럼 사용 가능하다
p[0] = 12;
p[1] = 24;
*(p+2) = 36; //*(p+2)==p[2]
...
언제 배열 대신 동적할당을 사용할까?
배열은 크기가 고정되어 있으므로 공간 부족에 대한 문제 해결이 어렵다.
동적으로 할당된 배열은 공간이 부족할 경우 더 큰 배열을 할당하여 사용 가능하다.
int * array = (int *)malloc(4*sizeof(int));
array[0] = 1;
array[1] = 2;
*(array+2) = 3;
int * tmp = (int *)malloc(8*sizeof(int));
int i;
for (i=0; i<4; i++)
tmp[i] = array[i]; //원래 배열에 있던 모든 데이터를 새로 할당 받은 배열에 복사
array = tmp;
//array, tmp 모두 포인터 변수. tmp가 가지고 있는 값(32byte 메모리 공간의 주소)을 array에 저장
//기존 array가 가지고 있던 주소에 위치한 배열은 garbage가 됨
위 코드에서 int * array = (int *)malloc(4*sizeof(int)); 를 int array[4];로 바꿔도 되지 않을까?
▷ 배열은 시작 주소를 변경할 수 없다
따라서, int array[4];를 사용할 경우, array = tmp; 에서 오류가 나는 것을 확인할 수 있다.
*참고 강의. 'C로 배우는 자료구조 및 여러가지 예제 실습' - 권오흠
* 잘못된 내용에 대해서는 댓글 남겨주시면 확인 후 수정하겠습니다
'Language > C' 카테고리의 다른 글
[C언어] 자료구조를 위한 기초 문법 리뷰 - 문자열 (0) | 2021.02.17 |
---|