반응형
포인터 (Pointers)
요약
- 포인터는 메모리 주소를 저장하며, 간접적으로 데이터를 조작.
- 배열과 포인터:
- 배열 이름은 첫 번째 요소의 주소를 가리키는 포인터.
- arr[i]는 *(arr + i)와 동일.
- 함수 포인터:
- 함수를 가리키는 포인터로, 동적 함수 호출 가능.
- 동적 메모리와 포인터:
- malloc, calloc, realloc, free를 통해 메모리를 동적으로 관리.
11.1 포인터의 개념
- **포인터(pointer)**는 다른 변수의 메모리 주소를 저장하는 변수입니다.
- **주소 연산자 (&)**와 **역참조 연산자 (*)**를 통해 값을 다룹니다.
포인터의 선언
데이터타입 *포인터이름;
예제
#include <stdio.h>
int main(void) {
int x = 10;
int *p; // 정수를 가리키는 포인터 선언
p = &x; // x의 주소를 p에 저장
printf("x의 값: %d\n", x);
printf("x의 주소: %p\n", &x);
printf("p의 값 (x의 주소): %p\n", p);
printf("*p의 값 (x의 값): %d\n", *p);
return 0;
}
출력 결과:
x의 값: 10
x의 주소: 0x7ffee4c0a9cc
p의 값 (x의 주소): 0x7ffee4c0a9cc
*p의 값 (x의 값): 10
11.2 포인터와 메모리 주소
1) 주소 연산자 (&)
- 변수의 메모리 주소를 반환.
int x = 10;
int *p = &x; // p에 x의 주소 저장
2) 역참조 연산자 (*)
- 포인터가 가리키는 주소에 저장된 값을 참조하거나 수정.
int x = 10;
int *p = &x;
*p = 20; // x의 값을 20으로 변경
printf("%d\n", x); // 출력: 20
11.3 포인터와 함수
포인터를 함수의 매개변수로 전달하면, 함수 내부에서 원래 변수의 값을 변경할 수 있습니다.
포인터를 사용한 값 변경
#include <stdio.h>
void updateValue(int *p) {
*p = 20; // 포인터가 가리키는 변수의 값을 변경
}
int main(void) {
int x = 10;
printf("변경 전: %d\n", x);
updateValue(&x); // x의 주소 전달
printf("변경 후: %d\n", x);
return 0;
}
출력 결과:
변경 전: 10
변경 후: 20
11.4 배열과 포인터
배열의 이름은 배열의 첫 번째 요소의 주소를 나타내는 포인터처럼 작동합니다.
배열과 포인터의 관계
int arr[3] = {10, 20, 30};
printf("%p\n", arr); // 배열의 시작 주소
printf("%p\n", &arr[0]); // 첫 번째 요소의 주소
배열 요소 접근
- arr[i]는 *(arr + i)와 동일합니다.
int arr[3] = {10, 20, 30};
printf("%d\n", arr[1]); // 20
printf("%d\n", *(arr + 1)); // 20
11.5 포인터 산술 연산
포인터는 배열과 함께 사용할 때 산술 연산을 지원합니다.
포인터 증가
- 포인터를 증가시키면, 데이터 타입 크기만큼 이동.
#include <stdio.h>
int main(void) {
int arr[3] = {10, 20, 30};
int *p = arr;
printf("%d\n", *p); // 10
p++;
printf("%d\n", *p); // 20
return 0;
}
11.6 다차원 배열과 포인터
1) 2차원 배열
2차원 배열은 배열의 배열로 표현됩니다.
- matrix[i][j]는 *(*(matrix + i) + j)와 동일.
#include <stdio.h>
int main(void) {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
printf("%d\n", matrix[1][2]); // 6
printf("%d\n", *(*(matrix + 1) + 2)); // 6
return 0;
}
11.7 함수 포인터
1) 함수 포인터의 선언
- 함수 포인터는 함수의 주소를 저장하는 포인터입니다.
반환형 (*포인터이름)(매개변수 타입들);
2) 함수 포인터 사용
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main(void) {
int (*funcPtr)(int, int) = add; // add 함수의 주소 저장
printf("결과: %d\n", funcPtr(10, 20)); // 함수 호출
return 0;
}
출력 결과:
결과: 30
11.8 동적 메모리 할당과 포인터
동적 메모리 할당은 포인터를 통해 관리됩니다.
1) 동적 메모리 할당 (malloc)
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = (int *)malloc(5 * sizeof(int)); // 정수 5개 메모리 할당
if (p == NULL) {
printf("메모리 할당 실패\n");
return 1;
}
for (int i = 0; i < 5; i++) {
p[i] = i + 1; // 메모리 초기화
}
for (int i = 0; i < 5; i++) {
printf("%d ", p[i]); // 출력
}
free(p); // 메모리 해제
return 0;
}
출력 결과:
1 2 3 4 5
11.9 심화 예제
1) 포인터 배열
포인터 배열은 여러 포인터를 저장하는 배열입니다.
#include <stdio.h>
int main(void) {
char *fruits[] = {"Apple", "Banana", "Cherry"};
for (int i = 0; i < 3; i++) {
printf("%s\n", fruits[i]);
}
return 0;
}
출력 결과:
Apple
Banana
Cherry
2) 배열 포인터
배열 포인터는 배열 전체를 가리킵니다.
#include <stdio.h>
int main(void) {
int arr[3] = {10, 20, 30};
int (*p)[3] = &arr;
printf("%d\n", (*p)[0]); // 10
printf("%d\n", (*p)[1]); // 20
return 0;
}
요약
- 포인터는 메모리 주소를 저장하며, 간접적으로 데이터를 조작.
- 배열과 포인터:
- 배열 이름은 첫 번째 요소의 주소를 가리키는 포인터.
- arr[i]는 *(arr + i)와 동일.
- 함수 포인터:
- 함수를 가리키는 포인터로, 동적 함수 호출 가능.
- 동적 메모리와 포인터:
- malloc, calloc, realloc, free를 통해 메모리를 동적으로 관리.
반응형
'Computer Science > C 언어' 카테고리의 다른 글
[C #14] 동적 메모리 할당 (Dynamic Memory Allocation) (0) | 2024.12.12 |
---|---|
[C #13] 포인터와 배열 (Pointers and Arrays) (1) | 2024.12.11 |
[C# 11] Makefile 분석 (0) | 2024.12.09 |
[C 10] 프로그램 조직화 (Program Organization) (1) | 2024.12.08 |
[C #9] 함수 (Functions) (3) | 2024.12.07 |