2009-10-20 19 views
24

Mam tablicę struktur, które utworzyłem gdzieś w moim programie.Powtarzanie przez macierz C

Później chcę iterację, ale nie mam rozmiaru tablicy.

Jak mogę iterować przez elementy? Czy muszę gdzieś przechowywać rozmiar?

Odpowiedz

18

można przechowywać rozmiar gdzieś, czy można mieć struct ze specjalnym zestawem wartości, który służy jako strażnik, tak samo jak „\ 0” oznacza koniec łańcucha.

+4

+1 Zazwyczaj używam wskaźników do struktur, aby upewnić się, że 'NULL' jest unikalnym wskaźnikiem. –

+5

Myślę, że po modelu zakończonym znakiem null jest zły pomysł – hasen

+0

@hasen j: Zgadzam się, chyba że wiesz, że zawsze musisz iterować po całej tablicy za każdym razem, w którym to przypadku wskaźnik może nieco wyjaśnić kod. Kłopot ze strażnikiem polega na tym, że możesz skończyć z O (N) zachowaniem, które zrobiłby O (1), i nie zawsze sobie z tego sprawę. – quark

39

Jeśli rozmiar tablicy jest znany w czasie kompilacji, można użyć rozmiar struktury w celu określenia liczby elementów.

struct foo fooarr[10]; 

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

Jeśli nie jest znany w czasie kompilacji, trzeba będzie przechowywać rozmiar gdzieś lub utworzyć specjalną wartość terminatora na końcu tablicy.

+3

Aggh, ty byłeś szybszy! Edytowałem swoją odpowiedź lol :) – AntonioMO

+1

Rzeczywiście, ale wolałbym użyć 'sizeof (fooarr [0])' lub 'sizeof (* fooarr)' niż 'sizeof (struct foo)' – gatopeich

9

To zależy. Jeśli jest to tablica przydzielana dynamicznie, to znaczy, że stworzyłeś ją nazywając malloc, a następnie, jak sugerują inni, musisz albo zapisać rozmiar tablicy/liczby elementów gdzieś, albo mieć wartownika (strukturę ze specjalną wartością, która będzie ostatni).

Jeśli jest to statyczna tablica, można sizeof to wielkość/rozmiar jednego elementu. Na przykład:

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

zauważyć, że o ile nie jest to globalny, to działa tylko w zakresie, w którym inicjowane tablicę, bo jeśli obok niego do innej funkcji pobiera zepsute do wskaźnika.

Mam nadzieję, że to pomaga.

+1

Nie chodzi o to, czy tablica jest przydzielane dynamicznie lub nie. Chodzi o to, o ile typ tablicy ma się rozpadać na typ wskaźnika. Na przykład mogę utworzyć tablicę alokowaną dynamicznie, taką jak ta 'int (* a) [10] = malloc (sizeof * a) 'i użyj' sizeof * a/sizeof ** a', aby "określić" liczbę elementów później . Nie musisz osobno przechowywać rozmiaru. – AnT

+7

+1, chociaż nieco lepiej jest zrobić 'sizeof (array)/sizeof (array [0])' tak, aby nadal działało, jeśli zmienia się podstawowy typ tablicy; ten formularz pozwala również na łatwe definiowanie makra, np. '#define ARRAY_COUNT (a) (sizeof (a)/(sizeof (a [0]))'. –

+0

To samo dotyczy przekazywania go do funkcji. Wszystko zależy od tego, jak je przekazujesz. – AnT

0

Myślę, że powinieneś przechowywać gdzieś rozmiar.

Typ null-terminowany łańcuch do określania długości tablicy to zły pomysł. Na przykład, uzyskanie rozmiaru tablicy będzie O (N), kiedy może bardzo łatwo być O (1) w przeciwnym razie.

uwzględniając powiedział, że dobrym rozwiązaniem może być glib's Arrays, mają dodatkową zaletę rozwija się automatycznie, jeśli trzeba dodać kolejne elementy.

P.S. szczerze mówiąc, nie używałem zbyt wiele glib, ale myślę, że jest to (bardzo) renomowana biblioteka.