포인터와 예제
1. 포인터의 개요
1.1. 포인터 변수의 개념
-
정의:
포인터 변수는 변수의 주소를 값으로 저장하는 변수입니다 -
주소:
모든 변수는 메모리 상에 고유한 주소를 가지며, 포인터 변수는 이러한 주소를 저장하여 다른 변수에 간접적으로 접근할 수 있게 합니다.
1.2. 포인터 변수의 선언 및 초기화
-
선언:
데이터타입 *포인터변수이름;
형식으로 선언합니다.
예시:int *b; // 정수형 변수의 주소를 저장할 포인터 변수 b 선언
-
초기화:
포인터변수이름 = &변수이름;
형식으로 변수의 주소를 포인터 변수에 할당합니다.
여기서&
는 주소 연산자입니다.예시:
int a = 10;
int *b;
b = &a; // b에 a의 주소 저장
1.3. 포인터 변수의 데이터 타입 일치
- 포인터 변수도 데이터 타입을 가집니다.
- 포인터변수가 가리키는 변수의 데이터타입과 포인터변수의 데이터타입이 일치해야 함
올바른 예:
int i = 10;
int *ip;
ip = &i;
오류 예:
float i = 10;
int *ip;
ip = &i; // 타입 불일치로 인한 오류
1.4. 포인터 연산자
-
주소 연산자 (
&
):
변수의 주소는&
연산자로 접근 가능함 예: 변수 a의 주소는&a
로 얻을 수 있습니다. -
간접 참조 연산자 (
*
):
포인터변수에 들어있는 주소의 값을 가져오는 연산자 예: 포인터 변수 b가 저장하고 있는 주소에 있는 값은*b
로 접근할 수 있습니다. -
주소 출력:
주소를 출력하기 위해서는printf
함수에서%p
또는%u
변환 문자를 사용합니다6, p.24).
2. 포인터 활용 예제
2.1. 포인터 변수와 배열
-
배열의 이름:
배열의 이름은 배열의 시작 주소를 저장하는 포인터처럼 동작합니다."배열의 이름은 배열을 시작하는 주소를 저장함"
-
포인터를 이용한 배열 접근:
int arr[5] = {1, 2, 3, 4, 5};
int *arptr;
arptr = arr; // 배열의 시작 주소를 포인터에 할당arptr[i]
를 사용하여 배열처럼 접근하거나,*(arptr + i)
를 사용하여 간접 참조 연산과 포인터 연산을 통해 배열 요소를 접근할 수 있습니다- 마찬가지로
*(arr + i)
와 같이 배열의 이름에 직접 간접 참조 연산과 포인터 연산을 적용하여 요소를 접근할 수도 있습니다
2.2. 포인터 변수의 연산
포인터 변수는 값의 증가/감소 뿐만 아니라 주소의 증가/감소 연산도 가능합니다
-
ptr++
(주소 증가):
포인터 변수 자체가 다음 메모리 위치로 이동합니다."포인터변수는 4byte 단위로 이동합니다." 이는 포인터가 가리키는 자료형의 크기만큼 주소가 증가함을 의미합니다.
(예: int는 4바이트, double은 8바이트, char는 1바이트)printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 증가, *ptr은 새로운 주소의 값
-
(*ptr)++
(가리키는 값 증가):
포인터가 가리키는 메모리 위치에 저장된 값을 1 증가시킵니다.
포인터 변수 자체의 주소는 변하지 않습니다.printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr은 변함없고, *ptr의 값이 1 증가
-
*(++ptr)
(주소 증가 후 참조):
포인터 변수를 먼저 증가시킨 후, 증가된 주소에 있는 값을 참조합니다.printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 증가, *ptr은 새로운 주소의 값
-
*(--ptr)
(주소 감소 후 참조):
포인터 변수를 먼저 감소시킨 후, 감소된 주소에 있는 값을 참조합니다.printf("ptr=%p *ptr=%d\n", ptr, *ptr); // ptr의 값이 감소, *ptr은 새로운 주소의 값
3. 학습 정리 (핵심 요약)
-
포인터 변수 개념: