Programing

void * 란 무엇이며 어떻게 사용합니까?

crosscheck 2020. 7. 5. 08:05
반응형

void * 란 무엇이며 어떻게 사용합니까?


오늘 다른 사람들의 코드를 읽을 때와 같은 것을 보았습니다. void *func(void* i);이것은 void*각각 함수 이름과 변수 유형에 대해 무엇을 의미합니까?

또한 언제 이런 종류의 포인터를 사용해야합니까?


에 대한 포인터 void는 "일반적인"포인터 유형입니다. A void *는 명시적인 캐스트없이 다른 포인터 유형으로 변환 될 수 있습니다. a를 역 참조 void *하거나 포인터 산술을 수행 할 수 없습니다 . 먼저 완전한 데이터 유형에 대한 포인터로 변환해야합니다.

void *동일한 코드에서 다른 포인터 유형으로 작업 할 수 있어야하는 곳에서 종종 사용됩니다. 일반적으로 인용되는 한 가지 예는 라이브러리 함수입니다 qsort.

void qsort(void *base, size_t nmemb, size_t size, 
           int (*compar)(const void *, const void *));

base는 배열의 주소, 배열 nmemb의 요소 수, size각 요소의 크기 및 compar배열의 두 요소를 비교하는 함수에 대한 포인터입니다. 다음과 같이 호출됩니다.

int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);

배열 식을 iArr, dArr그리고 lArr암시 함수 호출 포인터 타입으로 배열 형으로 변환되고, 각각의 내재적 "포인터로 변환한다 int/ double/ long"포인터 "를 void".

비교 함수는 다음과 같습니다.

int compareInt(const void *lhs, const void *rhs)
{
  const int *x = lhs;  // convert void * to int * by assignment
  const int *y = rhs;

  if (*x > *y) return 1;
  if (*x == *y) return 0;
  return -1;
}

을 수락 void *하면 qsort모든 유형의 배열로 작업 할 수 있습니다.

사용의 단점은 void *유형 안전을 창 밖으로 나가고 다가오는 트래픽에 버리는 것입니다. 잘못된 비교 루틴을 사용하지 못하도록 보호 할 방법은 없습니다.

qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);

compareInt인수가 ints를 가리키고 있지만 실제로 doubles 와 작업하고 있습니다. 컴파일 타임에이 문제를 잡을 방법이 없습니다. 배열이 잘못 배열되어 있습니다.


void *를 사용하면 함수가 특정 유형일 필요가없는 포인터를 사용할 수 있습니다. 예를 들어, 소켓 함수에서

send(void * pData, int nLength)

예를 들어 여러 가지 방법으로 호출 할 수 있습니다.

char * data = "blah";
send(data, strlen(data));

POINT p;
p.x = 1;
p.y = 2;
send(&p, sizeof(POINT));

이와 관련하여 C가 현저하다. void는 아무것도 없다고 말할 수 있습니다 void *는 모든 것입니다 (모든 것이 될 수 있습니다)

차이를 만드는 것은이 작은 것입니다.

르네가 지적했다. void *는 어떤 위치를 가리키는 포인터입니다. "해석"하는 방법은 사용자에게 있습니다.

C에서 불투명 한 유형을 갖는 유일한 방법입니다. 예를 들어 glib 또는 일반 데이터 구조 라이브러리에서 매우 두드러진 예제를 찾을 수 있습니다. "C 인터페이스 및 구현"에 매우 자세히 설명되어 있습니다.

나는 당신이 완전한 장을 읽고 "얻기"에 대한 포인터의 개념을 이해하려고 노력할 것을 제안합니다.


void*

'어떤 유형이 저장되어 있는지 가정하지 않고 메모리에 대한 포인터'입니다. 예를 들어 함수에 인수를 전달하려는 경우이 인수는 여러 유형이 될 수 있으며 기능상 각 유형을 처리합니다.


You can have a look at this article about pointers http://www.cplusplus.com/doc/tutorial/pointers/ and read the chapter : void pointers.

This also works for C language.

The void type of pointer is a special type of pointer. In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereference properties).

This allows void pointers to point to any data type, from an integer value or a float to a string of characters. But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some other pointer type that points to a concrete data type before dereferencing it.


A void pointer is known as generic pointer. I would like to explain with a sample pthread scenario.

The thread function will have the prototype as

void *(*start_routine)(void*)

The pthread API designers considered the argument and return values of thread function. If those thing are made generic, we can type cast to void* while sending as argument. similarly the return value can be retrieved from void*(But i never used return values from thread function).

void *PrintHello(void *threadid)
{
   long tid;

   // ***Arg sent in main is retrieved   ***
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      //*** t will be type cast to void* and send as argument.
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);   
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }    
   /* Last thing that main() should do */
   pthread_exit(NULL);
}

a void* is a pointer, but the type of what it points to is unspecified. When you pass a void pointer to a function you will need to know what its type was in order to cast it back to that correct type later in the function to use it. You will see examples in pthreads that use functions with exactly the prototype in your example that are used as the thread function. You can then use the void* argument as a pointer to a generic datatype of your choosing and then cast it back to that type to use within your thread function. You need to be careful when using void pointers though as unless you case back to a pointer of its true type you can end up with all sorts of problems.


C11 standard (n1570) §6.2.2.3 al1 p55 says :

A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

You can use this generic pointer to store a pointer to any object type, but you can't use usual arithmetic operations with it and you can't deference it.


The function takes a pointer to an arbitrary type and returns one such.


it means pointer you can use this link to get more info about pointer http://www.cprogramming.com/tutorial/c/lesson6.html


The VOID before function name means that it doesn't return anything. Just doing some stuff. On the other hand VOID as parameter makes it generic function that can accept any type of parameter. But you have to provide the function with the size of the this parameter.

참고URL : https://stackoverflow.com/questions/11626786/what-does-void-mean-and-how-to-use-it

반응형