2009-12-28 19 views
6

un código de ejemplo para iniciar la pregunta:bucle de una matriz de tamaño fijo sin definir su tamaño en C

#define FOO_COUNT 5 

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

La forma en que esto normalmente se itera sobre, como por un ejemplo, es el siguiente:

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

¿Hay alguna forma de hacer lo anterior sin contar explícitamente con el número de humanos el número 5? En el futuro podría agregar/eliminar elementos y olvidar actualizar el tamaño de la matriz, rompiendo así mi aplicación.

Respuesta

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

sería esto todavía funciona si los punteros de caracteres en foo apuntaban a cadenas de caracteres de tamaño variable? – randombits

+0

Sí (15 límite char) –

+0

así que si cualquier elemento supera los 15 caracteres, esta comprobación fallará? probablemente mejor usar el centinela NULL entonces? gracias de nuevo – randombits

0

Sí.

sizeof (foo)/sizeof (char *)

es 5.

2

La manera habitual de hacer esto es poner fin a la matriz con NULL y recorrer hasta llegar a eso.

2

Sí.

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

Nota: Esto solo se aplica a las matrices asignadas estáticamente. No funcionará para malloc ed o new matrices ed.

12

Utilice un centinela en el extremo, tal como 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] 

Esto divide el número total de bytes de la matriz foo (sizeof foo) por el número de bytes en un solo elemento (sizeof *foo), dando la cantidad de elementos en la matriz.

2

También hay otro método en C99, especialmente si desea índices con nombre, lo que permite la localización de instancias y tal.

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

Al utilizar el inicializador con nombre, el programa sigue siendo correcto incluso si cambia un valor enum.

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

o en cualquier lugar en el programa con el índice llamado

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

Esta técnica se puede utilizar para simular los paquetes ressource. Declare uno enum y varias matrices de cadenas con variantes de idioma y use un puntero en el resto del programa. Sencillo y rápido (sobre todo en máquinas de 64 bits donde obtener la dirección de una constante (cadena) puede ser relativamente costosa Editar:.. El * técnica de foo sizeof foo/sizeof todavía funciona con este

0

Para algunas aplicaciones, tratar y Catch funcionaría.

+0

Incluso si C tenía 'try' y' catch', no veo cómo son relevantes para iterar sobre una matriz. – Nefrubyr

Cuestiones relacionadas