You could do something like this, which is nicely analogous to null termination for strings:
char * strings[] = {
"one",
"two",
NULL
};
You could print those strings using a loop like this:
char **pp;
for(pp = strings; pp != NULL; pp++)
printf("%s\n", *pp);
But when I say "you could do", I mean it. There's no rule saying you must do it this way. (This is in contrast to the strings themselves, where you really must use null-character termination if you construct your own strings and if you want yours to be compatible with strcpy, printf, etc.)
The NULL termination I have shown works well for an array of pointers. It can be harder to pick an appropriate sentinel value for other types, such as array of int. (If you know your numbers are all positive, you can use 0 or -1 as a sentinel, but if your array has both positive and negative numbers, you may be stuck.)
The other possibility is to maintain a separate count:
char * strings[] = {
"one",
"two"
};
int nstrings = 2;
int i;
for(i = 0; i < nstrings; i++)
printf("%s\n", strings[i]);
Rather than counting the strings by hand and explicitly initializing nstrings to 2, the better technique is to let the compiler do it for you:
int nstrings = sizeof(strings) / sizeof(strings[0];
sizeof(strings) gives you the size of the whole array in bytes, while sizeof(strings[0]) gives you the size of one element -- that is, one pointer -- in bytes, and the division therefore gives you the number of entries, which is what you want.
Using sizeof and dividing like that is a pefectly common and perfectly legal idiom, but it's mildly obscure, so I prefer to encapsulate it (and make it a bit more self-documenting) with a macro, like this:
#define SIZEOFARRAY(a) (sizeof(a) / sizeof(a[0])
int nstrings = SIZEOFARRAY(strings);