Некоторый пример кода для запуска вопроса:
#define FOO_COUNT 5
static const char *foo[] = {
"123",
"456",
"789",
"987",
"654"
};
Путем это обычно выполнялось бы с помощью итераций, что касается одного примера, следующее:
int i = FOO_COUNT;
while (--i >= 0) {
printf("%s\n", foo[i]);
Там должен так или иначе сделать, вышеупомянутое, явно не имея человека считает номер 5? В будущем я мог бы добавить/удалить элементы и забыть обновлять размер массива, таким образом повредив мое приложение.
Использовать sendinel в конце, например NULL:
static const char *foo[] = {
"123",
"456",
"789",
"987",
"654",
NULL
};
for (char *it = foo[0]; it != NULL; it++)
{
...
}
Обычный способ сделать это - закончить массив с NULL и выполнить итерацию до тех пор, пока вы не ударите по нему.
.Да.
int i = sizeof(foo) / sizeof(char*);
Примечание: Это относится только к статически выделенным массивам. Это не будет работать для malloc
ed или new
ed массивов.
size_t i = sizeof foo / sizeof *foo; // or sizeof foo / sizeof foo[0]
Это делит общее количество байт в массиве Foo (sizeof foo
) на количество байт в одном элементе (sizeof *foo
), давая количество элементов в массиве.
В C99 есть и другой метод, особенно если вам нужны именованные индексы, позволяющие, например, локализацию и тому подобное.
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",
};
При использовании именованного инициализатора программа остается корректной, даже если значение перечисления изменится.
for (i = STR_THING1; i<STR_MAX; i++)
puts(foo[i]);
или в любом месте программы с именованным индексом
printf("thing2 is %s\n", foo[STR_THING3]);
Этот прием можно использовать для имитации пучков ресурсов. Объявите один enum
и несколько строковых массивов с вариантами языка и используйте указатель в остальной части программы. Просто и быстро (особенно на 64-битных машинах, где получение адреса константы (строки) может быть относительно дорогостоящим.
Edit: техника sizeof foo/sizeof *foo все еще работает с этим.