[C언어] 13. 포인터
포인터
int *p;
포인터 타입변수는 변수의 주소값을 다루는 데이터 타입입니다.
변수의 주소에 접근하여 제어해야할 때, 큰 데이터, 배열을 옮길 때 활용할 수 있습니다.
포인터도 데이터 타입이지만, 일반적인 변수와 유사하게 타입(base type)을 가지게 됩니다
렇기에 다른 타입의 포인터 변수로 초기화하면 에러가 발생합니다.
포인터 변수 선언
int *p;
포인터 변수를 선언하는 방식은 간단합니다.
원하는 데이터 타입을 입력하고, 변수명과 데이터 타입 사이에 *
연산자를 입력합니다.
int* a;
int * b;
int *c;
위치는 크게 상관이 없습니다. 본인이 원하는 스타일로 작성할 수 있습니다.
* 연산자 (Deferencing Operator)
int *p = /* 주소값 */;
printf("%d \n", *p);
*
연산자는 포인터 변수에 저장된 주소값이 나타내는 데이터를 나타내는 기능을 가지고 있습니다.
포인터 변수 앞에 *연산자를 사용하면, 주소에 저장된 데이터로 접근할 수 있습니다.
포인터 변수에도 *
연산자를 활용하면 일반 변수와 비슷하게 활용할 수 있습니다.
& 연산자 (Addressing Operator)
int a = 0;
int *p = &a;
출력 함수인 scanf
함수에서도 활용했던 연산자입니다.
&
연산자는 변수의 주소값을 나타내는 기능을 가지고 있습니다.
모든 변수에 활용할수 있고, 포인터 변수의 데이터 타입과 일치하면 포인터 변수에 &연산자를 활용하여 주소를 저장할 수 있습니다.
NULL
int *p = NULL;
NULL
은 주소가 없음을 의미합니다.
NULL 과 0의 차이
NULL
은 0 과 비슷한 개념이지만, 다릅니다.
0은 ‘0’이라는 데이터가 있지만, NULL 은 데이터 자체가 없는 경우를 뜻합니다.
배열과 포인터
전에 설명했듯, 배열은 메모리에 연속적으로 선언되는 구조입니다.
때문에, 배열은 포인터 변수와 거의 비슷한 구조를 가집니다.
arr[n];
배열을 활용하기 위해선 []
연산자를 활용합니다.
이 연산자는 해당 변수(주소)에 n 번이후에 있는 데이터를 뜻합니다.
이로 알 수 있듯, 배열은 포인터와 유사하게 활용할 수 있습니다.
*(arr + n)
위 코드는 위에서 설명한 배열과 같은 역할을 합니다.
int arr[10];
int *p = &arr[0];
p = arr;
포인터는 배열을 저장할 수 있습니다.
전에 설명했듯 c언어는 다른 언어와 다르게 배열은 다른 배열로 초기화할 수 없습니다.
만약 하고 싶다면, 반복문을 활용해서 각각 초기화를 진행해야 합니다.
하지만, 포인터를 활용하면 배열을 초기화 할 수 있습니다.
int *k;
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
k = arr;
printf("%d", k[5]);
위 코드는 포인터를 활용하여 배열에 접근하는 방식입니다.
결과값으로는 6이 나옵니다.
배열과 포인터의 차이
배열과 포인터는 구조적으로는 거의 동일한 구조를 가지고 있습니다.
하지만, 전에 설명했듯 배열은 주소를 바꿀 수 없습니다.
포인터는 주소를 자유롭게 바꿀 수 있죠.
또, 이후에 설명하겠지만, 포인터를 배열처럼 활용한다면, 배열을 더 효율적으로 활용할 수 있습니다.
포인터 활용
void swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
전에 설명했듯, 함수는 해당 변수를 데이터만 가져옵니다.
그렇기 때문에, 변수의 데이터를 아무리 바꾸어도 데이터는 변하지 않습니다.
하지만 위 코드는 포인터로 주소값을 받아옵니다.
함수에서 주소로 접근하여 변수 데이터를 활용하기 때문에, 데이터가 원하는대로 변경됩니다.
call by value / call by reference
위에서 설명한 데이터만 가져오는 경우가 call by value
방식입니다.
변수의 데이터를 호출(call)하기 때문에, 변수의 데이터는 바뀌지 않습니다.
- 이 경우 변수는 호출된 데이터를 저장하는 데이터 공간이(메모리) 생성됩니다.
포인터를 활용한 방식이 call by reference
방식입니다.
변수의 주소를 호출하기 때문에, 변수의 데이터도 변경됩니다.
void changeString(char *str, char text[]) {
str = text;
}
....
char a[10];
changeString(a, "abcd");
전에 설명했던 문자열(문자의 배열)도 결국 배열입니다.
그렇기에 함수에서 호출하는 경우 call by reference
방식으로 호출됩니다.
💡 지적 환영합니다
Comments