web-dev-qa-db-fra.com

Qu'est-ce qu'un pointeur vide et qu'est-ce qu'un pointeur nul?

Je passais donc par quelques questions d'entrevue et je suis tombé sur ne sur les pointeurs nuls et nuls , qui prétend:

un pointeur sans type de retour est appelé pointeur nul. Il peut s'agir de n'importe quel type de données.

Cela m'a complètement dérouté! Il semble nul et non avenu pourrait être utilisé de manière interchangeable selon cette question, et je ne pense pas que ce soit correct. J'ai supposé que void était un type de retour et null une valeur. Mais je suis juste une recrue de code et je ne suis pas sûr d'avoir raison.

Veuillez exprimer votre point de vue sur ce qu'est un pointeur nul et un pointeur vide. Je ne cherche pas de différence entre nul et non avenu.

40
Shouvik

Les deux concepts sont orthogonaux:

  1. Un pointeur vide, (void *) est un pointeur brut vers un emplacement mémoire.
  2. Un pointeur nul est un pointeur spécial qui ne pointe vers rien, par définition. Il peut s'agir d'un pointeur vers n'importe quel type, vide ou autre.

Un pointeur vide peut être nul ou non:

void *void_ptr1 = nullptr;
void *void_ptr2 = malloc(42);
void *void_ptr3 = new Foo;               // void * can point to almost anything
void *void_ptr4 = (char*)void_ptr3 + 1;  // even somewhere inside an object

Un pointeur non vide peut également être nul ou non:

Foo *f = nullptr;
Foo *g = new Foo;
46
Marcelo Cantos

Oubliez simplement cette réponse. Une citation de votre lien:

"un pointeur sans type de retour est appelé un pointeur nul."

C'est tellement simple ( [~ # ~] faux [~ # ~] . Le type de retour d'un pointeur ? VRAIMENT? Ceci est une mauvaise source ...

void* est un pointeur universel type car tout type de pointeur (à l'exception du pointeur vers const et/ou volatile) peut être implicitement converti à void*. En d'autres termes, vous pouvez affecter n'importe quel pointeur à une variable de type void*. Un pointeur nul est un pointeur ( valeur 0

30
Armen Tsirunyan

Le type void signifie en général qu'aucune information de type n'est donnée.

Vous devez toujours garder à l'esprit qu'un pointeur transmet deux informations: le type des données pointées (int, double, ...), qui spécifie comment l'interpréter, et adresse des données vers lesquelles il pointe, qui spécifie vous pouvez obtenir la valeur réelle des données pointées.

Les informations de type sont dans le type du pointeur (double*, int*, ...), tandis que l'adresse des données est la valeur réelle contenue dans la variable pointeur.

Ainsi, un pointeur void (void *) est un pointeur qui ne spécifie aucune information de type. Il vous indique où se trouvent les données, mais il ne vous indique pas comment les interpréter. Vous savez qu'à cette adresse, il y a quelque chose, mais vous ne savez pas s'il s'agit d'un int, d'un double ou d'un tableau de vaches volantes. Pour utiliser réellement ces données, vous devez obtenir des informations de type à ce sujet d'une autre manière (par exemple avec un autre paramètre magique), convertir ce pointeur en un type de pointeur normal, puis l'utiliser comme d'habitude.

void * est souvent utilisé en C pour fournir une sorte de support à la programmation générique; voir par exemple la fonction de bibliothèque qsort C.

Un pointeur NULL, à la place, est un pointeur qui ne pointe vers rien. Dans ce cas, les informations de type sur le pointeur en général sont présentes, mais c'est l'adresse des données pointées qui manque. Bien sûr, il est possible d'avoir un void * c'est-à-dire NULL.

Exemple rapide (en supposant que v est déclaré comme double v;):

                         Type information present
             +----------------------+----------------------+
             |          ✔           |          ✘           |
         +---+----------------------+----------------------+
    p  c |   |                      |                      |
 v  o  o | ✔ | double * ptr = &v;   | void * ptr = &v;     |
 a  i  n |   |                      |                      |
 l  n  t +---+----------------------+----------------------+
 i  t  e |   |                      |                      |
 d  e  n | ✘ | double * ptr = NULL; | void * ptr = NULL;   |
    d  t |   |                      |                      |
         +---+----------------------+----------------------+

Anecdote: NULL, au moins dans la norme actuelle, est garanti à 0.

Dans d'autres domaines du langage, void est toujours utilisé pour spécifier le manque de type. L'utiliser comme valeur de retour (remarque: je parle maintenant de void, pas de void *) signifie que la fonction ne renvoie aucune valeur, et le fait d'exprimer une expression à void est un moyen sophistiqué de supprimer une valeur (vous signalez au compilateur et aux autres programmeurs que vous savez que vous n'utilisez pas une certaine valeur).

19
Matteo Italia

S'il vous plaît, dites-nous: quelle est la différence:

  • entre réservoir de gaz et situation sans gaz
  • entre pot de cookies et sans cookies
  • entre le terme "argent" et "poches vides"

Si vous venez avec ces derniers, vous pourrez saisir null vs void * dillema.

12
Daniel Mošmondor

void est un non-type. null est une non-valeur.

8
Nicolas Repiquet

Voici quelques différences en ce qui concerne l'arithmétique des pointeurs:

Cela vient du fait que void est un type incomplet.

void *vp;
vp++;     // error, incomplete type
vp += 2;  // same error

void *p = 0;
p++;      // still same error

int *p = 0;
p++;      // well-formed program, but UB ($5.6/5)
3
Chubsdad

L'article lié est tout simplement faux. Sa première phrase:

un pointeur sans type de retour est appelé pointeur nul

déclenche toutes sortes d'alarmes pour moi. Il s'agit d'une écriture très confuse.

Vous avez presque raison. "Pointer to void" est un type (pas un "type de retour"). Les valeurs de tout type peuvent être renvoyées par les fonctions, et donc être le type de retour (de la fonction).

Un pointeur nul est un pointeur qui, quel que soit son type, pointe vers l'objet nul, qui n'est pas un objet valide pouvant être créé. On peut dire qu'un pointeur nul pointe vers "rien".

Un pointeur vers void peut également être nul;

void *nothing = 0;

est un code parfaitement valide, et dit simplement que ce pointeur est capable de pointer un objet non typé, mais pour l'instant ce n'est pas le cas.

2
unwind

le pointeur nul pointe vers 0x000000 (ce qui est incorrect pour accéder au pointeur), tandis que le pointeur vide est un pointeur correct vers un type non spécifié (void *). Cependant, le pointeur vide peut être un pointeur nul, mais le non-référencement du pointeur génère une erreur.

1
Vladimir Ivanov

UNE void *ptr est le pointeur qui peut être utilisé pour pointer tout type de données. Il peut s'agir de int, float, double. Il n'a pas de type de retour qui est initialement un pointeur est créé avec un type de pointeur (ayant une valeur hexadécimale) et nous pouvons affecter ce pointeur à n'importe quel type de données.

Alors que le pointeur nul est le pointeur ayant une valeur NULL comme adresse, le pointeur se voit attribuer une valeur NULL afin qu'il ne puisse pas être utilisé pour accéder à d'autres données que son adresse peut contenir lors de la création. Je pense que c'est une bonne technique de programmation d'affecter un pointeur NULL s'il n'est pas utilisé pour le moment.

1
anurag tiwari