javascription - ¿Cuál es la diferencia entre NULL, ''/ 0'' y 0
onclick void 0 (11)
¿Cuál es la diferencia entre NULL, ''/ 0'' y 0
El "carácter nulo (NUL)" es el más fácil de descartar. ''/0''
es un carácter literal. En C, se implementa como int
, por lo tanto, es lo mismo que 0, que es de INT_TYPE_SIZE
. En C ++, el literal de caracteres se implementa como char
, que es de 1 byte. Esto suele ser diferente de NULL
o 0
.
A continuación, NULL
es un valor de puntero que especifica que una variable no apunta a ningún espacio de direcciones. Dejando de lado el hecho de que normalmente se implementa como ceros, debe poder expresar el espacio completo de direcciones de la arquitectura. Por lo tanto, en una arquitectura de 32 bits, NULL (probable) es de 4 bytes y en la arquitectura de 64 bits de 8 bytes. Esto depende de la implementación de C.
Finalmente, el 0
literal es de tipo int
, que es de tamaño INT_TYPE_SIZE
. El valor predeterminado de INT_TYPE_SIZE
podría ser diferente según la arquitectura.
Apple escribió:
El modelo de datos de 64 bits utilizado por Mac OS X se conoce como "LP64". Este es el modelo de datos común utilizado por otros sistemas UNIX de 64 bits de Sun y SGI, así como Linux de 64 bits. El modelo de datos LP64 define los tipos primitivos de la siguiente manera:
- los ints son de 32 bits
- largos son de 64 bits
- largos y largos son también de 64 bits
- los punteros son de 64 bits
Wikipedia de 64 bits :
El compilador VC ++ de Microsoft usa el modelo LLP64.
64-bit data models
Data model short int long long long pointers Sample operating systems
LLP64 16 32 32 64 64 Microsoft Win64 (X64/IA64)
LP64 16 32 64 64 64 Most Unix and Unix-like systems (Solaris, Linux, etc.)
ILP64 16 64 64 64 64 HAL
SILP64 64 64 64 64 64 ?
Edición : Añadido más en el carácter literal.
#include <stdio.h>
int main(void) {
printf("%d", sizeof(''/0''));
return 0;
}
El código anterior devuelve 4 en gcc y 1 en g ++.
En C, parece haber diferencias entre varios valores de cero: NULL
, NUL
y 0
.
Sé que el carácter ASCII ''0''
evalúa a 48
o 0x30
.
El puntero NULL
se define generalmente como:
#define NULL 0
O
#define NULL (void *)0
Además, existe el carácter NUL
''/0''
que parece evaluar a 0
también.
¿Hay momentos en que estos tres valores no pueden ser iguales?
¿Esto también es cierto en sistemas de 64 bits?
"NUL" no es 0, pero se refiere al carácter ASCII NUL. Al menos, así es como lo he visto usar. El puntero nulo a menudo se define como 0, pero esto depende del entorno en el que se está ejecutando y de la especificación del sistema operativo o idioma que utilice.
En ANSI C, el puntero nulo se especifica como el valor entero 0. Por lo tanto, cualquier mundo donde eso no sea cierto no es compatible con ANSI C.
(void *) 0 es NULL, y ''/ 0'' representa el final de una cadena.
A one-L NUL, termina una cadena.
Un two-L NULL apunta a ninguna cosa.
Y apostaré un toro de oro.
Que no hay NULLL de tres L.
Los tres definen el significado de cero en un contexto diferente.
- contexto del puntero: se utiliza NULL y significa que el valor del puntero es 0, independientemente de si es de 32 bits o de 64 bits (un caso, 4 bytes, los otros 8 bytes de ceros).
- contexto de cadena: el carácter que representa el dígito cero tiene un valor hexadecimal de 0x30, mientras que el carácter NUL tiene un valor hexadecimal de 0x00 (utilizado para terminar cadenas).
Estos tres son siempre diferentes cuando miras la memoria:
NULL - 0x00000000 or 0x00000000''00000000 (32 vs 64 bit)
NUL - 0x00 or 0x0000 (ascii vs 2byte unicode)
''0'' - 0x20
Espero que esto lo aclare.
No se garantiza que NULL
sea 0; su valor exacto depende de la arquitectura. La mayoría de las arquitecturas principales lo definen como (void*)0
.
''/0''
siempre será igual a 0, porque así se codifica el byte 0 en un literal de carácter.
No recuerdo si los compiladores de C están obligados a usar ASCII; de lo contrario, ''0''
podría no ser igual a 48. Sin embargo, es poco probable que alguna vez encuentre un sistema que use un conjunto de caracteres alternativo como EBCDIC, a menos que esté Trabajando en sistemas muy oscuros.
Los tamaños de los distintos tipos diferirán en los sistemas de 64 bits, pero los valores enteros serán los mismos.
Algunos comentaristas han expresado dudas de que NULL sea igual a 0, pero no sea cero. Aquí hay un programa de ejemplo, junto con la salida esperada en tal sistema:
#include <stdio.h>
int main () {
size_t ii;
int *ptr = NULL;
unsigned long *null_value = (unsigned long *)&ptr;
if (NULL == 0) {
printf ("NULL == 0/n"); }
printf ("NULL = 0x");
for (ii = 0; ii < sizeof (ptr); ii++) {
printf ("%02X", null_value[ii]); }
printf ("/n");
return 0;
}
Ese programa podría imprimir:
NULL == 0
NULL = 0x00000001
Parece que varias personas no entienden cuáles son las diferencias entre NULL, ''/ 0'' y 0. Entonces, para explicar, y en un intento por evitar repetir las cosas dichas antes:
Una expresión constante de tipo int con el valor 0, o una expresión de este tipo, convertida en tipo void * es una constante de puntero nula , que si se convierte en un puntero se convierte en un puntero nulo . El estándar garantiza la comparación desigual entre cualquier puntero y cualquier objeto o función .
NULL es una macro, definida como una constante de puntero nula .
''/ 0'' es una construcción utilizada para representar el carácter nulo , que se utiliza para terminar una cadena.
Un carácter nulo es un byte que tiene todos sus bits establecidos en 0.
Un byte con un valor de 0x00 es, en la tabla ASCII, el carácter especial llamado "NUL" o "NULL". En C, ya que no debe incrustar caracteres de control en su código fuente, esto se representa en cadenas C con un 0 escapado, es decir, "/ 0".
Pero un verdadero NULL no es un valor. Es la ausencia de un valor. Para un puntero, significa que el puntero no tiene nada a lo que apuntar. En una base de datos, significa que no hay ningún valor en un campo (que no es lo mismo que decir que el campo está en blanco, 0 o lleno de espacios).
El valor real que un formato de archivo de base de datos o sistema determinado utiliza para representar un valor NULL no es necesariamente 0x00.
Una buena pieza que me ayuda cuando empiezo con C (Tomado de la Programación Expert C de Linden)
The One ''l'' nul y The Two ''l'' null
Memorice esta pequeña rima para recordar la terminología correcta para los punteros y el ASCII cero:
The one "l" NUL ends an ASCII string,
The two "l" NULL points to no thing.
Apologies to Ogden Nash, but the three "l" nulll means check your spelling.
El carácter ASCII con el patrón de bits de cero se denomina "NUL". El valor de puntero especial que significa que los puntos de puntero en ninguna parte es "NULL". Los dos términos no son intercambiables en significado.
c-faq.com/null/nullor0.html En la lista de preguntas frecuentes de C también se aborda este problema:
Los programadores de C deben entender que
NULL
y0
son intercambiables en contextos de puntero, y que un0
emitido es perfectamente aceptable. Cualquier uso de NULL (en lugar de0
) debe considerarse un recordatorio suave de que hay un puntero involucrado; los programadores no deben depender de ello (ya sea por su propio entendimiento o por el compilador) para distinguir los punteros0
''de los enteros0
'' s.Es solo en contextos de puntero que
NULL
y0
son equivalentes. No se debe usarNULL
cuando se requiere otro tipo de0
, aunque podría funcionar, porque al hacerlo se envía el mensaje de estilo incorrecto. (Además, ANSI permite que la definición deNULL
sea((void *)0)
, que no funcionará en todos los contextos sin puntero). En particular, no useNULL
cuando se desee el carácter nulo ASCII (NUL
). Proporcione su propia definición
#define NUL ''/0''
si debes.
Nota: esta respuesta se aplica al lenguaje C, no a C ++.
Punteros nulos
La constante entera literal 0
tiene diferentes significados dependiendo del contexto en el que se usa. En todos los casos, sigue siendo una constante entera con el valor 0
, simplemente se describe de diferentes maneras.
Si se está comparando un puntero con el literal 0
constante, entonces esto es una verificación para ver si el puntero es un puntero nulo. Este 0
se conoce como una constante de puntero nulo. El estándar de C define que 0
emitido al tipo void *
es tanto un puntero nulo como una constante de puntero nulo.
Además, para facilitar la legibilidad, la macro NULL
se proporciona en el archivo de encabezado stddef.h
. Dependiendo de tu compilador podría ser posible #undef NULL
y redefinirlo a algo raro.
Por lo tanto, aquí hay algunas formas válidas de verificar un puntero nulo:
if (pointer == NULL)
NULL
se define para comparar igual a un puntero nulo. Es una implementación definida cuál es la definición real de NULL
, siempre que sea una constante de puntero nula válida.
if (pointer == 0)
0
es otra representación de la constante de puntero nulo.
if (!pointer)
Esta instrucción if
comprueba implícitamente que "no es 0", por lo que revertimos que significa "es 0".
Las siguientes son formas INVÁLIDAS de verificar un puntero nulo:
int mynull = 0;
<some code>
if (pointer == mynull)
Para el compilador esto no es una comprobación para un puntero nulo, sino una comprobación de igualdad en dos variables. Esto podría funcionar si mynull nunca cambia en el código y las optimizaciones del compilador constantemente doblan el 0 en la sentencia if, pero esto no está garantizado y el compilador debe producir al menos un mensaje de diagnóstico (advertencia o error) de acuerdo con el Estándar C.
Tenga en cuenta que lo que es un puntero nulo en el lenguaje C. No importa en la arquitectura subyacente. Si la arquitectura subyacente tiene un valor de puntero nulo definido como dirección 0xDEADBEEF, entonces es responsabilidad del compilador resolver este problema.
Como tal, incluso en esta arquitectura divertida, las siguientes formas siguen siendo formas válidas de verificar un puntero nulo:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Las siguientes son formas INVÁLIDAS de verificar un puntero nulo:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
ya que estos son vistos por un compilador como comparaciones normales.
Caracteres nulos
''/0''
se define como un carácter nulo, es decir, un carácter con todos los bits establecidos en cero. Esto no tiene nada que ver con los punteros. Sin embargo, puede ver algo similar a este código:
if (!*string_pointer)
comprueba si el puntero de cadena está apuntando a un carácter nulo
if (*string_pointer)
comprueba si el puntero de cadena apunta a un carácter no nulo
No confundas estos con punteros nulos. Solo porque la representación de bits es la misma, y esto permite algunos casos cruzados convenientes, en realidad no son lo mismo.
Además, ''/0''
es (como todos los literales de caracteres) una constante entera, en este caso con el valor cero. Por lo tanto, ''/0''
es completamente equivalente a una constante entera sin adornos 0
- la única diferencia es la intención que transmite a un lector humano ("lo estoy usando como un carácter nulo").
Referencias
Vea la pregunta 5.3 de las preguntas frecuentes comp.lang.c para más información. Vea este pdf para el estándar C. Consulte las secciones 6.3.2.3 Indicadores, párrafo 3.