210117 개발일지(41일차) - c언어 알아보기(6) : 포인터 심화학습(포인터의 크기, 역참조 연산자(*), 다양한 자료형 포인터 등)

고재개발·2021년 1월 17일
0

C Language

목록 보기
9/13

앞에서 잠깐 포인터가 무엇인지에 대해서는 알아봤다.

이제 프린터에 대해 심화학습을 해보자. 공부 및 자료참조는 코딩도장에서 했다.

포인터 한 줄 요약

"포인터는 주소"다.
포인터 변수에 저장되는 값은 (메모리 상에서 어떤 data를 가리키는) 주소값이다. 이 것을 항상 잘 생각하자.

포인터의 크기(포인터는 몇 byte일까?)

정답은 cpu에따라 다르다. 32, 64bit 컴퓨터에서 각각 32bit / 64bit이다.

  • 32비트: 16진수 8자리
    : 0x00000000 ~ 0xFFFFFFFF
  • 64비트: 16진수 16자리
    : 0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF
    sizeof로 포인터의 크기를 구해보면 32비트에서는 4바이트, 64비트에서는 8바이트가 나온다.
//아래와 같이 실행해보면 확인해볼 수 있다.
sizeof(포인터)
sizeof(자료형 *)

역참조(dereference) 연산자 : *

*은 포인터 변수를 만들어 줄 때도 사용했지만, 포인터 변수 앞에 *을 붙이면 "포인터 변수가 가리키는 주소값으로 가라"는 뜻이 된다. 따라서 아래와 같이 작성하면 '10'이 프린트 된다.

#include <stdio.h>

int main()
{
    int *numPtr;      // 포인터 변수 선언
    int num1 = 10;    // 정수형 변수를 선언하고 10 저장

    numPtr = &num1;   // num1의 메모리 주소를 포인터 변수에 저장
    printf("%d\n", *numPtr);    // 10: 역참조 연산자로 num1의 메모리 주소에 접근하여 값을 가져옴
}

아래의 사진처럼 생각하면 된다. 포인터를 선언할 때 사용한 *과 역참조를 하는 *를 구분지어 생각하는 편이 좋다.

다양한 자료형의 포인터

자료형 마다 *을 붙여서 포인터를 만드는 이유는 아래와 같다. 즉, 어떤 자료형이냐에 따라 그 크기에 해당하는 만큼 주소에 접근하기 때문이다.

const를 가리키는 포인터와 const 포인터

  • 포인터는 상수를 가리킬 수 있다. 그럼, 포인터로 그 값에 접근해서 조회는 할 수 있지만 변경은 할 수 없는 상황인 것이다.
const int num1 = 10;    // int형 상수
const int *numPtr;      // int형 상수를 가리키는 포인터. int const *numPtr도 같음
numPtr = &num1;
*numPtr = 20;    // 컴파일 에러. num1이 상수이므로 역참조로 값을 변경할 수 없음
  • 반면, 포인터 자체를 한 메모리 주소만 가리키게 상수처럼 설정할 수 있다. 다른 주소값 입력이 불가능하게 만드는 것이다.
int num1 = 10;    // int형 변수
int num2 = 20;    // int형 변수
int * const numPtr = &num1;    // int형 포인터 상수
numPtr = &num2;    // 컴파일 에러. 포인터(메모리 주소)를 변경할 수 없음

const 자료형을 가리키는 const 포인터도 만들 수 있지만, 굳이 쓸 일이 없을 것 같아서 적지 않았다.

다음 포스팅에서 포인터의 꽃(?)인 void포인터이중 포인터, 포인터 형 변환 등에 대해 알아보자.

profile
고재개발

1개의 댓글

comment-user-thumbnail
2021년 1월 18일

내사랑귀염둥이 화이팅❤️ 잘하그있그만!!!! 좋아좋아 우리집 가장 화이팅!

답글 달기