C++

C++) 포인터 , 기초부터 다시하기

나무늘보섬 2024. 9. 3. 18:12

코딩할 때마다 헷갈리고, 찾아보게 되서 내가 다시 정리하는 포인터 개념!

기초가 부족한 것을 깨닫고 다시하기

 

 

pointer ( * )

- 특정한 데이터의 주소값을 보관하는 변수  ( <- 이름만 들어선 모름)qust

- 포인터하면 항상 &(ampersand)가 빠지지 않음

- &: "변수의 주소값"을 말한다.

 

더보기

예시 코드 (코드 출처: https://modoocode.com/23)

#include <stdio.h>
int main() {
  int *p;
  int a;

  p = &a;

  printf("포인터 p 에 들어 있는 값 : %p \n", p);
  printf("int 변수 a 가 저장된 주소 : %p \n", &a);

  return 0;
}

.

.

.

.

.

 

 

해석

- *p는 p라는 주소에 담긴 값(value)이고 , p는 a의 주소값(address)이다  -> 따라서 *p는 a에 담긴 값이 된다. (이 코드에선 없음)

- a는 정수형 변수, &a는 a가 담긴 "주소값"이다.

 

저기서

 printf("*p의 값: %d\n",*p);

라고 하면 ? a의 값이 나온다.

(참고로, 이때  0이 나옴, 그 이유 -> 초기화 하지 않는 전역 변수의 경우 '0'으로 초기화가 된다.)

 

 

 

 

실제 값을 대입해보자 (아래 글)

더보기

예시 코드 (코드 출처: https://modoocode.com/23)

#include <stdio.h>
int main() {
  int *p;
  int a;

  p = &a;
  a = 2;

  printf("a 의 값 : %d \n", a);
  printf("*p 의 값 : %d \n", *p);

  return 0;
}

 

 

.

.

.

.

.

.

.

 

 

결과 값은? 

 a의 값: 2 ( a=2라고 했으니)

*p의 값: 2

( p=&a -> 즉, p에 &a(a의 주소값)를 대입했다, 그러므로 *p는 *(&a)와 동일하다. 

-> 따라서 *p는 a의 주소값에 담긴 데이터 값이라고 해석)

 


만약 const가 붙는 경우면??

const와 *가 결합하는 경우는 2가지로 나뉜다. 

 

  •  const가 데이터 값에 붙는 경우
  •  const가 *(포인터)에 붙는 경우

 

이 2가지로 나뉜다.

 

 

const가 값(value)에 붙는 경우

int a;

const int* pa= &a; 일 때. 다음과 같이 해석된다.

const가 int에 해당한다 -> 따라서 주소는 변경이 가능함, 그러나 pa의 정수값은 변경 불가능.

 

더보기

예시 코드

#include <stdio.h>
int main() {
  int a;
  int b;
  const int* pa = &a;

  *pa = 3;  // 올바르지 않은 문장
  pa = &b;  // 올바른 문장
  return 0;
}

 

 

이 코드도 보면 *pa  즉, pa의 값(value)를 변경하려 했기 때문에 올바르지 않은 문장이지만,

pa 즉, 주소 값을 b의 주소 값으로 변경하는 건 가능하다

 

 

 

const가 *(포인터) 에 붙는 경우

이런 경우는  다음과 같이 작성한다

int *const pa = &a;

이 경우는 위와 다르게 해석된다 . 주소 값은 변경이 불가능하지만 pa의 값(value)은 변경이 가능

더보기

예시코드

#include <stdio.h>
int main() {
  int a;
  int b;
  int* const pa = &a;

  *pa = 3;  // 올바른 문장
  pa = &b;  // 올바르지 않은 문장

  return 0;
}

 

*pa 즉, pa의 값(value)은 변경이 가능하지만 , const가 포인터에 붙었기 때문에 pa의 주소값은 변경이 불가능하다.

 

 

정리하자면, 

  const int* pa int* const pa
주소값 (address value) o x
값(value) x o

 

 


만약 *가 배열에 붙는다면?

우선 int arr[3] -> arr이라는 배열에 3개의 정수 값이 보관 가능하다.

따라서 printf("%d",arr[0]);를 하면  arr의  0번째 값(value)가 나온다.

 

만약 printf("%d",arr);를 하면 똑같이 0번째 값이 나오지 않는다!

-> 배열의 이름은 0번째 index의 주소값이다. 즉 arr == &(arr[0])과 동일하다는 것

 

 

int arr[3]와 int *arr[3]의 차이

- int arr[3]은정수형 변수 3개가 담긴 arr배열이 존재한다.

- int *arr[3]은 주소가 3개 담긴 arr 배열인데, 그 주소는 정수형 변수의 주소이다.

 

즉, 값들의 배열이냐 주소들의 배열이냐 차이!

 

arr[3] -> 값들의 배열 

---------------------------------------

*arr[3] -> 주소들의 배열 ∴ arr[0], [1], [2] == &(변수) 

즉, 요소들의 주소가 배열로 나와있는 것!

그래서 주소안의 값에 접근하려면? -> *arr[0], *arr[1] 이런 방식으로 접근을 해야한다!

 

 

-----------------------------------------------------------------------------------------------------------------------------

추가로, for문을 사용하기 위해서 int arr[3]이 있으면 for(int i=0; i<sizeof(arr); i++) 했더니,

이상하게 코딩됐음!

-> sizeof(arr)을 하면 int는 4바이트 공간 3칸 -> 4x3이 되서 12가 나옴!

따라서 sizeof를 사용할 땐 int *arr or  int arr 관계없이 무조건 <sizeof(arr)/sizeof(arr[0])>해야 배열의 길이만큼 반복 가능!

 


https://modoocode.com/23