사고쳤어요
C 포인터 본문

변수는 위와 같이 0x1000이라는 메모리 주소에 저장된 값을 불러오기 위한 메모리 주소의 식별자이다.
변수 덕분에 메모리 주소를 외울 필요 없이 편리하게 메모리로부터 값을 불러올 수 있다.

포인터는 포인터 변수의 줄임말로 메모리의 주소값을 저장하고 있는 변수이다.
이를 한 번 더 풀어서 설명하면, 메모리의 주소값을 저장하고 있는 메모리의 주소값을 저장하는 식별자이다.
메모리 주소 0x01에 저장된 값 65를 사용하기 위한 변수 a가 있을 때,
메모리 주소 0x21에 저장된 값 0x01을 사용하기 위한 변수 pA가 포인터이다.
포인터 사용 방법
C에서는 포인터 변수를 사용할 때 일반 변수와 구분하기 위해 변수명 앞에 * 기호를 붙인다.
예를 들면 int *pA; char *pB; 와 같이 선언하면 된다.
선언을 했다면, 변수에 주소값을 할당해주어야 할 것이다.
C에서는 변수의 주소값을 나타내기 위해 변수명 앞에 & 기호를 붙인다.
예를 들어 int *pA = &a; 와 같이 선언하면, 포인터 변수 pA는 변수 a의 주소값을 저장한다는 의미이다.
포인터가 선언이 되었다면 포인터에는 메모리 주소가 저장되어 있을 것이다.
그런데 이를 활용하여, 포인터가 저장하고 있는 메모리 주소가 저장하고 있는 값을 불러올 수 있다.
예를 들어 int *pA = &a; 가 있을 때 printf("%d", pA);를 실행하면 a의 메모리 주소가 출력된다.
그리고 pA의 앞에 * 기호를 붙여 printf("%d", *pA);를 실행하면 a의 값이 출력된다.
여기서 *pA는 처음 pA를 선언할 때 int *pA = &a;의 *pA와 다른 의미라는 것을 알아야 한다.
int main(){
int a = 100;
int *pA = &a; // 여기서 *pA는 포인터 변수라는 뜻의 *
printf("a: %d \n", a); // a: 100
printf("&a: %x \n", &a); // &a: 61ff18
printf("*pA: %d \n", *pA); // *pA: 100, 여기서 *pA는 가리키는 메모리 주소의 실제 값이라는 뜻의 *
printf("pA: %x \n", pA); // pA: 61ff18
}
배열과 포인터
C에서는 배열을 사용하기 위해 int arr[5] = {1, 2, 3, 4, 5}와 같이 사용할 수 있다.
배열의 각 요소에 접근하기 위해서는 인덱스를 사용하여 arr[0], arr[1], ... 과 같이 접근이 가능하다.
그리고 배열의 이름 arr은 배열의 첫 번째 요소의 주소값을 가리키는 포인터 변수의 역할을 한다.
즉 arr은 arr[0]의 주소값, &arr[0]과 같다.
int main(){
int arr[5] = {1, 2, 3, 4, 5};
printf("&arr[0]: %x \n", &arr[0]); // &arr[0]: 61ff0c
printf("arr: %x \n", arr); // arr: 61ff0c
}
그렇다면 배열의 이름도 포인터이니 다른 포인터 변수 값으로 값을 바꿀 수 있을까?
int main(){
int arr[5] = {1, 2, 3, 4, 5};
int a = 3;
int *pA = &a;
arr = pA; // 오류 발생
}
배열의 이름을 다른 값으로 변경하려 하면 오류가 발생하는데, 상수이기 때문이다.
배열의 이름은 포인터 상수로 가리키고 있는 주소값을 변경할 수 없다.
함수와 포인터
void func(int *pArr){
for (int i = 0; i < 5; i++){
printf("%d \n", *(pArr + i));
}
}
int main(){
int arr[5] = {1, 2, 3, 4, 5};
func(arr);
}
// output
// 1
// 2
// 3
// 4
// 5
함수의 파라미터로 포인터 변수를 받을 수 있다.
위의 예시에서는 *pArr이라는 이름의 포인터를 통해 그 메모리 주소에 저장된 값을 출력한다.
그리고 func(arr)이 호출되면 pArr에 arr의 값, &arr[0]이 복사되어 저장된다.
int plus(int a, int b){
return a + b;
}
int main(){
int (*fPtr)(int pa, int pb); // 함수 포인터
fPtr = plus;
printf("%d", fPtr(3, 5)); // 8
}
포인터가 가리키는 주소값을 함수로 지정할 수도 있다.
위 코드에서 fPtr은 함수 plus를 가리키게 되어 있고, 그 주소값을 통해서 plus함수를 호출하고 있다.