2013-04-24 2 views
11

So che questa domanda è stata posta molto, ma non sono ancora chiaro come accedere alle strutture.c puntatore a matrice di strutture

Voglio fare un puntatore globale a un array di struct:

typdef struct test 
{ 
    int obj1; 
    int obj2; 
} test_t; 

extern test_t array_t1[1024]; 
extern test_t array_t2[1024]; 
extern test_t array_t3[1025]; 

extern test_t *test_array_ptr; 

int main(void) 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0, 0}; 
    (*test_array_ptr)[0] = new_struct; 
} 

ma mi dà avvertimenti. Come devo accedere alle strutture specifiche con []?

Analogamente, come dovrei creare un array di puntatori di tipo struct? test_t *_array_ptr[2];?

+1

non si dovrebbe dare avvertimenti, dovrebbe dare un errore. '(* test_array_ptr) [0]' dereferences due volte, ma c'è solo un livello di stelle. –

+0

@DanielFischer: gcc, ad esempio, stampa frequentemente gli avvisi per i costrutti che sono "violazioni dei vincoli" (circa tanto quanto C viene a dire che qualcosa è * illegale *). L'opzione '-pedantic-errors' rende il comportamento più rigoroso. –

+0

@KeithThompson Sì, ma per quel problema specifico, gcc dice 'deref.c: 18: 18: errore: il valore dell'iscrizione non è né array né pointer né vector' senza alcun flag. (Hmm, cos'è un 'vector', questo è C?) Per cose come il dereferenziamento di una struct, o l'accesso a un membro di un' int', dove il compilatore non ha idea di come dovrebbe farlo, si arrende e lancia un errore. –

risposta

14

La sintassi che stai cercando è un po 'ingombrante, ma sembra che questo:

// Declare test_array_ptr as pointer to array of test_t 
test_t (*test_array_ptr)[]; 

è possibile utilizzare in questo modo:

test_array_ptr = &array_t1; 
(*test_array_ptr)[0] = new_struct; 

Per rendere la sintassi più facile da capire, è possibile utilizzare un typedef:

// Declare test_array as typedef of "array of test_t" 
typedef test_t test_array[]; 
... 
// Declare test_array_ptr as pointer to test_array 
test_array *test_array_ptr = &array_t1; 
(*test_array_ptr)[0] = new_struct; 

L'utilità cdecl è utile per decifrare le dichiarazioni C complesse, soprattutto quando gli array e puntatori a funzione coinvolti.

+0

grazie per la risposta utile! ma qual è la differenza dalla prima risposta. where function foo() { test_array_ptr = array_t1; test_t new_struct = {0,0}; test_array_ptr [0] = new_struct; } – user1539348

0

Il problema che si ha è che si sta prendendo (*test_array_pointer) che è il primo elemento della matrice. Se si desidera assegnare ad un elemento specifico della matrice, si dovrebbe effettuare le seguenti ...

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    memcpy(&test_array_ptr[0], &new_struct, sizeof(struct test_t)); 
} 

se si desidera assegnare sempre al primo elemento della matrice si potrebbe fare questo ...

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    memcpy(test_array_ptr, &new_struct, sizeof(struct test_t)); 
} 

ed è stato mi ha fatto notare da altri, e qualcosa che onestamente ero completamente dimenticato di aver non utilizzato nella parte migliore di sempre, si può fare affidamento diretto di strutture semplici in C ...

function foo() 
{ 
    test_array_ptr = array_t1; 

    test_t new_struct = {0,0}; 
    test_array_ptr[0] = new_struct; 
} 
+1

Sono abbastanza sicuro che tu possa copiare le strutture (non i puntatori alle strutture) semplicemente usando '='. –

+1

Sì, è possibile. Questo è ad esempio un modo per copiare array con un semplice compito, avvolgerli in una 'struct'. –

+0

Sì ... quello era ossuto ... solo qualcosa che non ho usato da decenni e ho dimenticato che anche tu potresti. Aggiustato. –

4

test_t * test_array_ptr è un puntatore a test_t. Potrebbe essere un puntatore a singola istanza di test_t, ma potrebbe essere un puntatore al primo elemento di un array di istanze di test_t:

test_t array1[1024]; 

test_t *myArray; 
myArray= &array1[0]; 

questo rende myArray punto al primo elemento di array1 e puntatori permette anche tu puoi trattare questo puntatore come un array. Ora è possibile accedere al 2 ° elemento di array1 in questo modo: myArray[1], che equivale a *(myArray + 1).

Ma da quanto ho capito, che cosa si vuole realmente fare è dichiarare un puntatore a puntatore a test_t che rappresenterà un array di puntatori ad array:

test_t array1[1024]; 
test_t array2[1024]; 
test_t array3[1025]; 

test_t **arrayPtr; 
arrayPtr = malloc(3 * sizeof(test_t*)); // array of 3 pointers 
arrayPtr[0] = &array1[0]; 
arrayPtr[1] = &array2[0]; 
arrayPtr[2] = &array3[0]; 
+0

come potrei creare un puntatore a una singola struttura di array alla volta? e come potrei accedere a una struttura all'interno della matrice? – user1539348

+0

@ user1539348: Controlla la mia risposta ora :) – LihO

0

userei un puntatore a un puntatore come:

test_t array_t1[1024]; 
test_t **ptr; 
ptr = array_t1; 
ptr[0] = ...; 
ptr[1] = ...; 
etc.