Looping a fixed size array without defining its size in C
Some example code to start the question:
#define FOO_COUNT 5
stat开发者_JS百科ic const char *foo[] = {
"123",
"456",
"789",
"987",
"654"
};
The way this would normally be iterated over, as for one example, is the following:
int i = FOO_COUNT;
while (--i >= 0) {
printf("%s\n", foo[i]);
Is there anyway to do the above without explicitly having the human count the number 5? In the future I might add/remove elements and forget to update the size of the array, thus breaking my app.
int i = sizeof(foo)/sizeof(foo[0]);
Use a sentinel at the end, such as NULL:
static const char *foo[] = {
"123",
"456",
"789",
"987",
"654",
NULL
};
for (char *it = foo[0]; it != NULL; it++)
{
...
}
The usual way to do this is to end the array with NULL and iterate until you hit that.
Yes.
int i = sizeof(foo) / sizeof(char*);
Note: This only applies to statically allocated arrays. It will not work for malloc
ed or new
ed arrays.
size_t i = sizeof foo / sizeof *foo; // or sizeof foo / sizeof foo[0]
This divides the total number of bytes in the foo array (sizeof foo
) by the number of bytes in a single element (sizeof *foo
), giving the number of elements in the array.
There's also another method in C99, especially if you want named indexes, allowing for instance localization and such.
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",
};
By using named initializer the program still is correct even if an enum value changes.
for (i = STR_THING1; i<STR_MAX; i++)
puts(foo[i]);
or anywhere in the program with the named index
printf("thing2 is %s\n", foo[STR_THING3]);
This technique can be used to simulate ressource bundles. Declare one enum
and several string arrays with language variants and use a pointer in the rest of the program. Simple and fast (especially on 64bit machines where getting the address of a constant (string) can be relatively costly.
Edit: the sizeof foo/sizeof *foo technique still works with this.
Yes.
sizeof(foo)/sizeof(char*)
is 5.
For some application, try and Catch would work.
精彩评论