Hoy, cuando estaba leyendo el código de otros, vi algo como void *func(void* i);
, ¿qué significa esto void*
aquí para el nombre de la función y para el tipo de variable, respectivamente?
Además, ¿cuándo necesitamos usar este tipo de puntero y cómo usarlo?
malloc
ycalloc
. La página de manual continúa diciendo: "... devuelve un puntero a la memoria asignada, que está alineada adecuadamente para cualquier tipo de datos incorporado".Respuestas:
Un puntero a
void
es un tipo de puntero "genérico". Avoid *
se puede convertir a cualquier otro tipo de puntero sin una conversión explícita. No puede desreferenciarvoid *
ni hacer aritmética de puntero con él; primero debe convertirlo en un puntero a un tipo de datos completo.void *
a menudo se usa en lugares donde necesita poder trabajar con diferentes tipos de puntero en el mismo código. Un ejemplo comúnmente citado es la función de bibliotecaqsort
:base
es la dirección de una matriz,nmemb
es el número de elementos en la matriz,size
es el tamaño de cada elemento ycompar
es un puntero a una función que compara dos elementos de la matriz. Se llama así:Las expresiones de matriz
iArr
,dArr
ylArr
se convierten implícitamente a partir de los tipos de matriz a los tipos de puntero en la llamada de función, y cada uno se convierten implícitamente de "puntero aint
/double
/long
" a "puntero avoid
".Las funciones de comparación se verían así:
Al aceptar
void *
,qsort
puede trabajar con matrices de cualquier tipo.La desventaja de usar
void *
es que arrojas la seguridad de tipografía por la ventana y hacia el tráfico que viene. No hay nada que lo proteja de usar la rutina de comparación incorrecta:compareInt
espera que sus argumentos apunten aint
s, pero en realidad está trabajando condouble
s. No hay forma de detectar este problema en tiempo de compilación; terminarás con una matriz mal ordenada.fuente
void*
se pueda convertir a un puntero de función. Pero para los apuntadores de datos, lo que dijiste es válido.Usar un vacío * significa que la función puede tomar un puntero que no necesita ser de un tipo específico. Por ejemplo, en las funciones de socket, tiene
Esto significa que puede llamarlo de muchas maneras, por ejemplo
fuente
C es notable a este respecto. Se puede decir
void
que la nadavoid*
es todo (puede ser todo).Es solo este pequeño
*
que hace la diferencia.Rene lo ha señalado. A
void *
es un puntero a alguna ubicación. Lo que hay cómo "interpretar" se deja al usuario.Es la única forma de tener tipos opacos en C. Se pueden encontrar ejemplos muy destacados, por ejemplo, en bibliotecas de estructura de datos generales o glib. Se trata de manera muy detallada en "Interfaces e implementaciones C".
Le sugiero que lea el capítulo completo e intente comprender el concepto de un puntero para "obtenerlo".
fuente
es un "puntero a la memoria sin suposiciones de qué tipo hay almacenado". Puede usar, por ejemplo, si desea pasar un argumento a la función y este argumento puede ser de varios tipos y en función manejará cada tipo.
fuente
Puede echar un vistazo a este artículo sobre punteros http://www.cplusplus.com/doc/tutorial/pointers/ y leer el capítulo: punteros nulos .
Esto también funciona para el lenguaje C.
fuente
Un puntero vacío se conoce como puntero genérico. Me gustaría explicar con un ejemplo de escenario pthread.
La función de hilo tendrá el prototipo como
Los diseñadores de la API pthread consideraron el argumento y los valores de retorno de la función thread. Si esas cosas se hacen genéricas, podemos escribir cast to void * mientras se envía como argumento. Del mismo modo, el valor de retorno se puede recuperar de void * (pero nunca usé valores de retorno de la función de hilo).
fuente
pthread_exit(NULL);
lugar dereturn 0;
al final de main?a
void*
es un puntero, pero el tipo de lo que apunta no está especificado. Cuando pasa un puntero vacío a una función, necesitará saber cuál era su tipo para poder volver a ese tipo correcto más adelante en la función para usarlo. Verá ejemplos en lospthreads
que se utilizan funciones con exactamente el prototipo en su ejemplo que se utilizan como la función de hilo. Luego puede usar elvoid*
argumento como un puntero a un tipo de datos genérico de su elección y luego volverlo a ese tipo para usar dentro de su función de hilo. Sin embargo, debe tener cuidado al usar punteros vacíos, ya que a menos que vuelva a utilizar un puntero de su tipo real, puede terminar con todo tipo de problemas.fuente
El estándar C11 (n1570) §6.2.2.3 al1 p55 dice:
Puede usar este puntero genérico para almacenar un puntero a cualquier tipo de objeto, pero no puede usar operaciones aritméticas habituales con él y no puede deducirlo.
fuente
La función toma un puntero a un tipo arbitrario y devuelve uno.
fuente
significa puntero, puede usar este enlace para obtener más información sobre el puntero http://www.cprogramming.com/tutorial/c/lesson6.html
fuente