Buscando obtener los fundamentos sobre el origen del término " vacío " y por qué se llama vacío. La intención de la pregunta es ayudar a alguien que no tiene experiencia en C y de repente está buscando una base de código basada en C.
Buscando obtener los fundamentos sobre el origen del término " vacío " y por qué se llama vacío. La intención de la pregunta es ayudar a alguien que no tiene experiencia en C y de repente está buscando una base de código basada en C.
Respuestas:
Básicamente significa "nada" o "sin tipo"
Hay 3 formas básicas de usar el vacío:
Argumento de int myFunc(void)
la función : la función no toma nada.
Valor de retorno de void myFunc(int)
la función : la función no devuelve nada
Puntero de datos genérico: void* data
- 'datos' es un puntero a datos de tipo desconocido, y no puede ser desreferenciado
Nota: el void
argumento en una función es opcional en C ++, por lo que int myFunc()
es exactamente el mismo que int myFunc(void)
, y se deja completamente en C #. Siempre se requiere para un valor de retorno.
Siempre lo he tomado como ausente . Aquí hay cuatro casos en el lenguaje C que coinciden con este uso de ausente
R f(void)
- Los parámetros de la función están ausentesvoid f(P)
- El valor de retorno está ausentevoid *p
- El tipo de lo que se señala está ausente(void) p
- El uso del valor está ausenteOtros descendientes de C lo usan para otras cosas. El D
lenguaje de programación lo utiliza para casos en los que falta un inicializador
T t = void;
- el valor de inicialización está ausente(void)p
hacer? No entendí lo que querías decir con "el uso del valor está ausente".
(void) var;
declaración, he encontrado respuestas detalladas en stackoverflow.com/q/21045615 .
Hay dos formas de usar void:
void foo(void);
o
void *bar(void*);
El primero indica que no se pasa ningún argumento o que no se devuelve ningún argumento.
El segundo le dice al compilador que no hay ningún tipo asociado con los datos de manera efectiva, lo que significa que no puede hacer uso de los datos apuntados hasta que se conviertan en un tipo conocido.
Por ejemplo, verá que se void*
usa mucho cuando tiene una interfaz que llama a una función cuyos parámetros no se pueden conocer de antemano.
Por ejemplo, en el Kernel de Linux al diferir el trabajo, configurará una función para que se ejecute en un momento posterior, dándole un puntero a la función que se ejecutará y un puntero a los datos que se pasarán a la función:
struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
} deferred_work;
Luego, un subproceso del kernel pasa por una lista de trabajos diferidos y, cuando llega a este nodo, se ejecuta efectivamente:
bar(somedata);
Luego en el bar tienes:
void bar(void* mydata) {
int *data = mydata;
/* do something with data */;
}
Significa "sin valor". Se usa void
para indicar que una función no devuelve un valor o que no tiene parámetros o ambos. Bastante consistente con los usos típicos de la palabra void en inglés.
Indica la ausencia de un valor de retorno en una función.
Algunos lenguajes tienen dos tipos de subrutinas: procedimientos y funciones. Los procedimientos son solo una secuencia de operaciones, mientras que una función es una secuencia de operaciones que devuelve un resultado.
En C y sus derivados, la diferencia entre los dos no es explícita. Todo es básicamente una función. la void
palabra clave indica que no es una función "real", ya que no devuelve un valor.
Piense en el vacío como la "estructura vacía". Dejame explicar.
Cada función toma una secuencia de parámetros, donde cada parámetro tiene un tipo. De hecho, podríamos agrupar los parámetros en una estructura, con los espacios de estructura correspondientes a los parámetros. Esto hace que cada función tenga exactamente un argumento. Del mismo modo, las funciones producen un resultado, que tiene un tipo. Podría ser un booleano, o podría ser flotante, o podría ser una estructura, que contiene un conjunto arbitrario de otros valores escritos. Si queremos un lenguaje que tenga múltiples valores de retorno, es fácil insistir en que se empaqueten en una estructura. De hecho, siempre podemos insistir en que una función devuelve una estructura. Ahora cada función toma exactamente un argumento y produce exactamente un valor.
Ahora, ¿qué sucede cuando necesito una función que produce un valor "no"? Bueno, considere lo que obtengo cuando formo una estructura con 3 ranuras: contiene 3 valores. Cuando tengo 2 ranuras, tiene dos valores. Cuando tiene una ranura, un valor. Y cuando tiene cero ranuras, contiene ... uh, valores cero o "no" valor ". Entonces, puedo pensar en una función que devuelve void como una estructura que no contiene valores. Incluso puede decidir que" void " es solo un sinónimo del tipo representado por la estructura vacía, en lugar de una palabra clave en el idioma (quizás sea solo un tipo predefinido :)
Del mismo modo, puedo pensar en una función que no requiere valores como aceptar una estructura vacía, por ejemplo, "vacío".
Incluso puedo implementar mi lenguaje de programación de esta manera. Pasar un valor vacío ocupa cero bytes, por lo que pasar valores vacíos es solo un caso especial de pasar otros valores de tamaño arbitrario. Esto facilita que el compilador trate el resultado o argumento "nulo". Probablemente desee una función de idioma que pueda descartar el resultado de una función; en C, si llama a la función de resultado no nula foo en la siguiente declaración: foo (...); el compilador sabe que foo produce un resultado y simplemente lo ignora. Si void es un valor, esto funciona perfectamente y ahora los "procedimientos" (que son solo un adjetivo para una función con resultado void) son solo casos especiales triviales de funciones generales.
Void * es un poco más divertido. No creo que los diseñadores de C pensaron en vacío de la manera anterior; Acaban de crear una palabra clave. Esa palabra clave estaba disponible cuando alguien necesitaba un punto para un tipo arbitrario, por lo tanto nulo * como el modismo en C. En realidad, funciona bastante bien si interpreta nulo como una estructura vacía. Un puntero nulo * es la dirección de un lugar donde se ha colocado esa estructura vacía.
Los lanzamientos de nulo * a T * para otros tipos T, también funcionan con esta perspectiva. Los lanzamientos de punteros son un truco completo que funciona en la mayoría de las arquitecturas comunes para aprovechar el hecho de que si un tipo compuesto T tiene un elemento con el subtipo S colocado físicamente al comienzo de T en su diseño de almacenamiento, entonces lanza S * a T * y viceversa, el uso de la misma dirección de máquina física tiende a funcionar, ya que la mayoría de los punteros de máquina tienen una única representación. Reemplazar el tipo S por el tipo void produce exactamente el mismo efecto, y por lo tanto, lanzar hacia / desde void * funciona.
El lenguaje de programación PARLANSE implementa las ideas anteriores muy de cerca. Nos burlamos de su diseño y no prestamos mucha atención al "vacío" como tipo de retorno y, por lo tanto, tenemos palabras clave de lenguaje para el procedimiento. Es principalmente un simple cambio de sintaxis, pero es una de las cosas a las que no se puede acceder una vez que obtiene un código de trabajo de gran cuerpo en un idioma.
En c # usaría la palabra clave nula para indicar que un método no devuelve un valor:
public void DoSomeWork()
{
//some work
}
Tres casos de uso para vacío:
Firmas de funciones. void foo(int bar)
no devuelve un valor int bar(void)
no toma ningún parámetro, pero esto se expresa por lo general con lista de argumentos vacía: int bar()
. El uso de la palabra clave nula aquí corresponde a su significado en inglés.
Puntero genérico de tipo superior void *
que apunta a datos no especificados y no se puede desreferenciar. Aquí el significado de vacío es diferente de otros significados de vacío: tipo universal versus ningún tipo.
En modelos como (void) new Foo(this)
para significar que el valor de retorno se desecha deliberadamente. Aquí el uso de palabras clave también coincide con su significado en inglés.
Los casos 1 y 2 ya estaban cubiertos por @Gerald, pero el caso 3 aún no se ha abordado.
Si está explicando el concepto a un principiante, podría ser útil usar una analogía. El uso de vacío en todos estos casos es análogo al significado de una página en un libro que tiene las siguientes palabras, "Esta página se dejó en blanco intencionalmente". Es para diferenciar al compilador entre algo que debe marcarse como un error, frente a un tipo que debe dejarse en blanco intencionalmente porque ese es el comportamiento que desea.
Siempre aparece en el código donde normalmente esperaría ver aparecer un tipo, como un tipo de retorno o un tipo de puntero. Es por eso que en C #, void se asigna a un tipo CLR real, System.Void porque es un tipo en sí mismo.
Algunos lenguajes de programación nunca desarrollaron el concepto de vacío, al igual que algunas culturas humanas nunca inventaron el concepto del número cero. El vacío representa el mismo avance en un lenguaje de programación que el concepto de cero representa para el lenguaje humano.
Significa "sin valor". Utiliza void para indicar que una función no devuelve un valor o que no tiene parámetros o ambos. Es muy consistente con los usos típicos de la palabra void en inglés.
El vacío no debe confundirse con nulo. Nulo significa que para la variable cuya dirección está en la pila, el valor en el montón para esa dirección está vacío.
Void se usa solo en firmas de métodos. Para los tipos de devolución, significa que el método no devolverá nada al código de llamada. Para los parámetros significa que no se pasan parámetros al método.
p.ej
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
En C # podemos omitir el vacío para los parámetros y podemos escribir el código anterior como:
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
El vacío no debe confundirse con nulo. Nulo significa que para la variable cuya dirección está en la pila, el valor en el montón para esa dirección está vacío.
nulo significa que no devolverá ningún valor de la función o método
Anulado significa que no se requiere ningún valor en el tipo de retorno de una función en los tres idiomas.