본문 바로가기

BackEnd/C

포인터 형과 *연산자

반응형

1. 포인터 형 이란?


기존의 데이터 형은 자료형이라 불리는데 대표적인 데이터 형들은 다음과 같다.


int, char, long, float, double


이처럼 데이터에 데이터형이 존재하듯이 포인터에도 포인터 형이 존재한다.


int *    > int형 포인터


char *  > char형 포인터


double *  > double 형 포인터


2. *연산자


*연산자는 변수의 이름을 이용해서 직접 접근하는 것이 아니고 포인터 변수를 이용해서 간접적으로


접근할때 사용되는 연산자이기 때문에 간접 참조 연산자라고도 한다.  


단항 연산자로 *가 사용되면 포인터가 가리키는 메모리 공간의 접근을 의미한다. 


아래 예제에서 *ptr은 변수 num을 가리킨다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void)
{
    int num=10;
    int * ptr;
 
    ptr=#
    printf("포인터 ptr이 가리키는 변수 값: %d \n"*ptr); 
     printf("num에 저장된 값: %d \n\n", num);
 
    *ptr=20;  
    printf("포인터 ptr이 가리키는 변수 값: %d \n"*ptr);
    printf("num에 저장된 값: %d \n\n", num);
 
    (*ptr)++
    printf("포인터 ptr이 가리키는 변수 값: %d \n"*ptr);
    printf("num에 저장된 값: %d \n\n", num);
 
    return 0;
}
cs


1
2
3
4
5
6
7
8
포인터 ptr이 가리키는 변수 값: 10
num에 저장된 값: 10
 
포인터 ptr이 가리키는 변수 값: 20
num에 저장된 값: 20
 
포인터 ptr이 가리키는 변수 값: 21
num에 저장된 값: 21
cs


7행의 *ptr은 ptr에 저장된 주소값의 메모리 공간을 참조하라는 뜻, 즉 변수 num을 참조하라는 뜻이다.


10행은 ptr이 가리키는 변수 num 에 20을 저장하라는 의미이다.


14행은 변수 num의 값을 1증가시키라는 의미이다.  


정리하면 포인터 ptr과 *연산자를 이용해서 진행한 모든 연산의 결과는 변수 num에 그대로 반영이 된다.


즉 *ptr은 변수 num이다. 


3. int형 변수에 주소값을 저장하면 안된다.


주소값 저장은 int형 포인터 변수에 해야한다. 왜냐하면 결론적으로 int 형 변수에 저장 된 주소값만


을 이용해서는 해당 주소의 메모리 공간에 접근이 불가능하다.


아래 예제를 봐보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(void)
{
    int data1;
    char data2;
    double data3;
 
    int * ptr1=&data1;
    char * ptr2=&data2;
    double * ptr3=&data3;
 
    *ptr1=100;
    *ptr2=100;
    *ptr3=100;
 
    printf("data1: %d \n"*ptr1);
    printf("data2: %c \n"*ptr2);
    printf("data3: %f \n"*ptr3);
    
    return 0;
}
cs


1
2
3
data1: 100
data2: d
data3: 100.000000
cs


11행~13행에 100이 동일하게 저장되지만 방식에는 큰차이가 있다. 아래를 보자



우선 int형 포인터 ptr1이 가리키는 대상에 4바이트 메모리 공간의 정수의 형태로 100이 저장됬다.


반면에 doble형 포인터 ptr3이 가리키는 대상에 8바이트 메모리 공간의 실수의 형태로 100.0이 저장됬다.


왜 이렇게 저장 될까?


int형 포인터를 통해서 포인터가 가리키는 변수에 값을 저장할 때는 무조건 4바이트 정수의 형태로 저장된다.


double형 포인터를 통해서 변수에 값을 저장할 때는 8바이트 실수의 형태로 저장이 된다.


즉 포인터의 형은 포인터가 가리키는 메모리 공간의 데이터 저장 및 참조 방식을 결정한다.


정수와 실수의 저장 및 참조방식은 앞서 보았는데 링크를 참고하자.


https://cg-developer.tistory.com/69


결론적으로 int형 변수에 주소값을 저장하면 안된다. int 형 변수에 저장 된 주소값만을 이용해서는 


해당 주소의 메모리 공간에 접근이 불가능하다. 


해당 주소의 메모리 공간에 대한 정보가 없기 때문이다. 



4. 포인터 변수도 변수이기 때문에 값의 변경이 허용된다.


포인터 변수에 저장된 값도 당연히 변경이 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main(void)
{
    int num1=10;
    int num2=20;
 
    int * p1;
    int * p2;
    int * temp;
 
    /* p1은 num1을 p2는 num2를 가리킴 */
    p1=&num1;
    p2=&num2;
 
    printf("p1 참조 값: %d \n"*p1);
    printf("p2 참조 값: %d \n\n"*p2);
 
    /* p1과 p2가 저장하고 있는 값 교체 */
    temp=p1;
    p1=p2;
    p2=temp;
 
    printf("p1 참조 값: %d \n"*p1);
    printf("p2 참조 값: %d \n\n"*p2);
 
    return 0;
}
cs


18~20행 포인터 p1과 p2가 저장하고 있는 주소의 값을 서로 교환했다.

반응형

'BackEnd > C' 카테고리의 다른 글

&연산자가 반환하는것은?  (0) 2019.03.12
잘못된 포인터 사용의 예와 NULL 포인터  (0) 2019.03.12
포인터 변수 선언  (0) 2019.03.12
포인터와 메모리  (0) 2019.03.11
포인터  (0) 2019.03.11