Aujourd'hui, quand je lisais le code des autres, j'ai vu quelque chose comme void *func(void* i);
, qu'est-ce que ça faitvoid*
que signifie ici pour le nom de la fonction et pour le type de variable, respectivement?
De plus, quand devons-nous utiliser ce type de pointeur et comment l'utiliser?
malloc
etcalloc
. La page de manuel continue en disant: "... renvoie un pointeur vers la mémoire allouée, qui est correctement alignée pour tout type de données intégré."Réponses:
Un pointeur vers
void
est un type de pointeur "générique". Avoid *
peut être converti en tout autre type de pointeur sans conversion explicite. Vous ne pouvez pas déréférencer unvoid *
ou faire de l'arithmétique de pointeur avec lui; vous devez d'abord le convertir en pointeur vers un type de données complet.void *
est souvent utilisé dans les endroits où vous devez pouvoir travailler avec différents types de pointeurs dans le même code. Un exemple couramment cité est la fonction de bibliothèqueqsort
:base
est l'adresse d'un tableau,nmemb
est le nombre d'éléments dans le tableau,size
est la taille de chaque élément etcompar
est un pointeur vers une fonction qui compare deux éléments du tableau. Il s'appelle ainsi:Les expressions du tableau
iArr
,dArr
etlArr
sont convertis implicitement des types de tableau à des types de pointeur dans l'appel de fonction, et chacun est implicitement converti de « pointeur versint
/double
/long
» à « pointeurvoid
».Les fonctions de comparaison ressembleraient à quelque chose comme:
En acceptant
void *
,qsort
peut travailler avec des tableaux de tout type.L'inconvénient de l'utilisation
void *
est que vous jetez la sécurité de type par la fenêtre et dans le trafic venant en sens inverse. Rien ne vous empêche d'utiliser la mauvaise routine de comparaison:compareInt
s'attend à ce que ses arguments pointent versint
s, mais travaille en fait avec l'double
art. Il n'y a aucun moyen d'attraper ce problème au moment de la compilation; vous vous retrouverez juste avec un tableau mal trié.la source
void*
puisse être converti en un pointeur de fonction. Mais pour les pointeurs de données, ce que vous avez dit est valable.L'utilisation d'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
cela signifie que vous pouvez l'appeler de plusieurs façons, par exemple
la source
C est remarquable à cet égard. On peut dire que le
void
néantvoid*
est tout (peut être tout).C'est juste ce minuscule
*
qui fait la différence.René l'a signalé. A
void *
est un pointeur vers un emplacement. Ce qu'il y a comment «interpréter» est laissé à 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 des bibliothèques de structures de données générales. Il est traité de manière très détaillée dans "Interfaces C et implémentations".
Je vous suggère de lire le chapitre complet et d'essayer de comprendre le concept d'un pointeur pour "l'obtenir".
la source
est un «pointeur vers la mémoire sans hypothèse sur le type de stockage». Vous pouvez utiliser, par exemple, si vous voulez passer un argument à la fonction et cet argument peut être de plusieurs types et en fonction, vous gérerez chaque type.
la source
Vous pouvez consulter cet article sur les pointeurs http://www.cplusplus.com/doc/tutorial/pointers/ et lire le chapitre: void pointers .
Cela fonctionne également pour le langage C.
la source
Un pointeur void est appelé pointeur générique. Je voudrais expliquer avec un exemple de scénario pthread.
La fonction thread aura le prototype comme
Les concepteurs de l'API pthread ont pris en compte l'argument et les valeurs de retour de la fonction de thread. Si ces éléments sont rendus génériques, nous pouvons taper cast to void * lors de l'envoi en argument. de même, la valeur de retour peut être récupérée à partir de void * (mais je n'ai jamais utilisé les valeurs de retour de la fonction de thread).
la source
pthread_exit(NULL);
plutôtreturn 0;
qu'à la fin de main?a
void*
est un pointeur, mais le type de ce qu'il pointe n'est pas spécifié. Lorsque vous passez un pointeur void à une fonction, vous devez savoir quel était son type afin de le renvoyer à ce type correct plus tard dans la fonction pour l'utiliser. Vous verrez des exemplespthreads
qui utilisent des fonctions avec exactement le prototype de votre exemple qui sont utilisées comme fonction de thread. Vous pouvez ensuite utiliser l'void*
argument comme pointeur vers un type de données générique de votre choix, puis le renvoyer vers ce type pour l'utiliser dans votre fonction de thread. Vous devez être prudent lorsque vous utilisez des pointeurs vides, car à moins que vous ne reveniez à un pointeur de son vrai type, vous pouvez vous retrouver avec toutes sortes de problèmes.la source
La norme C11 (n1570) §6.2.2.3 al1 p55 dit:
Vous pouvez utiliser ce pointeur générique pour stocker un pointeur sur n'importe quel type d'objet, mais vous ne pouvez pas utiliser les opérations arithmétiques habituelles avec lui et vous ne pouvez pas le déférer.
la source
La fonction prend un pointeur vers un type arbitraire et en renvoie un.
la source
cela signifie pointeur que vous pouvez utiliser ce lien pour obtenir plus d'informations sur le pointeur http://www.cprogramming.com/tutorial/c/lesson6.html
la source