2009-10-20 22 views
24

Tengo una serie de estructuras que he creado en algún lugar de mi programa.Iterar a través de una matriz C

Más tarde, quiero repetirlo, pero no tengo el tamaño de la matriz.

¿Cómo puedo iterar a través de los elementos? ¿O necesito guardar el tamaño en alguna parte?

Respuesta

18

Puede almacenar el tamaño en alguna parte, o puede tener una estructura con un conjunto de valores especiales que use como centinela, del mismo modo que '\ 0' indica el final de una cadena.

+4

+1 Normalmente utilizo punteros para estructurar de modo que pueda estar seguro de que 'NULL' es un centinela único. –

+5

Creo que seguir el modelo de cadena terminada en nulo es una mala idea – hasen

+0

@hasen j: estoy de acuerdo, a menos que sepa que siempre tiene que iterar a través de la matriz completa cada vez, en cuyo caso un centinela puede aclarar un poco el código. El problema con el centinela es que puede terminar con el comportamiento O (N) donde O (1) lo habría hecho, y no siempre darse cuenta. – quark

39

Si se conoce el tamaño de la matriz en tiempo de compilación, puede usar el tamaño de la estructura para determinar la cantidad de elementos.

struct foo fooarr[10]; 

for(i = 0; i < sizeof(fooarr)/sizeof(struct foo); i++) 
{ 
    do_something(fooarr[i].data); 
} 

Si no se conoce en tiempo de compilación, que se necesitan para almacenar un tamaño de alguna parte o crear un valor especial de terminación al final de la matriz.

+3

¡Aggh fuiste más rápido! Estaba editando mi respuesta lol :) – AntonioMO

+1

De hecho, pero prefiero usar 'sizeof (fooarr [0])' o 'sizeof (* fooarr)' que 'sizeof (struct foo)' – gatopeich

9

Depende. Si se trata de una matriz dinámicamente asignada, es decir, la creó llamando a malloc, entonces, como otros sugieren que debe guardar el tamaño de la matriz/número de elementos en algún lugar o tener un centinela (una estructura con un valor especial, que será el el último).

Si se trata de una matriz estática, puede dimensionar su tamaño/tamaño de un elemento. Por ejemplo:

int array[10], array_size; 
... 
array_size = sizeof(array)/sizeof(int); 

Tenga en cuenta que, a menos que sea global, esto sólo funciona en el ámbito en el que la inicialización del array, ya que si pasado a otra función, el fichero es decayeron a un puntero.

Espero que ayude.

+1

No se trata de si la matriz está dinámicamente asignado o no. Se trata de que permita que el tipo de matriz decaiga al tipo de puntero. Por ejemplo, puedo crear una matriz asignada de forma dinámica como esta 'int (* a) [10] = malloc (sizeof * a)' y usar 'sizeof * a/sizeof ** a' para" determinar "el número de elementos posteriores . No es necesario almacenar el tamaño por separado. – AnT

+7

+1, aunque es ligeramente preferible hacer 'sizeof (array)/sizeof (array [0])' para que funcione aún si el tipo de matriz subyacente cambia; esta forma también le permite definir fácilmente una macro, p. ej. '#define ARRAY_COUNT (a) (sizeof (a)/(sizeof (a [0]))'. –

+0

Lo mismo se aplica a pasarlo a una función. Todo depende de cómo lo pases. – AnT

0

Creo que deberías almacenar el tamaño en alguna parte.

El tipo de modelo de cadena terminada en nulo para determinar la longitud de la matriz es una mala idea. Por ejemplo, obtener el tamaño de la matriz será O (N) cuando podría muy bien haber sido O (1) en caso contrario.

Habiendo dicho eso, una buena solución podría ser glib's Arrays, tienen la ventaja adicional de expandirse automáticamente si necesita agregar más elementos.

P.S. para ser completamente honesto, no he usado mucho de simplista, pero creo que es una biblioteca (muy) respetable.

Cuestiones relacionadas