À quoi sert NIL pour représenter des nœuds nuls?

17

Dans mon cours sur les algorithmes et les structures de données , les professeurs, les diapositives et le livre ( Introduction aux algorithmes, 3e édition ) ont utilisé le mot NILpour désigner par exemple un enfant d'un nœud (dans un arbre) qui n'existe pas.

Une fois, pendant une conférence, au lieu de dire NIL, mon camarade de classe a dit null, et le professeur l'a corrigé, et je ne comprends pas pourquoi les professeurs mettent l'accent sur ce mot.

Y a-t-il une raison pour laquelle les gens utilisent le mot NILau lieu de null, ou none, ou tout autre mot? A NILune signification particulière que les autres n'ont pas? Y a-t-il une raison historique?

Notez que j'ai également vu quelques endroits sur le Web où, par exemple, le mot a nullété utilisé à la place NIL, mais généralement ce dernier est utilisé.

nbro
la source

Réponses:

25

En ce qui me concerne, null, nil, noneet nothingsont des noms communs pour le même concept: une valeur qui représente « l' absence d'une valeur », et qui est présent dans de nombreux types différents (appelés types nullables ). Cette valeur est généralement utilisée lorsqu'une valeur est normalement présente, mais peut être omise, par exemple un paramètre facultatif. Différents langages de programmation implémentent cela différemment, et certains langages peuvent ne pas avoir un tel concept. Dans les langues avec des pointeurs, c'est un pointeur nul . Dans de nombreux langages orientés objet, null n'est pas un objet: appeler une méthode dessus est une erreur. Pour donner quelques exemples:

  • En Lisp, nilest couramment utilisé pour représenter l'absence de valeur. Contrairement à la plupart des autres langues, nila une structure - c'est un symbole dont le nom est "NIL". C'est aussi la liste vide (car une liste doit être une cellule contre, mais parfois il n'y a pas de cellule contre car la liste est vide). Qu'il soit implémenté par un pointeur nul sous le capot ou comme symbole comme un autre, cela dépend de l'implémentation.
  • En Pascal, nilest une valeur de pointeur (valide dans n'importe quel type de pointeur) qui ne peut pas être déréférencée.
  • En C et C ++, tout type de pointeur inclut une NULLvaleur distincte de tout pointeur vers un objet valide.
  • Dans Smalltalk, nilest un objet sans méthode définie.
  • En Java et en C #, nullest une valeur de n'importe quel type d'objet. Toute tentative d'accès à un champ ou une méthode de nulldéclenche une exception.
  • En Perl, undefest distinct de toute autre valeur scalaire et utilisé dans tout le langage et la bibliothèque pour indiquer l'absence d'une valeur "réelle".
  • En Python, Noneest distinct de toute autre valeur et utilisé dans le langage et la bibliothèque pour indiquer l'absence d'une valeur «réelle».
  • En ML (SML, OCaml), Noneest une valeur de tout type dans le schéma de types 'a option, qui contient Noneet Some xpour tout xtype 'a.
  • Dans Haskell, le concept similaire utilise les noms Nothinget Just xles valeurs et Maybe ale type.

Dans les présentations d'algorithmes, le nom utilisé a tendance à provenir de l'arrière-plan du présentateur ou du langage utilisé dans les exemples de code.

NULLnjel

Il est possible que votre professeur veuille utiliser le mot nullpour une constante de pointeur nul dans le langage de programmation utilisé dans le cours (Java ou C #?), Et NILpour dénoter l'absence de nœud dans certaines structures de données, qui peuvent ou non être implémentées comme une constante de pointeur nul (par exemple, comme vu ci-dessus, en Lisp, NILn'est souvent pas implémenté comme un pointeur nul). Cette distinction serait pertinente lors de l'examen des techniques de mise en œuvre des structures de données. Lorsque nous discutons des structures de données elles-mêmes, le concept de constante de pointeur nul n'est pas pertinent, seul le concept de valeur non égale à aucune autre valeur importe.

Il n'y a pas de schéma de dénomination standard. Un autre conférencier ou manuel pourrait utiliser des noms différents.

Gilles 'SO- arrête d'être méchant'
la source
Deux autres exemples. L'objectif C a à la fois NULL(pour la compatibilité C) et nil; appeler des méthodes nilest un no-op. JavaScript a à la fois null(une valeur ne représentant rien) et undefined(la valeur n'est même pas définie).
200_success
1
"Dans les langages orientés objet, null n'est pas un objet: appeler une méthode dessus est une erreur." - Ce n'est pas vrai pour toutes les langues, y compris certaines des langues que vous avez répertoriées. En Ruby et Smalltalk, nilest un objet comme un autre, c'est une instance de NilClass, il n'y a pas d'autre concept de "null-ness", et en particulier, il n'y a pas de pointeur nul. En Scala, Nilest très différent de null, nullest un peu comme un pointeur nul, cependant, il a en fait un type ( Null), Nilest un vieil objet ordinaire, l'instance singleton de la EmptyListclasse si vous voulez, et il y a aussi ...
Jörg W Mittag
1
NothingQui est le type inférieur et n'a pas d'instance, et Unitqui est le type de sous-programmes qui ne renvoient pas de valeur et qui a l'instance singleton (). nullporte en quelque sorte avec elle la notion de "pointeur nul" ou de "référence nulle", non pas parce que c'est en quelque sorte inhérent au terme mais simplement à cause de l'omniprésence de langages comme C, C ++, D, Java, C #, qui l'utilisent dans ce manière. NILne porte pas cette connotation, même si elle est effectivement utilisée de cette façon, par exemple en Pascal, Modula-2 et Oberon. Dans Ruby, nila de nombreuses méthodes utiles: nil.to_i # => 0, nil.to_s # => '', ...
Jörg W Mittag
1
... nil.to_a # => [], nil.to_h # => {}, nil.to_f # => 0.0, nil.inspect # => 'nil'et ainsi de suite. Vous pouvez voir la liste complète ici .
Jörg W Mittag
3

Je crois que la raison de l'utilisation de zéro et de nul est que le premier est principalement un substantif et le second principalement un adjectif (j'ai vérifié sur le Web et dans mon dictionnaire papier: American Heritage 1992).

En ce qui concerne le sens et l'histoire, NIL est une contraction du latin "nihil" qui signifie "rien".

À ma connaissance, l'utilisation du nom nilpour désigner un pointeur nul a été introduite avec le langage de programmation Lisp (1958).

Un pointeur nul est une valeur de pointeur qui est censée pointer vers rien et ne doit donc pas être déréférencé. Dans la plupart des cas, les pointeurs sont simplement des adresses mémoire. Toute variable (c'est-à-dire n'importe quel emplacement) destinée à contenir un tel pointeur contiendra toujours une configuration de bits, et toute configuration de ce type peut être lue comme une adresse mémoire. Par conséquent, il arrive souvent que la valeur nilsoit l'adresse d'une zone de mémoire interdite au programme, provoquant ainsi une certaine forme d'échec (éventuellement une interruption) si le programme tente de déréférencer nil, ce qui ne peut être qu'une erreur.

Avoir une valeur standard unique prédéfinie pour jouer ce rôle est essentiel dans les langages utilisant explicitement des pointeurs, car il est important de pouvoir tester si un pointeur pointe ou non vers un emplacement mémoire. Typiquement, en Lisp, une liste était construite comme une succession de paires "contre" contenant un pointeur "voiture" vers un élément de la liste et un pointeur "cdr" vers la paire suivante. Dans la dernière paire de la liste, le deuxième pointeur était nil.

Cela correspond à la définition récursive d'une liste en tant que liste vide ou élément de liste concaténé à une liste. Par conséquent, une liste sans élément était représentée par nil. Cette liste vide se trouve être l'identité du monoïde de la liste.

Puisque les listes peuvent être utilisées pour représenter des ensembles, l'ensemble vide peut dans ce cas également être représenté par nil.

Ainsi nilétait historiquement une valeur de pointeur spécial, mais il est venu à être compris comme une valeur d'identité spéciale pour d' autres domaines plus abstraits, comme les listes ou ensembles.

Un pointeur égal à nilétait un pointeur nul, null étant un adjectif plutôt qu'un substantif (c'est-à-dire un substantif).

L'utilisation coordonnée des deux mots, comme adjectif et nom est tout à fait cohérente avec d'autres pratiques. Le qualificatif null est souvent utilisé pour le zéro d'une structure algébrique, comme l'identité d'un monoïde: l' élément nul . Les listes forment un monoïde , où la valeur nulle est l'identité. Il en va de même pour les ensembles (bien qu'ils forment une algèbre avec de nombreuses autres propriétés). On dit de même qu'un entier est nul quand il est nul.

Il existe de nombreuses variantes sur l'utilisation de ces mots et d'autres, comme aucun, selon les auteurs et les particularités des langages de programmation.

Les deux connotations principales sont , comme expliqué ci-dessus

  • comme une "valeur indéfinie" standard, représentant en fait l'absence de toute valeur utilisable.

  • comme valeur d'identité d'un domaine

Cela montre qu'il n'est pas tout à fait exact d'affirmer que NIL est " une valeur qui représente" l'absence de valeur ", comme l'a fait Gilles dans la réponse acceptée . Cela dépend de la langue et de ses usages. Le langage de programmation LISP a probablement introduit NIL dans la terminologie de programmation il y a 55 ans. Dans LISP, NILest la liste vide, et peut être notée de manière équivalente ()qui est la représentation naturelle de la liste vide.Il ne représente pas l'absence de valeur. Il est parfois utilisé comme espace réservé pour les valeurs manquantes, bien que cela soit souvent à éviter précisément parce que la liste vide est une valeur. Ce qui représente une valeur manquante dans une structure dans n'importe quel objet arbitraire, choisi par le programmeur, qui ne peut pas être confondu avec des valeurs acceptables.

Les deux concepts sont assez différents, même si nous avons montré ci-dessus qu'ils peuvent être liés. Il pourrait être intéressant d'avoir un mode taxonomie détaillé de l'utilisation de la terminologie énumérée par Gilles'answer, pour voir si les usages de chacun de ces mots sont davantage orientés vers une connotation ou l'autre.

Les noms ne sont rien de plus que ce qu'ils sont censés signifier dans un contexte donné, par celui qui définit le discours. Certaines utilisations sont plus courantes, plus naturelles ou plus cohérentes, mais il faut toujours vérifier les définitions et s'assurer de la signification voulue dans chaque contexte. Et il ne faut pas toujours s'attendre à ce que la terminologie ait été choisie avec goût ou consistance.

babou
la source
0

NIL est un objet avec une valeur qui indique au programmeur que l'objet n'est pas valide. C'est particulièrement utile en C ++ où NULL est défini comme 0. Si vous dé-référencez NULL en C ++, vous obtenez un comportement indéfini. Si vous dé-référencez NIL (un pointeur vers un objet vide que vous avez défini), vous obtenez un objet dont vous pouvez dire qu'il est au-delà de la fin de votre structure de données. Il est idéal pour prévenir les échecs de programmes catastrophiques et détecter les erreurs.

Vous pouvez utiliser NIL dans des cas tels que des listes à double liaison, que ce soit le début et la fin de la liste pour garder une trace de la tête et de la queue, et assurez-vous que les pointeurs -> suivant et -> précédent ne dé-référencent jamais NULL.

abastion
la source
Pour autant que je puisse voir, c'est tout simplement incorrect. Il n'y a pas de "NIL" en C ++ .
David Richerby
1
Je pense que vous avez mal interprété ma réponse. Le lien que vous avez fourni n'a aucune corrélation avec ma réponse. J'ai proposé que nil soit un objet défini par l'utilisateur, défini par classe, pour pointer vers un objet vide (mais valide) de cette classe.
abastion
La façon dont vous écrivez «NIL est un objet» (c'est moi qui souligne) plutôt que de dire «NIL peut être défini comme un objet» donne l'impression que vous décrivez une fonction du langage, plutôt qu'un style de programmation. Cependant, si votre réponse concerne uniquement un style de programmation, ce n'est pas vraiment un sujet, ici.
David Richerby