2010-06-02 15 views
19

He estado tratando de descubrir por qué C++ me está volviendo loco escribiendo NULL. De repente, me golpea el otro día; Estuve escribiendo null (minúsculas) en Java durante años. Ahora, de repente estoy programando en C++ y ese pequeño pedazo de memoria muscular me está volviendo loco.¿Cuál es la diferencia entre NULL en C++ y null en Java?

Wikiperipatetic define C++ NULL como parte de la stddef:

Una macro que se expande a un puntero nulo constante. Se puede definir como ((void *) 0), 0 o 0L según el compilador y el idioma.

documentos de sol me dice esto acerca de Java "nula literal":

El tipo nulo tiene un valor, la referencia nula , representada por el literal nula, que está formado por ASCII caracteres . Un literal nulo siempre es del tipo nulo.

Todo esto es muy agradable. Sé lo que es una referencia de puntero nulo y gracias por las notas del compilador. Ahora estoy un poco borroso en la idea de un literal en Java, por lo que he leído en ...

Un literal es el código fuente representación de un valor fijo; literales están representados directamente en su código sin requerir el cómputo .

También hay un nulo literal literal que se puede utilizar como un valor para cualquier tipo de referencia . null se puede asignar a cualquier variable, excepto las variables de tipos primitivos. Hay poco que puede hacer con un valor nulo más allá de probando su presencia. Por lo tanto, null se usa a menudo en programas como un marcador para indicar que algún objeto es no disponible.

Bien, entonces creo que lo entiendo ahora. En C++, NULL es una macro que, cuando se compila, se evalúa como la constante de puntero nulo. En Java, null es un valor fijo que cualquier no primitivo puede ser asignado también; ideal para probar en un práctico if statement.

Java no tiene punteros, por lo que puedo ver por qué mantienen nulo un valor simple en lugar de algo sofisticado. ¿Pero por qué decidió Java cambiar las mayúsculas NULL a null?

Además, ¿me falta algo aquí?

+7

"Java no tiene punteros". En realidad, Java * solo * tiene punteros. –

+1

Excepto para los tipos básicos =) –

+1

'((void *) 0)' no es una definición válida de 'NULL' en C++. –

Respuesta

20

Java's null es más parecido a C++ 0x nullptr. NULL en C++ es solo 0 y puede terminar resolviendo en int en lugar de un puntero como lo desearía. Considere:


void f(int); 
void f(char*); 

... 

f(NULL); // which f()? 

C++ 0x tiene nullptr, que soluciona ese problema, pero todavía no va a ser totalmente equivalente a nulo de Java. Son solo idiomas diferentes.

Ah, y otra diferencia es que Java no tiene punteros (o eso dice). En Java puedes legítimamente asignar null a una referencia, en C++ no puedes hacer eso sin haber usado una construcción mal formada. Es cierto que Java sería inútil sin esta habilidad, pero definitivamente es otra diferencia importante.

+4

Las referencias de Java tienen algunas de las propiedades de los punteros de C++ y algunas de las propiedades de las referencias de C++, por lo que es difícil compararlas directamente. –

+2

No, Java 'null' no tiene ninguna similitud con C++' nullptr' simplemente porque Java no tiene punteros, y 'nullptr' de C++ es estrictamente específico del puntero. – AnT

+0

@Tyler: me parece que son más como punteros que referencias por el motivo exacto de que pueden ser nulos. Realmente, la única diferencia entre java refs y C++ ptrs es que no se pueden hacer cálculos matemáticos sobre ellos. Por supuesto, AFAIK Java en realidad no los trata como tipos diferentes en absoluto, referencia o puntero, mientras que C++ sí lo hace. En realidad, los dos idiomas son apenas similares en absoluto. –

23
  • NULL es un identificador directiva preprocesador, según la convención, los debería ser todos los casquillos.

  • null es una Litteral idioma que representa un valor constante y debe de acuerdo con la convención ser todo inferior (al igual que true o false).

+3

Bien conocido y buena respuesta. Ahora, ¿alguna idea de por qué tienen esta convención? Sabes que tenían que estar sentados alrededor de una mesa hablando de verdadero/falso/nulo y pensando ... "hmm, estamos cambiando la nulidad sobre ellos ..." – Stephano

+2

@Stephano Probablemente no se quedaron sentados hablando de eso. "verdadero" y "falso" son todos minúsculos en C++, también. Es una convención bastante común. Una vez que Java decidió que el concepto de "ningún objeto aquí" era una constante incorporada, tenía que seguir la convención. Por lo tanto, "nulo". – moswald

+2

No se puede pensar en ninguna buena respuesta, excepto que todas las palabras clave son minúsculas. Tal vez simplemente querían enfatizar que no era una macro de ningún tipo, y en realidad parte de la especificación del lenguaje. Para ser sincero, no creo que lo hayan considerado un "cambio" de C++ NULL. – aioobe

2

Uso 0 en lugar de NULL.

De "El lenguaje de programación C++" libro del creador del lenguaje, Bjarne Stroustrup:

En C, que ha sido popular para definir una macro NULL para representar el puntero nulo. Debido a la comprobación de tipo más estricta de C++, el uso de simple 0, en lugar de cualquier macro NULL sugerida, conduce a menos problemas. Si cree que debe definir NULL, use const int NULL = 0;

+0

Guau, muy interesante. Entonces puedo decir algo como: (clase) Nodo n = 0; ? – Stephano

+0

Tendría que ser Node * n = 0, porque 0 es un puntero (nulo). En otras palabras, dado que ningún objeto puede tener una dirección en la memoria 0, 0 en ese caso indicaría que el puntero apunta a ninguna instancia de la clase Node. De lo contrario, parece que intentas convertir un nodo en un número entero. – metaliving

+1

Derecha, C++ NULL es 0, mientras que C NULL es más frecuente (nulo *) 0. –

1

En C++ NULL es una macro que, cuando compilado, define el puntero nulo constante.

Aquí es donde lo entendiste mal. En C++, NULL es 0 y nada más. Tanto los punteros como los enteros pueden ser NULL.

En java, por el contrario, null es un puntero nulo, lo que significa que solo los objetos pueden ser nulos.

+0

No diría que está mal. 'NULL' es una macro que evalúa la constante de puntero nulo' 0'. No * define * el contexto del puntero nulo, pero creo que es solo una cuestión de elección ambigua de palabras. –

+0

Esa fue una mala elección de palabra. Lo cambié a "evalúa a". – Stephano

+1

@ambos comentarios: este póster es correcto y es importante tenerlo en cuenta. NULL no es una constante de puntero, es una constante integral. Resulta que el valor que NULL es, 0, también se evalúa como un puntero nulo cuando se usa en el contexto de un valor de puntero. Como menciono en mi propia publicación, NULL se resolverá en entero antes del puntero porque eso es lo que realmente es. –

0

Bueno, no sé POR QUÉ java decidió cambiar NULL a nulo, sin embargo, en mayúsculas es más difícil escribir (al menos en mi consideración). Pero probablemente siempre puedas preguntarle al sol :-P. De todos modos, decir que java no tiene punteros no es completamente cierto, porque las referencias normales en java o C# o los gustos funcionan más como punteros que como referencias en C++. Por ejemplo, en C++ una referencia no puede ser NULL, pero sí una referencia en java. Y una referencia en C++ no puede cambiar a qué variable apunta (podría estar equivocado en este punto), pero la referencia java sí puede.

2

No, casi lo tiene. En C++, un puntero nulo es cualquier valor cero literal que se asigna a un puntero. NULL es solo una macro para 0, por lo que ptr = 0 y ptr = NULL son idénticos. Está incluido solo por conveniencia/legibilidad. La razón por la que está en mayúscula es porque existe una convención de larga data en C y C++ de que los nombres de las macros deberían estar en mayúsculas.

En Java, null es un literal incorporado, y como no es una macro (y Java no tiene ningún concepto de una macro de todos modos), no hay una razón convincente para hacerlo en mayúscula.

6

Respecto a su última pregunta, no estoy seguro de cuál es la razón de diseño detrás de la null minúscula, pero creo que el objetivo era hacer que null sea literal (como verdadero o falso) en lugar de constante.

Las palabras clave en java generalmente se escriben en minúsculas, por lo que se denominan literales. Las constantes (como Integer.MAX_VALUE) son típicamente mayúsculas.

+0

+1 También una buena respuesta. Tuve que buscar un montón de constantes, pero parece que son mayúsculas. Punto interesante – Stephano

+5

Como comentario, me gustaría señalar que C no tenía 'true' o' false', pero los archivos de cabecera normalmente '#define TRUE 1' y' #define FALSE 0'. El C 'NULL' se ajusta a este patrón. –

1

Java no tiene punteros, como usted mismo dijo, razón por la cual el concepto de "nulo" es completamente incomparable entre Java y C++.

Su pregunta tiene tanto sentido como "¿cuál es la diferencia entre un ángulo y una manzana", es decir, no se puede responder de ninguna otra manera además de lo obvio: NULL en C++ y null en Java son dos totalmente y conceptos completamente no relacionados.

Java nunca se "decidió" cambiar todas las tapas NULL a null, porque, una vez más, de Java null no tiene relación alguna con C++ 's NULL.

+2

Desde otro punto de vista, Java es principalmente punteros, y por lo tanto los conceptos son muy cercanos. –

+0

Andrey: Eso es estrictamente cierto, pero prácticamente falso. Tiene razón en que a Java le faltan punteros, como tal, pero sus referencias son muy parecidas a los punteros C/C++. –

0

Los apuntadores son básicamente direcciones de memoria. Y solo hay una dirección de memoria conocida y establecida, 0. La C++ NULL está en mayúscula porque es una macro de preprocesador y siempre están en mayúsculas por convención. El concepto de puntero se asigna directamente al concepto de un espacio de direcciones en el hardware.

Java utiliza referencias y tiene su propia forma interna de representarlas. Hay una referencia bien conocida, nula. Está en minúscula porque es básicamente otro símbolo, aunque se refiere a un valor literal. No creo que hayan "cambiado" nada de C a Java. Creo que solo querían el concepto nulo, así que lo llamaron "nulo".

En ambos casos, el nulo permite que una función devuelva información adicional. puede devolver la dirección del resultado y el hecho de que tal vez la operación no fue exitosa.

+1

El uso de 0 para el puntero nulo en C y C++ no se basa en la idea de que la ubicación de la memoria 0 sea especial, aunque así es como generalmente se implementa. Una integral constante 0 se convertirá en la constante de puntero nulo. –

+0

No digo que la ubicación de la memoria 0 sea especial, solo que es conocida y usada como una convención para decir que el puntero no es una dirección válida. – Vagrant

2

La palabra clave Java null se usa para identificar una variable que no hace referencia a ningún objeto. La palabra clave null no se puede asignar a una variable que se declara con un tipo de datos primitivo. El valor C++ NULL es una constante que se define como 0.

Cuestiones relacionadas