티스토리 뷰

728x90
반응형

1. Void포인터에 대해서

Void포인터는 한줄로 정리하면 "대상체가 정해져 있지 않은 포인터" 이다.

 

대상체가 정해져 있지않기 때문에 어떠한 Type의 변수도 포인팅 할 수 있다.

 

하지만 역참조로 포인팅 하는 값을 읽을려면, 대상체의 크기를 알지 못하기 때문에 문제가 된다.

#include <stdio.h>
#include <stdlib.h>

int main(){    
    int a = 5;
    void *temp;
    //정상적으로 void pointer에 다른 type의 변수를 할당할 수 있다.
    temp = &a;    
    //하지만 역참조연산자로 void pointer가 가리키고 있는
    //데이터를 읽을 경우 에러가 발생한다.
    //대상체의 정보가 없기 때문
    printf("%d", *temp);
    /*
    error: 'void*' is not a pointer-to-object type
   12 |     printf("%d", *temp);
      |                  ^~~~~
    */
}

 

2. 포인터는 무엇을 가지고 있는가?

포인터는 기본적으로 주소값을 갖는다. 하지만 주소값만 가지고 있는것은 아니다.

 

포인터는 자신이 가리키고 있는 변수(또는 구조체)의 주소값 + 대상체의 크기 정보를 가지고 있다.

block 하나당 4byte일때, double pointer이기 때문에 다음 위치는 1block 을 넘기고 다음 block이다

 

void 포인터는 주소값은 가지고 있으니 어떠한 변수던 포인팅을 할 수 있지다. 하지만 읽을 대상체의 크기정보가 없는 상태이기 때문에 역참조로 읽을 수가 없다.

 

따라서 포인터변수 자체에 정수값을 할당하는것은 불가능하다.

#include <stdio.h>
#include <stdlib.h>

int main(){    
    int a = 5;
    int *temp;
    temp = 0x76541;    
    /*
    error: invalid conversion from 'int' to 'int*' [-fpermissive]
    7 |     temp = 0x76541;
      |            ^~~~~~~
      |            |
      |            int
    */
    printf("%d", *temp);
}

하지만, 대상체가 정해진 pointer의 경우 정수연산이 가능하다

 

3. malloc후 type casting을 하는 이유

malloc은 사용 가능한 메모리영역을 확보한 뒤, 이 영역(buff)을 void 포인터 형태로 반환해 준다.

 

즉, 포인터가 가리키고 있는 buff라는 영역에 Data를 쓸 수 있게 해주는 것이다.

 

하지만 반환해주는 포인터의 대상체 정보가 void이기 때문에 바로 사용이 불가능하고, type casting을 통해서 대상체 정보를 명시해 주는 것이다.

 

4. Array와 pointer는 같은가?

학부때까지 나도 같은 줄 알았다. 하지만 다르다.

 

pointer는 pointer 변수 자체가 메모리를 할당받는 반면 array는 array[0]의 주소값이고, 변수 자체는 메모리를 할당받지 않는다.

 

때문에 *(++pointer) 와 같은 연산은 *pointer = *pointer + 1로 정상적으로 연산이 가능하지만

 

array의 경우 ++array나 array = array +1 를 할 경우 에러가 발생한다.

 

5. 2차원 배열을 가리키는 포인터와 포인터를 가진 2차원 배열

int *ptr[5] : 정수포인터 5개를 가진 배열을 선언한 것.(포인터를 Element로 갖는 배열)

 

int (*ptr)[5] : int[5]를 대상체로 갖는 포인터를 의미한다. (이걸 배열포인터 라고 한다더라)

 

위와같은 배열을 대상체로 갖는 포인터를 malloc하기 위해서는 아래와같이 사용해야 한다.

#include <stdio.h>
#include <stdlib.h>

void test_foo(int (*test_var)[]){
    printf("in foo");
}

int main(){	
    int row = 20;    
    const int col = 5;    
    int (*ptr)[col];    
    ptr = (int(*)[col])malloc(sizeof(int)*col*row);
    for (int i = 0; i<row; i++){
    	printf("%p\n", *(ptr+i));
    }
    test_foo(ptr);
}
/*
0x561c30fb42a0
0x561c30fb42b4
0x561c30fb42c8
...
0x561c30fb43f4
0x561c30fb4408
0x561c30fb441c
in foo
==> 포인터의 증감 연산마다 4*5 = 20씩 주소값이 증가하는 것을 확인할 수 있다.
*/

 

6. 문자열 포인터와 문자열 배열은 다르다.

문자열을 'string'가 아니라, "string"를 사용해서 만든다.

이때 "string"으로 생성할 경우, 해당 문자열의 생성과 동시에 문자열의 주소를 반환한다.

때문에 문자열 포인터 선언과 동시에 할당이 가능하다.

문자열 포인터 : 문자열 "상수"를 가리키는 포인터(문자열 배열을 포인팅 하는것과 다르다)

문자열 배열 : 문자 하나를 배열 element로 갖는 배열

728x90
반응형

'C언어 잡기술 > C' 카테고리의 다른 글

C언어 배열에 대해사  (0) 2022.07.18
malloc()에 대해서  (0) 2022.03.13
alloc()에 대해서  (0) 2021.12.27
getchar()에 대해서  (0) 2021.12.26
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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 27 28
29 30
글 보관함