함수에 인자 전달 시 포인터를 사용하지 않는다면 전달되는 인자의 크기만큼의 메모리를 복사하게 되기 때문입니다.
만약 int형 100개를 가진 배열을 포인터를 쓰지 않고 인자로 전달한다면 복사하기 위해 4byte x 100 = 400byte의 메모리를 더 쓰게 되는 일이 발생합니다.
하지만 포인터를 쓰게 된다면 바로 배열의 메모리에 접근하여 값을 가져올 수 있게 됩니다. pc를 사용하면 메모리 용량이 커서 괜찮을 수도 있으나 임베디드 보드같이 메모리가 작다면 포인터를 사용할 수 밖에 없을 것입니다.
2. 포인터 선언
int *ptr = NULL; //int형 변수를 가리키는 포인터
float *ptr = NULL; // float형 변수를 가리키는 포인터
char *ptr = NULL; // char형 변수를 가리키는 포인터
위와 같이 [포인터가 가리키고자 하는 변수형] *[포인터 변수 이름] 형식으로 선언해 주시면 됩니다.
포인터가 가리키고자 하는 변수형 뒤에 별표를 써주시면 되는데 int *ptr로 선언하나 int* ptr로 선언하나 차이는 없습니다.
!!포인터 선언 시 반드시 NULL로 초기화하거나 선언과 동시에 주소값을 할당해 주어야 한다. int *ptr; *ptr = 100; 위와 같이 선언 후, ptr이 어디를 가리키는 지 모르는 상태(메모리의 중요한 부분을 가리킬 수도 있다!!)로 값을 대입하게 된다면, 시스템 전체에 심각한 문제를 일으킬 수도 있다.
함수 포인터를 생각하면 소괄호를 해주는 것이 좋습니다. ex) (int *) returnIntValue(void); // int형 포인터를 반환하는 함수 int (*funcPtr)(void) = func; // func함수를 가리키는 funcPtr 함수 포인터 선언 함수 포인터는 다음에 자세히 설명해드리도록 하겠습니다.
어떤 변수의 주소값을 나타낼 때는 변수 이름 앞에 '&'를 붙이시면 됩니다.
또한, 포인터가 가리키고 있는 변수가 가지고 있는 값을 보고싶을 때는 포인터 변수 앞에 '*'를 붙이시면 됩니다.
int int_value = 10;
float float_value = 0.9;
char char_value = 'c';
int *int_ptr = &int_value;
float *float_ptr = &float_value;
char *char_ptr = &char_value;
printf("int형 포인터가 가지고 있는 주소값 = %d\n", int_ptr); //int_value의 주소
printf("int형 포인터가 가리키고 있는 변수가 가지고 있는 값 = %d\n", *int_ptr); // int_value가 가지고 있는 값 10
3. 포인터 크기
int형 포인터와 char형 포인터의 크기는 얼마일까요?
32bit 컴파일을 사용한다면 포인터의 크기는 int형 포인터든 char형 포인터든 4byte가 됩니다. 포인터 변수는 메모리 주소값을 저장하는데 메모리 주소값은 항상 4byte(32bit일 때)로 일정하기 때문입니다.
4. 참조자
참조자는 변수의 별명입니다.
예를 들어, 트램펄린타는 것을 지역마다 방방, 붕붕, 콩콩 등 여러 이름으로 불리지만 결국 같은 것을 가리키는 것처럼, 어떤 변수를 다른 이름으로도 쓸 수 있게 하는 것이 참조자입니다.
포인터의 참조자를 선언할 때는 [변수형] *(&참조자) = 포인터;
포인터를 가리키는 포인터를 선언할 때는 [포인터 변수형] **(이중 포인터 변수 이름) = 포인터;
int data = 10;
int *ptr = &data;
int &ref = *ptr; // (=data), ptr의 값인 data의 주소값이 ref의 주소값이 된다.
// int &ref = data;
int *(&ptr_ref) = ptr; // ptr의 별칭
int **pPtr = &ptr; // ptr을 가리키는 포인터(이중 포인터)
printf("data의 값 = %d\n", data);
printf("data의 주소 = %d\n", &data);
printf("ptr의 값 = %d\n", ptr);
printf("ptr의 주소 = %d\n", &ptr);
printf("ptr이 가리키고 있는 변수의 값 = %d\n", *ptr);
printf("ref의 값 = %d\n", ref);
printf("ref의 주소 = %d\n", &ref);
printf("ptr_ref의 값 = %d\n", ptr_ref);
printf("ptr_ref의 주소 = %d\n", &ptr_ref);
printf("pPtr의 값 = %d\n", pPtr);
printf("pPtr의 주소 = %d\n", &pPtr);
printf("pPtr이 가리키고 있는 변수의 값 = %d\n", *pPtr);
결과
data의 값 = 10
data의 주소 = 1560346132
ptr의 값 = 1560346132
ptr의 주소 = 1560346136 // &ptr
ptr이 가리키고 있는 변수의 값 = 10 // *ptr
ref의 값 = 10
ref의 주소 = 1560346132
ptr_ref의 값 = 1560346132
ptr_ref의 주소 = 1560346136
pPtr의 값 = 1560346136
pPtr의 주소 = 1560346144 // &pPtr
pPtr이 가리키고 있는 변수의 값 = 1560346132 // *pPtr
포인터 C++
1. 포인터 사용 이유
함수에 인자를 전해줄 때를 생각하면 왜 포인터가 필요한지 이해하기 쉽습니다.
함수에 인자 전달 시 포인터를 사용하지 않는다면 전달되는 인자의 크기만큼의 메모리를 복사하게 되기 때문입니다.
만약 int형 100개를 가진 배열을 포인터를 쓰지 않고 인자로 전달한다면 복사하기 위해 4byte x 100 = 400byte의 메모리를 더 쓰게 되는 일이 발생합니다.
하지만 포인터를 쓰게 된다면 바로 배열의 메모리에 접근하여 값을 가져올 수 있게 됩니다. pc를 사용하면 메모리 용량이 커서 괜찮을 수도 있으나 임베디드 보드같이 메모리가 작다면 포인터를 사용할 수 밖에 없을 것입니다.
2. 포인터 선언
위와 같이 [포인터가 가리키고자 하는 변수형] *[포인터 변수 이름] 형식으로 선언해 주시면 됩니다.
포인터가 가리키고자 하는 변수형 뒤에 별표를 써주시면 되는데 int *ptr로 선언하나 int* ptr로 선언하나 차이는 없습니다.
함수 포인터를 생각하면 소괄호를 해주는 것이 좋습니다.
ex) (int *) returnIntValue(void); // int형 포인터를 반환하는 함수
int (*funcPtr)(void) = func; // func함수를 가리키는 funcPtr 함수 포인터 선언
함수 포인터는 다음에 자세히 설명해드리도록 하겠습니다.
어떤 변수의 주소값을 나타낼 때는 변수 이름 앞에 '&'를 붙이시면 됩니다.
또한, 포인터가 가리키고 있는 변수가 가지고 있는 값을 보고싶을 때는 포인터 변수 앞에 '*'를 붙이시면 됩니다.
3. 포인터 크기
int형 포인터와 char형 포인터의 크기는 얼마일까요?
32bit 컴파일을 사용한다면 포인터의 크기는 int형 포인터든 char형 포인터든 4byte가 됩니다. 포인터 변수는 메모리 주소값을 저장하는데 메모리 주소값은 항상 4byte(32bit일 때)로 일정하기 때문입니다.
4. 참조자
참조자는 변수의 별명입니다.
예를 들어, 트램펄린타는 것을 지역마다 방방, 붕붕, 콩콩 등 여러 이름으로 불리지만 결국 같은 것을 가리키는 것처럼, 어떤 변수를 다른 이름으로도 쓸 수 있게 하는 것이 참조자입니다.
포인터의 참조자를 선언할 때는 [변수형] *(&참조자) = 포인터;
포인터를 가리키는 포인터를 선언할 때는 [포인터 변수형] **(이중 포인터 변수 이름) = 포인터;
결과
'Study' 카테고리의 다른 글