204 votes

Que signifie void* et comment l'utiliser ?

Aujourd'hui, en lisant le code d'autres personnes, j'ai vu quelque chose comme void *func(void* i); Qu'est-ce que cela signifie ? void* signifie ici pour le nom de la fonction et pour le type de variable, respectivement ?

En outre, quand avons-nous besoin d'utiliser ce type de pointeur et comment l'utiliser ?

239voto

John Bode Points 33046

Un pointeur vers void est un type de pointeur "générique". A void * peut être converti en n'importe quel autre type de pointeur sans un cast explicite. Vous ne pouvez pas déréférencer un void * ou faire de l'arithmétique de pointeur avec lui ; vous devez d'abord le convertir en un pointeur vers un type de données complet.

void * est souvent utilisé dans les cas où vous devez pouvoir travailler avec différents types de pointeurs dans le même code. Un exemple fréquemment cité est la fonction de bibliothèque qsort :

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

base est l'adresse d'un tableau, nmemb est le nombre d'éléments du tableau, size est la taille de chaque élément, et compar est un pointeur vers une fonction qui compare deux éléments du tableau. Elle est appelée comme suit :

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);

Les expressions du tableau iArr , dArr y lArr sont implicitement convertis de types tableau en types pointeur dans l'appel de la fonction, et chacun est implicitement converti de "pointeur à int / double / long "en "pointeur vers void ".

Les fonctions de comparaison ressembleraient à quelque chose comme :

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;
}

En acceptant void * , qsort peut travailler avec des tableaux de n'importe quel type.

L'inconvénient d'utiliser void * c'est que vous jetez la sécurité de type par la fenêtre et dans la circulation en sens inverse. Il n'y a rien pour vous protéger de l'utilisation d'une mauvaise routine de comparaison :

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

compareInt s'attend à ce que ses arguments pointent vers int mais travaille en fait avec double s. Il n'y a aucun moyen de détecter ce problème au moment de la compilation ; vous vous retrouverez simplement avec un tableau mal trié.

29voto

TheSteve Points 725

Utiliser un void * signifie que la fonction peut prendre un pointeur qui n'a pas besoin d'être d'un type spécifique. Par exemple, dans les fonctions de socket, vous avez

send(void * pData, int nLength)

cela signifie que vous pouvez l'appeler de plusieurs façons, par exemple

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

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

22voto

Friedrich Points 4058

C est remarquable à cet égard. On peut dire void est le néant void* est tout (peut être tout).

C'est juste ce petit * qui fait la différence.

René l'a souligné. A void * est un pointeur vers un emplacement quelconque. Ce qu'il y a à "interpréter" est laissé à l'appréciation de l'utilisateur.

C'est la seule façon d'avoir des types opaques en C. Des exemples très importants peuvent être trouvés, par exemple, dans glib ou dans les bibliothèques de structures de données générales. Il est traité de manière très détaillée dans "C Interfaces and implementations".

Je vous suggère de lire le chapitre complet et d'essayer de comprendre le concept de pointeur pour "comprendre".

9voto

René Kolařík Points 1184
void*

est un "pointeur vers la mémoire sans présumer du type de mémoire stockée". Vous pouvez l'utiliser, par exemple, si vous voulez passer un argument à une fonction et que cet argument peut être de plusieurs types. Dans la fonction, vous traiterez chaque type.

3voto

A.G. Points 942

Vous pouvez consulter cet article sur les pointeurs. http://www.cplusplus.com/doc/tutorial/pointers/ et lire le chapitre : void pointeurs .

Cela fonctionne également pour le langage C.

Le pointeur de type void est un type spécial de pointeur. En C++, void représente l'absence de type, donc les pointeurs void sont des pointeurs qui pointent vers une valeur qui n'a pas de type (et donc également une longueur longueur indéterminée et des propriétés de déréférencement indéterminées).

Cela permet aux pointeurs void de pointer sur n'importe quel type de données, d'une valeur ou un flottant, ou encore une chaîne de caractères. Mais en échange, ils ont une grande limitation : les données qu'ils pointent ne peuvent pas être directement déréférencées (ce qui est logique, puisque nous n'avons pas de type à déréférencer). ), et pour cette raison, nous devrons toujours convertir l'adresse du pointeur void en un autre pointeur. dans le pointeur void vers un autre type de pointeur qui pointe vers un type de données concret avant de le déréférencer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X