Open-Closed Principle

[C언어]포인터의 기초(pointer) 본문

Programming/C, C++

[C언어]포인터의 기초(pointer)

대박플머 2014. 6. 26. 00:51

포인터는 번지에 대한 기호화된 표현을 말한다. 즉, 포인터는 번지이다. 

Colored By Color Scripter

1
int pint;

pint라는 변수를 정의하면, 시스템이 프로그램이 실행중에 위의 정의를 만나면 pint에 대하여 4바이트의 메모리를 할당해준다. 시스템이 할당해준 4바이트는 다른 프로세스(다른 실행중인 프로그램)들이 할당 받지 못하므로 안전하게 사용할 수 있다. 이 4바이트는 각 바이트마다 모두 주소를 가지고 있는데 이를 번지라고 한다. 결국 포인터라는 것은 메모리의 위치(번지)를 표현한 기호인 것이다. 

포인터 변수 - 포인터는 메모리의 특정 위치(주소,번지)를 가리킨다고 했다. 포인터 변수는 포인터(주소, 번지)를 저장할 수 있는 변수를 말한다. 포인터 변수는 번지 이외에는 어떠한 것도 들어갈 수 없다는 사실 또한 잊어선 안된다.

포인터 변수의 정의

1
2
int*    pint; // 1. 
int    *pint // 2.

표기는 크게 이렇게 두가지 형태가 있다. 프로그래머마다 자신들만의 스타일이 있기 때문에 이런 형태로 사용하는 것인데 둘다 강조점이 조금 다른다. 
1.은 자료형을 강조 하기위해 자료형 자체가 int*라는 자료형이 있는 것처럼 받아 들이는 것 같고, 
2.는 실제로 포인터변수라는 것을 강조 하기 위해서이다. 변수명에 *가 표시된 주소를 저장할 수 있는 특별한 변수라는 것을 부각 하기 위해서 인것 같다. 

필자는 1번을 주로 이용하는 편이다. 참고 하길 바란다. 

포인터 변수의 할당

상식적으로 우리 한번 생각해보자. 필자가 위에서 계속 포인터 변수는 포인터(주소)를 저장하는 변수라고 말을 했다. 그렇다면 포인터 변수에 상식적으로 아래와 같은 할당이 가능한가?
1
2
3
4
int* pint
 
pint = 5;
pint = 'a';

맞다 어림도 없는 소리다. 이건 완전히 포인터 변수를 모른다는 이야기다. 
그렇다면 어떻게 포인터 변수에 주소를 저장 할 수 있을까?
아래와 같이 하면 된다. 키워드는 바로  "&이다. 

1
2
3
4
5
int* pint
 
int iCount = 5;
 
pint = &iCount;

바로 이렇게 포인터 변수에 주소를 할당 하는 것이다. 일반 자료형(포인터 자료형이 아닌)의 앞에 & 연산를 사용하면 일반 자료형을 사용하는 변수들의 주소를 얻어 올 수 있다.


포인터 변수의 타입

포인터 변수는 아래와 같이 타입별로 존제한다. 

1
2
3
4
int*        pi;
float*     pf;
double* pd;
char*     pc;

포인터 변수의 타입을 이야기 할 때 중요한 부분이 있다. 혹시 여러분은 int형 변수가 sizeof() 함수를 통해 출력의 결과가 몇 바이트 인지 알고 있나? 맞다. 4바이트이다. 64비트 환경에서는 8바이트로 나올 수도 있다. 그런데 int*는 몇바이트 일까?

다한번 실험을 해보자. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
 
int main(){
    int     int_;
    float     float_;
    double     double_;
    char     char_;
 
    int*     pint;
    float*     pfloat;
    double* pdouble;
    char*     pchar;
 
    printf("int[%d] float[%d] double[%d] char[%d]\n"sizeof(int_), sizeof(float_), sizeof(double_), sizeof(char_));
 
    printf("int[%d] float[%d] double[%d] char[%d]"sizeof(pint), sizeof(pfloat), sizeof(pdouble), sizeof(pchar));
 
}

결과가 궁굼할 것이다. 이야기 하고 싶은 부분은 바로 2번째 printf이니 두번째 printf결과를 확인하는 것이 중요할 것이다. 

32비트인 경우 4바이트 64바이트인경우 8바이트가 나왔을 것이다. 

여기서 우리는 한가지 알아야할 사실이 있다. 바로 포인터 변수는 모두 같은 바이트에 주소를 저장하는 구나 그리고 더 나아가 유추한다면 주소의 길이가 모두 같기 때문에 다 같을 수도 있겠다라고 유추도 해볼 수 있을 것이다. 

그리고 타입이 필요한 이유는 1번째 printf에서 찾을 수 있다. 포인터 변수는 포인터(주소)를 저장한다고 했다. 그런데 주소만 저장 되어 있지 주소가 몇 바이트인지 포인터 변수에 표시해 주질 않았다. 바로 이부분이다. 포인터 변수의 타입은 이런 점을 고려하여 컴파일 타임에 몇 바이트의 주소를 호출해야 하는지를 명세 하기 위해 타입을 적어 주는 것이다. 꼭 알아 두어야 한다. 


이상 포인터의 기초 


끝..