2009-12-28 14 views
6

Alcuni codice esempio per avviare la domanda:annodare una matrice di dimensione fissa senza definire la sua dimensione in C

#define FOO_COUNT 5 

static const char *foo[] = { 
     "123", 
     "456", 
     "789", 
     "987", 
     "654" 
}; 

Il modo in cui questo sarebbe normalmente iterati, come per un esempio, è la seguente:

int i = FOO_COUNT; 
while (--i >= 0) { 
printf("%s\n", foo[i]); 

Esiste comunque la possibilità di fare quanto sopra senza avere esplicitamente il conteggio umano numero 5? In futuro potrei aggiungere/rimuovere elementi e dimenticare di aggiornare la dimensione dell'array, rompendo così la mia app.

risposta

16
int i = sizeof(foo)/sizeof(foo[0]); 
+0

sarebbe questo ancora funzionare se i puntatori di caratteri in foo indicavano stringhe di caratteri di dimensioni variabili? – randombits

+0

sì (15 limite char) –

+0

quindi se ogni elemento supera i 15 caratteri, questo controllo non riesce? probabilmente meglio usare la sentinella NULL allora? grazie ancora – randombits

0

Sì.

sizeof (foo)/sizeof (char *)

è 5.

2

Il solito modo per farlo è quello di porre fine alla matrice con NULL e iterare fino a colpire questo.

2

Sì.

int i = sizeof(foo)/sizeof(char*); 

Nota: questo si applica solo agli array allocati staticamente. Non funzionerà con gli array malloc edo new ed.

12

Utilizzare una sentinella alla fine, come NULL:

static const char *foo[] = { 
     "123", 
     "456", 
     "789", 
     "987", 
     "654", 
     NULL 
}; 

for (char *it = foo[0]; it != NULL; it++) 
{ 
     ... 
} 
2
size_t i = sizeof foo/sizeof *foo; // or sizeof foo/sizeof foo[0] 

Questo divide il numero totale di byte nella matrice foo (sizeof foo) per il numero di byte in un unico elemento (sizeof *foo), dando il numero di elementi nella matrice.

2

C'è anche un altro metodo in C99, soprattutto se si desidera indici denominati, consentendo per esempio la localizzazione e così via.

enum STRINGS { 
    STR_THING1, 
    STR_THING2, 
    STR_THING3, 
    STR_THING4, 
    STR_WHATEVER, 

    STR_MAX   /* Always put this one at the end, as the counting starts at 0 */ 
        /* this one will be defined as the number of elements */ 
}  

static const char *foo[STR_MAX] = { 
    [STR_THING1] = "123", 
    [STR_THING2] = "456", 
    [STR_THING3] = "789", 
    [STR_THING4] = "987", 
    [STR_WHATEVER] = "OR Something else", 
}; 

Utilizzando nome di inizializzazione del programma è ancora corretta, anche se un valore di enumerazione modifiche.

for (i = STR_THING1; i<STR_MAX; i++) 
    puts(foo[i]); 

o in qualsiasi parte del programma con l'indice denominato

printf("thing2 is %s\n", foo[STR_THING3]); 

Questa tecnica può essere utilizzata per simulare fasci Ressource. Dichiarare uno enum e diversi array di stringhe con varianti di lingua e utilizzare un puntatore nel resto del programma. Semplice e veloce (specialmente su macchine a 64 bit in cui trovare l'indirizzo di una costante (stringa) possono essere relativamente costosi Edit:.. Il sizeof foo/sizeof * tecnica foo funziona ancora con questo

0

per alcune applicazioni, provare e Cattura avrebbe funzionato.

+0

Anche se C aveva 'try' e' catch', non vedo come siano rilevanti per iterare su un array. – Nefrubyr

Problemi correlati