ex) int n = 100; // 변수 선언
int *ptr = &n // 포인터 선언
밑에 그림은 ex) 예제 부분에서 사용된 변수와 포인터가 메모리에서 어떻게 저장되는지를 보여주는 예제
예시
복합 대입 연산식 | 연산 결과 |
---|---|
int N; | 정수형 변수 N 선언 |
int *pN; | 포인터 변수 pN 선언 |
pN = &N; | 정수 N 값이 저장된 주소를 저장하는 포인터변수 pN |
pN = pN + 1; | pN의 주소가 4바이트 증가된다. |
*pN = *pN + 1; | pN이 가리키는 값 즉 N의 값은 1이 증가한다. |
N = *pN * 2; | pN이 가리키는 값 즉 N의 값에 2를 곱해준다. |
장점
-> 메모리 매핑 하드웨어-외부장치를 메모리처럼 접근할 수 있다.
-> 참조에 의한 호출-함수외부 변수의 수정과 여러 개의 값을 반환할 수 있다.
단점
-> 사용하기 복잡하고 잘못 사용하면 심각한 오류가 발생한다.
ex 소스코드
int i, arr_len;
int num01 = 10, num02 = 20, num03 = 30;
int* arr[3] = {&num01, &num02, &num03}; // int형 포인터 배열 선언
arr_len = sizeof(arr)/sizeof(arr[0]);
for (i = 0; i < arr_len; i++)
{
printf("%d\n", *arr[i]);
}
위의 소스코드의 출력결과는 10 20 30이 나올것이다.
ex) 소스코드
#include <stdio.h>
int main(void)
{
char (*arr)[3];
char tmp1[3] = { 'b', 'l', 'o' };
char tmp2[3] = { 'c', 'k', '\0' }; //문자열의 끝을 알리는 '\0'을 추가
char tmp3[5] = { 'd', 'm', 'a', 's', 'k'}; //배열의 사이즈가 다릅니다. 가리키기 불가.
printf("tmp1[3]의 주소 : %p\n", tmp1);
printf("tmp2[3]의 주소 : %p\n", tmp2);
printf("tmp3[5]의 주소 : %p\n", tmp3);
printf("\n"); printf("\n");
arr = &tmp1; //arr은 tmp1의 주소를 가리킵니다.
printf("arr의 주소 : %p\t 문자열 : ", arr);
for (int i = 0; i < (int)sizeof(*arr); i++)
{
printf("%c", (*arr)[i]);
}
printf("\n");
arr = &tmp2; //arr은 tmp2의 주소를 가리킵니다.
printf("arr의 주소 : %p\t 문자열 : ", arr);
for (int i = 0; i < (int)sizeof(*arr); i++)
{
printf("%c", (*arr)[i]);
}
printf("\n");
//arr = &tmp3; 배열의 사이즈가 다르다는것은 타입이 다르다는 뜻 입니다.
return 0;
}
위 소스코드 예제를 그림으로 표시