2009-10-20 14 views
24

У меня есть массив структур, которые я создал где-то в моей программе.Итерация через массив C

Позже, я хочу пройти через это, но у меня нет размера массива.

Как я могу перебирать элементы? Или мне нужно хранить размер где-то?

ответ

18

Вы можете сохранить размер где-нибудь, или у вас может быть структура со специальным значением, установленным вами как часовым, так же, как «\ 0» указывает конец строки.

+4

+1 Обычно я использую указатели на структуры, чтобы я мог быть уверен, что 'NULL' является уникальным часовым. –

+5

Я думаю, что после модели с нулевой конечной строкой - это плохая идея. – hasen

+0

@hasen j: Я согласен, если вы не знаете, что вам всегда нужно перебирать весь массив каждый раз, и в этом случае часовое может немного прояснить код. Беда с дозорным вы можете в конечном итоге с O (N) поведение, где O (1) сделал бы, и не всегда это понимает. – quark

39

Если размер массива известен во время компиляции, вы можете использовать размер структуры для определения количества элементов.

struct foo fooarr[10]; 

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

Если не известно во время компиляции, вам нужно будет хранить размер где-то или создать специальное значение терминатора в конце массива.

+3

Агг вы быстрее! Я редактировал свой ответ lol :) – AntonioMO

+1

Действительно, но я бы предпочел использовать 'sizeof (fooarr [0])' или 'sizeof (* fooarr)', чем 'sizeof (struct foo)' – gatopeich

9

Это зависит. Если это динамически выделенный массив, т. Е. Вы создали его, вызывая malloc, то, как и другие, вы должны либо сохранить размер массива/количество элементов где-то, либо иметь дозорный элемент (структура со специальным значением, которая будет последний).

Если это статический массив, вы можете определить его размер/размер одного элемента. Например:

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

Обратите внимание, что, если это не глобальный, это работает только в объеме, где инициализируется массив, потому что если вы мимо нее к другой функции, которую он получает гнилой к указателю.

Надеюсь, это поможет.

+1

Речь идет не о том, динамически распределяется или нет. Речь идет о том, чтобы вы разрешили тип массива разлагаться на тип указателя. Например, я могу создать распределенный массив dynamicillay, подобный этому 'int (* a) [10] = malloc (sizeof * a)', и использовать 'sizeof * a/sizeof ** a' для« определения »количества элементов позже , Не нужно хранить размер отдельно. – AnT

+7

+1, хотя немного предпочтительнее делать 'sizeof (array)/sizeof (array [0])', так что он по-прежнему работает, если изменяется тип базового массива; эта форма также позволяет легко определить макрос, например. '#define ARRAY_COUNT (a) (sizeof (a)/(sizeof (a [0])). –

+0

То же самое касается передачи его функции. Все зависит от того, как вы его передаете. – AnT

0

Я думаю, что вы должны хранить размер где-то.

Модель модели с нулевым символом для определения длины массива - плохая идея. Например, получение размера массива будет O (N), когда это может быть очень легко O (1) в противном случае.

Учитывая, что хорошим решением может быть glib's Arrays, у них есть дополнительное преимущество при автоматическом расширении, если вам нужно добавить больше предметов.

P.S. чтобы быть полностью честным, я не использовал много glib, но я думаю, что это (очень) авторитетная библиотека.

Смежные вопросы