2012-07-12 25 views
5

estoy empezando a aprender C y leer siguiente código:¿Qué significa la declaración nula ** en el lenguaje C?

public void** list_to_array(List* thiz){ 
    int size = list_size(thiz); 
    void **array = malloc2(sizeof(void *) * size); 
    int i=0; 
    list_rewind(thiz); 
    for(i=0; i<size; i++){ 
     array[i] = list_next(thiz); 
    } 
    list_rewind(thiz); 
    return array; 
} 

que no entienden el significado de void**. ¿Alguien podría explicarlo con algunos ejemplos?

+3

'void **' = puntero a una '' void * – Mysticial

+1

En este caso, significa "puntero a una matriz de punteros void *" –

+2

@VariableLengthCoder, sin que sería ' void * (* array) [] '.Probablemente signifique "puntero al primer elemento de una matriz de punteros' void' ". –

Respuesta

1

void** es un puntero a void*, o un pointer a un void pointer si lo prefiere! Esta notación se usa tradicionalmente en C para implementar una matriz, por ejemplo. Entonces, en el caso de la matriz, sería pointer a array of pointers.

+1

Es un puntero a un puntero 'void', pero ¿qué es un puntero' void' a un puntero 'void'? –

+0

@CarlNorum Lo siento por cualquier error de escritura. – cybertextron

0

Normalmente, los punteros void * se utilizan para designar un puntero a un tipo de datos desconocido. En este caso, su función devuelve una matriz de punteros así la estrella doble.

En C, un puntero se utiliza a menudo para hacer referencia a una matriz. Por ejemplo, la siguiente asignación es perfectamente legal:

char str1[10]; 
char *str2 = str1; 

Ahora, cuando se utiliza vacío, significa que en lugar de carbón tiene una variable de tipo desconocido.

Los punteros a un tipo de datos desconocido son útiles para escribir algoritmos genéricos. P.ej. la función qsort en la biblioteca estándar de C se define como:

void qsort (void * base, 
      size_t num, 
      size_t size, 
      int (* comparator) 
      (const void *, const void *)); 

El algoritmo de ordenación en sí es genérico, pero no tiene conocimiento de los contenidos de los datos. Por lo tanto, el usuario debe proporcionar una implementación de un comparador que pueda manejarlo. El algoritmo llamará al comparador con dos punteros a los elementos que se compararán. Estos punteros son del tipo void *, porque ahora hay información sobre el tipo de datos que se ordenan.

Tome un vistazo a este hilo para más ejemplos http://forums.fedoraforum.org/showthread.php?t=138213

+3

-1 por decir que 'char ** strarray2 = strarray1;' es "perfectamente legal". –

+0

Jens tiene razón, 'char [] []' es equivalente a 'char []' (es solo la sintaxis de conveniencia que le permite al compilador hacer una aritmética de matriz bidimensional), mientras que 'char **' es una matriz de punteros a matrices de caracteres – Adam

+0

Gracias por señalar eso, no tenía un compilador de C en la mano cuando lo respondí para corregirme :( – anttix

4

vacío ** es un puntero a un puntero a void (tipo no especificado). Significa que la variable (ubicación de la memoria) contiene una dirección en una ubicación de memoria, que contiene una dirección a otra ubicación de memoria, y que no se especifica lo que está almacenado allí. En el caso de esta pregunta, es un puntero a una matriz de punteros void *.

Nota: Un puntero void no se puede desreferenciar, pero un vacío ** puede.

void *a[100]; 
void **aa = a; 

Al hacer esto, uno debería ser capaz de hacer, p. aa [17] para llegar al 18 ° elemento de la matriz a.

Para comprender tales declaraciones, puede usar la herramienta this y también puede consultar un relacionado question o two.

+0

La respuesta no se sostiene por sí sola: si esos enlaces se rompen, esto tendrá valor cero 0 y cuando se rompan. – dwanderson

+0

@ dwanderson Hola, gracias. He actualizado la respuesta. Debo haber sido un poco flojo en 2012 cuando escribí esta respuesta. Mi mal :) :) –

+0

¡Impresionante seguimiento! siempre aprecio cuando las personas responden a preguntas de hace años. ¡Gracias! – dwanderson

0

Los punteros vacíos se utilizan para mantener la dirección de cualquier tipo de datos. void** significa puntero al puntero de vacío. Los punteros vacíos se utilizan en un lugar donde queremos que una función reciba diferentes tipos de datos como argumento de la función. Por favor, compruebe el siguiente ejemplo

void func_for_int(void *int_arg) 
{ 
    int *ptr = (int *)int_arg; 
    //some code 
} 

void func_for_char(void *char_arg) 
{ 
    char *ptr = (char *)char_arg; 
    //some code 
} 

int common_func(void * arg, void (*func)(void *arg)) 
{ 
    func(arg); 
} 

int main() 
{ 
    int a = 10; 
    char b = 5; 

    common_func((void *)&a, func_for_int); 
    common_func((void *)&b, func_for_char); 

    return 0; 
} 
Cuestiones relacionadas