¿Cuál es el propósito de usar NIL para representar nodos nulos?


17

En mi curso de Algoritmos y Estructuras de Datos , profesores, diapositivas y el libro ( Introducción a los Algoritmos, 3ra edición ) han estado usando la palabra NILpara denotar, por ejemplo, un hijo de un nodo (en un árbol) que no existe.

Una vez, durante una conferencia, en lugar de decir NIL , mi compañero de clase dijo null, y el profesor lo corrigió, y no entiendo por qué los profesores enfatizan esta palabra.

¿Hay alguna razón por la cual las personas usan la palabra en NILlugar de null, onone , o cualquier otra palabra? ¿ NILTiene algún significado particular que los demás no tienen? ¿Hay alguna razón histórica?

Tenga en cuenta que también he visto algunos lugares en la web donde, por ejemplo, nullse usó la palabra en lugar de NIL, pero generalmente se usa esta última.

Respuestas:


25

En lo que a mí respecta, null, nil, noney nothingson nombres comunes para el mismo concepto: un valor que representa la “ausencia de un valor”, y que está presente en muchos tipos diferentes (llamados tipos anulables ). Este valor se usa generalmente donde normalmente está presente un valor, pero puede omitirse, por ejemplo, un parámetro opcional. Diferentes lenguajes de programación implementan esto de manera diferente, y algunos lenguajes pueden no tener tal concepto. En idiomas con punteros, es un puntero nulo . En muchos lenguajes orientados a objetos, nulo no es un objeto: llamar a cualquier método es un error. Para dar algunos ejemplos:

  • En Lisp, nilse usa comúnmente para representar la ausencia de un valor. A diferencia de la mayoría de los otros idiomas, niltiene estructura: es un símbolo cuyo nombre es "NIL". También es la lista vacía (porque una lista debe ser una celda de contras, pero a veces no hay una celda de contras porque la lista está vacía). Ya sea implementado por un puntero nulo debajo del capó, o como un símbolo como cualquier otro, depende de la implementación.
  • En Pascal, niles un valor de puntero (válido en cualquier tipo de puntero) que no se puede desreferenciar.
  • En C y C ++, cualquier tipo de puntero incluye un NULLvalor que es distinto de cualquier puntero a un objeto válido.
  • En Smalltalk, niles un objeto sin método definido.
  • En Java y en C #, nulles un valor de cualquier tipo de objeto. Cualquier intento de acceder a un campo o método de nulldesencadena una excepción.
  • En Perl, undefes distinto de cualquier otro valor escalar y se usa en todo el lenguaje y la biblioteca para indicar la ausencia de un valor "real".
  • En Python, Nonees distinto de cualquier otro valor y se utiliza en todo el lenguaje y la biblioteca para indicar la ausencia de un valor "real".
  • En ML (SML, OCaml), Nonees un valor de cualquier tipo en el esquema de tipo 'a option, que contiene Noney Some xpara cualquiera xde los tipos 'a.
  • En Haskell, el concepto similar usa los nombres Nothingy Just xpara los valores y Maybe apara el tipo.

En las presentaciones de algoritmos, el nombre que se usa tiende a provenir del fondo del presentador o del lenguaje que se usa en los ejemplos de código.

NULLnorteyol

Es posible que su profesor quiera usar la palabra nullpara una constante de puntero nulo en el lenguaje de programación utilizado en el curso (Java o C #?), Y NILdenotar la ausencia de un nodo en algunas estructuras de datos, que pueden o no implementarse como una constante de puntero nulo (por ejemplo, como se ve arriba, en Lisp, a NILmenudo no se implementa como un puntero nulo). Esta distinción sería relevante cuando se discutan técnicas de implementación para estructuras de datos. Cuando se discuten las estructuras de datos en sí mismas, el concepto constante de puntero nulo es irrelevante, solo importa el concepto de valor no igual a cualquier otro valor.

No existe un esquema de nomenclatura estándar. Otro profesor o libro de texto podría usar nombres diferentes.


Dos ejemplos más. El objetivo C tiene ambos NULL(para compatibilidad con C) y nil; invocar métodos niles un no-op. JavaScript tiene tanto null(un valor que no representa nada) como undefined(el valor ni siquiera está establecido).
200_success

1
"En los lenguajes orientados a objetos, nulo no es un objeto: llamar a cualquier método es un error". - Esto no es cierto para todos los idiomas, incluidos algunos de los idiomas que enumeró. En Ruby y Smalltalk, niles un objeto como cualquier otro, es una instancia de NilClass, no hay otro concepto de "nulidad" y, en particular, no hay puntero nulo. En Scala, Niles muy distinto de null, nulles algo así como un puntero nulo, sin embargo, en realidad tiene un tipo ( Null), Niles un objeto antiguo normal, la instancia singleton de la EmptyListclase si lo desea, y también hay ...
Jörg W Mittag

1
... Nothingcuál es el tipo de fondo y no tiene instancia, y Unitcuál es el tipo de subrutinas que no devuelve un valor y tiene la instancia de singleton (). nullde alguna manera lleva consigo la noción de "puntero nulo" o "referencia nula", no porque sea de alguna manera inherente al término sino simplemente por la ubicuidad de lenguajes como C, C ++, D, Java, C #, que lo usan en este conducta. NILno lleva esta connotación, aunque en realidad se usa de esa manera, por ejemplo, en Pascal, Modula-2 y Oberon. En Ruby, niltiene muchos métodos útiles: 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', y así sucesivamente. Puedes ver la lista completa aquí .
Jörg W Mittag

3

Creo que la razón del uso de nil y nulo es que el primero es principalmente un sustantivo y el segundo principalmente un adjetivo (lo comprobé en la web y en mi diccionario: American Heritage 1992).

Con respecto al significado y la historia, NIL es una contracción del latín "nihil" que significa "nada".

Que yo sepa, el uso del nombre nilpara denotar un puntero nulo se introdujo con el lenguaje de programación Lisp (1958).

Un puntero nulo es un valor de puntero que se supone que no apunta a nada y, por lo tanto, no debe desreferenciarse. En la mayoría de los casos, los punteros son simplemente direcciones de memoria. Cualquier variable (es decir, cualquier ubicación) que esté destinada a contener dicho puntero siempre contendrá alguna configuración de bits, y dicha configuración puede leerse como una dirección de memoria. Por lo tanto, a menudo es el caso que el valor nilserá la dirección de un área de memoria que está prohibida para el programa, causando alguna forma de falla (posiblemente interrupción) si el programa intenta desreferenciar nil, lo que solo puede ser un error.

Tener un valor estándar predefinido único para desempeñar este papel es esencial en los idiomas que usan punteros explícitamente, ya que es importante poder probar si un puntero apunta realmente a alguna ubicación de memoria, o no. Típicamente, en Lisp, se construyó una lista como una sucesión de pares "contras" que contienen un puntero "auto" a un elemento de la lista y un puntero "cdr" al siguiente par. En el último par de la lista, el segundo puntero era nil.

Esto corresponde a la definición recursiva de una lista como una lista vacía o como un elemento de lista concatenado a una lista. Por lo tanto, una lista sin elemento fue representada por nil. Esta lista vacía es la identidad del monoide de la lista.

Como las listas se pueden usar para representar conjuntos, el conjunto vacío también se puede representar en ese caso mediante nil.

Por nillo tanto , históricamente fue un valor de puntero especial, pero llegó a entenderse como un valor de identidad especial para otros dominios más abstractos, como listas o conjuntos.

Un puntero igual a nilera un puntero nulo, siendo nulo un adjetivo en lugar de un sustantivo (es decir, un sustantivo).

El uso coordinado de ambas palabras, como adjetivo y sustantivo, es bastante consistente con otras prácticas. El calificador nulo se usa a menudo para el cero de una estructura algebraica, como la identidad de un monoide: el elemento nulo . Las listas forman un monoide , donde el valor nulo es la identidad. Lo mismo ocurre con los conjuntos (aunque forman un álgebra con muchas más propiedades). Uno dice de manera similar que un número entero es nulo cuando es cero.

Existen muchas variaciones en el uso de estas palabras y otras, como ninguna, según los autores y las idiosincrasias de los lenguajes de programación.

Las dos connotaciones principales son , como se explicó anteriormente

  • como un "valor indefinido" estándar, que en realidad representa la ausencia de cualquier valor utilizable.

  • como valor de identidad de algún dominio

Esto muestra que no es del todo exacto afirmar que NIL es " un valor que representa la" ausencia de un valor ", como lo hizo Gilles en la respuesta aceptada . Depende del idioma y sus usos. El lenguaje de programación LISP probablemente introdujo NIL en la terminología de programación hace 55 años. En LISP, NILes la lista vacía, y se puede observar de manera equivalente.() cuál es la representación natural de la lista vacía. No representa la ausencia de un valor. A veces se usa como marcador de posición para valores perdidos, aunque eso a menudo se debe evitar precisamente porque la lista vacía es un valor. Lo que representa un valor faltante en una estructura en cualquier objeto arbitrario, elegido por el programador, que no puede confundirse con valores aceptables.

Los dos conceptos son bastante diferentes, a pesar de que hemos demostrado anteriormente que pueden estar relacionados. Puede ser interesante tener una taxonomía de modo detallado del uso de la terminología enumerada por la respuesta de Gilles, para ver si los usos de cada una de estas palabras están orientados más hacia una connotación u otra.

Los nombres no son más de lo que están asignados a significar en un contexto dado, por quien esté definiendo el discurso. Algunos usos son más comunes, más naturales o más consistentes, pero uno siempre debe verificar las definiciones y asegurarse de qué significado se pretendía en cada contexto. Y no siempre se debe esperar que la terminología se haya elegido con gusto o consistencia.


0

NIL es un objeto con un valor que le dice al programador que el objeto no es válido. Es particularmente útil en C ++ donde NULL se define como 0. Si des-referencia NULL en C ++, obtendrá un comportamiento indefinido. Si des-referencia NIL (un puntero a un objeto vacío que definió), obtendrá un objeto que puede ver que está más allá del final de su estructura de datos. Es excelente para prevenir fallas catastróficas del programa y detectar errores.

Puede usar NIL en casos como listas doblemente enlazadas, ya que es el principio y el final de la lista para realizar un seguimiento tanto de la cabeza como de la cola, y asegurarse de que -> siguiente y -> punteros anteriores nunca des-referencian NULL.


Hasta donde puedo ver, esto es simplemente incorrecto. No hay "NIL" en C ++ .
David Richerby

1
Creo que malinterpretaste mi respuesta. El enlace que proporcionó no tiene correlación con mi respuesta. Propuse que nil es un objeto definido por el usuario, definido por clase, para señalar un objeto vacío (pero válido) de esa clase.
abastion

La forma en que escribe "NIL es un objeto" (mi énfasis) en lugar de decir "NIL puede definirse como un objeto" hace que parezca que está describiendo una característica del lenguaje, en lugar de un estilo de programación. Sin embargo, si su respuesta es puramente sobre un estilo de programación, aquí no se trata realmente del tema.
David Richerby
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.