c++ - que - ¿Qué es un puntero de vacío y qué es un puntero nulo?
punteros como parametros de funciones en c (9)
Aquí hay algunas diferencias con respecto a la aritmética del puntero:
Se deriva del hecho de que el vacío es un tipo incompleto.
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)
Así que estaba pasando por algunas preguntas de la entrevista y me encontré con uno sobre punteros nulos y vacíos , que dice:
un puntero sin tipo de devolución se llama puntero nulo. Puede ser cualquier tipo de tipo de datos.
¡Esto me confundió completamente! Parece vacío y nulo podría usarse indistintamente según esta pregunta, y no creo que sea correcto. Supuse que sería un tipo de devolución y nulo para ser un valor. Pero solo soy un rookie de código y no estoy seguro de tener razón.
Exprese su opinión sobre qué es un puntero nulo y un puntero de vacío. No estoy buscando la diferencia entre nulo y vacío.
El artículo vinculado es simplemente incorrecto. Su primera frase:
un puntero sin tipo de devolución se llama puntero nulo
está activando todo tipo de alarmas para mí. Esta es una escritura muy confusa.
Estás casi en lo cierto. "Pointer to void" es un tipo (no un "tipo de devolución"). Los valores de cualquier tipo pueden ser devueltos por funciones, y por lo tanto ser (el tipo de retorno de la función).
Un puntero nulo es un puntero que, independientemente de su tipo, apunta al objeto nulo, que no es ningún objeto válido que se pueda crear. Se puede decir que un puntero nulo apunta a "nada".
Un puntero a vacío también puede ser nulo;
void *nothing = 0;
es un código perfectamente válido, y simplemente dice que este puntero es capaz de apuntar a un objeto sin tipo, pero en este momento no lo es.
El tipo de void
en general significa que no se proporciona información de tipo.
Siempre debe tener en cuenta que un puntero transmite dos partes de información: el tipo de datos apuntados ( int
, double
, ...), que especifica cómo interpretarlo, y la dirección de los datos a los que apunta, que especifica donde puedes obtener el valor real de los datos apuntados.
La información de tipo está en el tipo de puntero ( double
*
, int
*
, ...), mientras que la dirección de los datos es el valor real contenido en la variable de puntero.
Por lo tanto, un puntero de void
( void *
) es un puntero que no especifica ningún tipo de información. Le dice dónde están los datos, pero no le indica cómo interpretarlos. Sabes que en esa dirección hay algo, pero no sabes si es un int
, un double
o una selección de vacas voladoras. Para utilizar realmente esos datos, debe obtener información sobre el mismo de alguna otra forma (por ejemplo, con algún otro parámetro mágico), convertir ese puntero a un tipo de puntero regular y luego usarlo como de costumbre.
void *
se usa a menudo en C para proporcionar algún tipo de soporte a la programación genérica; ver por ejemplo la función de la biblioteca qsort
C.
Un puntero NULL
, en cambio, es un puntero que apunta a nada. En este caso, la información de tipo sobre el puntero en general está presente, pero es la dirección de los datos apuntados que falta. Por supuesto, es posible tener un void *
que sea NULL
.
Ejemplo rápido (suponiendo que v
se declara como 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 | | | |
+---+----------------------+----------------------+
Trivia : NULL
, al menos en el estándar actual, se garantiza que sea 0.
En otras áreas del lenguaje, el void
siempre se usa para especificar la falta de tipo. Utilizándolo como valor de retorno (nota: estoy hablando ahora de void
, no void *
) significa que la función no devuelve ningún valor, y convertir una expresión en vacío es una manera elegante de descartar un valor (estás señalando a el compilador y a otros programadores que eres consciente de que no estás usando un cierto valor).
Los dos conceptos son ortogonales:
- Un puntero void, (
void *
) es un puntero sin formato a alguna ubicación de memoria. - Un puntero nulo es un puntero especial que no apunta a nada, por definición. Puede ser un puntero a cualquier tipo, nulo o no.
Un puntero de vacío puede ser nulo o no:
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 puntero no nulo también puede ser nulo o no:
Foo *f = nullptr;
Foo *g = new Foo;
Por favor, cuéntanos: cuál es la diferencia:
- entre el tanque de gas y la situación sin gases
- entre cookie jar y no-cookies
- entre el término ''dinero'' y ''bolsillos vacíos''
Si se les ocurre esto, podrán captar null vs void * dillema.
Solo olvídate de esa respuesta. Una cita de tu enlace:
"un puntero sin tipo de retorno se llama puntero nulo".
Esto es muuuy claro MAL . Tipo de devolución de un puntero? ¿DE VERDAD? Esta es una mala fuente ...
void*
es un tipo de puntero universal porque cualquier tipo de puntero (excepto puntero a const y / o volátil) se puede convertir implícitamente a void*
. En otras palabras, puede asignar cualquier puntero a una variable de tipo void*
. Un puntero nulo es un valor de puntero 0
Un void *ptr
es el puntero que se puede usar para señalar cualquier tipo de datos. Puede ser int
, float
, double
. No tiene un tipo de retorno que inicialmente se crea con el tipo de puntero (que tiene un valor hexadecimal) y podemos asignar este puntero a cualquier tipo de datos.
Mientras que el puntero nulo es el puntero que tiene un valor NULO como dirección, al puntero se le asigna un valor NULL para que no se pueda usar para acceder a los datos de otros que su dirección puede contener durante la creación. Creo que es una buena técnica de programación asignar un puntero NULL si no se usa en este momento.
el puntero nulo apunta a 0x000000 (que es incorrecto para acceder al puntero), mientras que el puntero void es un puntero correcto a un tipo no especificado ( void *
). Sin embargo, el puntero void puede ser un puntero nulo, pero al reordenar el puntero generará un error.
void es un no tipo. null no tiene valor