포인터의 크기, 선언 방법, 값과 주소 연산자

C언어를 공부할 때 스트레스를 받는 부분이 문자열을 만들고자 할 때부터 나오는 포인터를 이해하는 것이죠.

지금은 거의 다 64비트 컴퓨터를 사용 중이겠지만 대부분 책에는 32비트 프로그램으로 설명하니 저도 32비트로 설명합니다.

비주얼 스튜디오의 Windows 데스크톱 마법사로 콘솔 응용 프로그램을 만들면 기본적으로 32비트 프로그램을 만드는 환경으로 되어있습니다.

아래 빨간 줄 부분이 x86이면 32비트, x64이면 64비트 프로그램이 됩니다.

 

포인터의 크기

포인터의 크기는 32비트 프로그램이라면 4바이트입니다. sizeof() 함수로 확인할 수 있습니다.

포인터 변수는 가상 메모리의 주소를 가지고 있을 뿐이기에 32비트(=  4바이트) 주소 체계에선 주소의 길이인 4바이트의 크기를 가지는 것입니다.

#include <stdio.h>
int main(void) {
	printf("%d\n", sizeof(char));   // 1
	printf("%d\n", sizeof(int));    // 4
	printf("%d\n", sizeof(float));  // 4
	printf("%d\n", sizeof(double)); // 8

	printf("%d\n", sizeof(char*));  // 4
	printf("%d\n", sizeof(int*));   // 4
	printf("%d\n", sizeof(float*)); // 4
	printf("%d\n", sizeof(double*));// 4
}

 

포인터의 선언 방법

포인터 선언 방법은 데이터 타입, *(간접 지정 연산자), 변수 이름을 순서대로 쓰기만 하면 됩니다. 다음 코드는 모두 정상입니다.

int* count;
int *count;
int*count;
int * count;
  • count라는 이름을 가진 변수는
  • *가 붙었으니 포인터 변수이고
  • int가 있으니 이 포인터가 가지고 있는 주소엔 정수가 있어야 한다. 라고 거꾸로 읽으면서 이해하면 쉽습니다.

 

주소 연산자

주소 연산자 &는 변수의 주소를 반환합니다. 따라서 다음처럼 포인터 변수를 선언과 동시에 초기화할 수 있습니다.

int num = 100;
int *count = &num;

포인터 변수가 먼저 선언되었다면 다음처럼 초기화할 수 있습니다.

int num = 100;
int *count;
count = &num;

만약 포인터 변수에 주소가 아닌 값을 넣으면 참조 수준이 다르다는 오류가 납니다. 예를 들어

count = num;

이렇게 주소가 아닌 정수를 넣는다면 말이죠. 데이터 타입이 다르면 변수의 크기가 4바이트로 동일해도 오류입니다.

하지만 정수를 포인터로 캐스팅(형 변환)하는 것은 가능합니다.

//int형 포인터의 경우
int num = 100;
int *count;
count = (int*)num;

// char형 포인터의 경우
int num=100;
char *count;
count = (char*)num;

int형 포인터라면 (int*)로 char형 포인터라면 (char*)로 말이죠.

하지만 이 경우 포인터가 메모리 주소 100을 가리키게 됩니다. 이렇게 쓸 일은 없습니다. 이걸 읽기라도 했다간 프로그램은 비정상 종료됩니다. 궁금하시다면 printf()로 *count 값을 출력해보세요.

 

포인터의 값

이번엔 1. 포인터 변수의 주소와 2. 포인터 변수가 가지고 있는 값과 3. 포인터 변수가 가리키고 있는 값을 출력해봅시다.

int num=100;
int *count;
count = &num;
printf("%d\n", &count); //9697236
printf("%d\n", count);  //9697248
printf("%d\n", *count); //100
printf("%d\n", &num);   //9697248
printf("%d\n", num);    //100

간단하게 하려고 형식 지정자를 %d로 통일했고 출력 결과는 주석에 쓰여있습니다.

출력 결과는 각자 다를 수 있습니다. 중요한 건

  • count라는 포인터 변수가 있는 곳은 967236이고
  • 이 곳에(포인터 변수가 가지고 있는 값이) 9697248이란 값이 들어있고
  • 이 값은 주소로 num이라는 변수가 있는 곳이며
  • 이 곳엔(num 변수가 가지고 있는 값이) 100이란 값이 있다는 것입니다.

count 포인터 변수는 num 변수가 있는 곳을 가리키고 있으므로

*count = 200;
printf("%d\n", *count); // 200
printf("%d\n", num);    // 200

이렇게 간접 지정 연산(*)으로 값을 변경할 수 있습니다.

SW Level Up

mail@swlevelup.com

You may also like...

2 Responses

  1. skEnd 댓글:

    제가 c언어 공부하면서 궁금한 게 생겨서 여쭤볼려고 합니다.
    만약에 2차원 배열에 16진수 형태로 초기값을 넣고, char 포인트 변수로 배열의 값이랑 바이트를 어떻게 구할 수 있을까요?
    값이 하나일때는 출력되는데 두개 이상부터는 안되네요ㅠ

    • Skills 댓글:

      char arr[2][3] = { {1,3,5},{7,9,11} };
      printf(“%d\n”, *(*(arr))); // 1
      printf(“%d\n”, *(*(arr)+1)); // 3
      printf(“%d\n”, *(*(arr)+2)); // 5
      printf(“%d\n”, *(*(arr+1))); // 7
      printf(“%d\n”, *(*(arr+1)+1)); // 9
      printf(“%d\n”, *(*(arr+1)+2)); // 11
      char *p = *(arr+1)+2; // 11이 있는 주소
      *p = *p + 10;
      printf(“%d\n”, *p); // 21
      이런걸 말씀하시는 거죠?

댓글 남기기

이메일은 공개되지 않습니다.