2012-07-12 8 views
5

Comincio a imparare il C e leggere seguente codice:Cosa vuol dire la dichiarazione ** nel linguaggio 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; 
} 

non capisco il significato di void**. Qualcuno potrebbe spiegarlo con alcuni esempi?

+3

'' vuoto ** = puntatore a una '' void * – Mysticial

+1

In questo caso, significa "puntatore a un array di puntatori void *" –

+2

@VariableLengthCoder, senza che sarebbe ' void * (* array) [] '.Probabilmente vuoi dire "puntatore al primo elemento di una matrice di puntatori" void "". –

risposta

1

void** è un puntatore a void* o un pointer a un void pointer se si preferisce! Questa notazione è tradizionalmente utilizzata in C per implementare una matrice, ad esempio. Quindi, nel caso di matrice, sarebbe un pointer su un array of pointers.

+1

È un puntatore a un puntatore 'void', ma cos'è un puntatore' void' su un puntatore 'void'? –

+0

@CarlNorum Mi dispiace per qualsiasi errore di digitazione. – cybertextron

0

Normalmente i puntatori void * indicano un puntatore a un tipo di dati sconosciuto. In questo caso la tua funzione restituisce una matrice di tali puntatori, quindi la doppia stella.

In C, un puntatore viene spesso utilizzato per fare riferimento a un array. Ad esempio, la seguente assegnazione è perfettamente legale:

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

Ora, quando si utilizza vuoto, significa che invece di char si dispone di una variabile di tipo sconosciuto.

I puntatori a un tipo di dati sconosciuto sono utili per scrivere algoritmi generici. Per esempio. la funzione qsort nella libreria standard C è definito come:

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

L'algoritmo di ordinamento stessa è generico, ma non ha alcuna conoscenza del contenuto dei dati. Pertanto, l'utente deve fornire un'implementazione di un comparatore in grado di gestirlo. L'algoritmo chiamerà il comparatore con due indicatori per gli elementi da confrontare. Questi puntatori sono di tipo void *, poiché ora sono disponibili informazioni sul tipo di dati che vengono ordinati.

Date un'occhiata a questo thread per ulteriori esempi http://forums.fedoraforum.org/showthread.php?t=138213

+3

-1 per aver detto che "char ** strarray2 = strarray1;" è "perfettamente legale". –

+0

Jens ha ragione, 'char [] []' è equivalente a 'char []' (è solo la sintassi di comodità che consente al compilatore di eseguire aritmetici puntatori di array 2D per te), mentre un 'char **' è una matrice di puntatori alle matrici di carbone. – Adam

+0

Grazie per averlo indicato, non avevo un compilatore C a portata di mano quando ho risposto per correggermi :( – anttix

4

vuoto ** è un puntatore ad un puntatore a void (tipo non specificato). Significa che la variabile (posizione di memoria) contiene un indirizzo in una posizione di memoria, che contiene un indirizzo in un'altra posizione di memoria, e ciò che è memorizzato non è specificato. Nel caso di questa domanda è un puntatore a una matrice di puntatori void *.

Sidenote: Un puntatore del vuoto non può essere dereferenziato, ma un vuoto ** può.

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

In questo modo si dovrebbe essere in grado di fare ad es. aa [17] per ottenere il 18esimo elemento dell'array a.

Per comprendere tali dichiarazioni è possibile utilizzare lo strumento this e si può anche verificare un relativo question o two.

+0

La risposta non sta da sola - se e quando questi link si interrompono, questo avrà valore zero – dwanderson

+0

@ dwanderson Hey grazie, ho aggiornato la risposta: devo essere stato un po 'pigro nel 2012, quando ho scritto questa risposta, il mio male :) –

+0

Follow-up impressionante! apprezza sempre quando le persone rispondono a domande vecchie di anni. Grazie! – dwanderson

0

I puntatori vuoto vengono utilizzati per contenere l'indirizzo di qualsiasi tipo di dati. void** significa puntatore a puntatore vuoto. I puntatori vuoti vengono utilizzati in un punto in cui vogliamo che una funzione riceva diversi tipi di dati come argomento della funzione. Si prega di controllare l'esempio seguente

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; 
}