Ok, here I go :-)
Ways to Work with Arrays in C
There are many ways to deal with an array in C. For the rest, I will talk about string* (and use the strings variable, which is of type string* ). This is because t[] "effectively decomposes" into t* , and char* is the string type "C". Thus, string* is a pointer to the string "C". This glosses over a number of pedantic issues in C wrt “arrays” and “pointers”. (Remember: only because a pointer can be obtained since p[i] does not make the type an array in C.)
Now strings (of type string* ) are not able to find out its size - it represents only a pointer to a string or, possibly, NULL. Now let's look at some of the ways we can “know” size:
Use the sentinel value. In this, I assume that the NULL value is used as the watchdog value (or it could be -1 for the "array" of integers, etc.). Remember that C does not have such a requirement that arrays have a sentinel value, so this approach, like the next two, is just a convention.
string* p; for (p = strings; p != NULL; p++) { doStuff(*p); }
Track the size of the array from the outside.
void display(int count, string* strings) { for (int i = 0; i < count; i++) { doStuff(strings[i]); } }
Bind the array and length together.
struct mystrarray_t { int size; string* strings; } void display(struct mystrarray_t arr) { for (int i = 0; i < arr.size i++) { doStuff(arr.strings[i]); } }
Java uses this last approach.
Each array object in Java has a fixed size, which can be accessed as arr.length . There is a special mask of byte code for this work (arrays are very magical in Java), but at the language level it is displayed as just a read-only integer that never changes (remember that each array object has a fixed size), Compilers and JVM / JIT can use this fact to optimize the loop.
Unlike C, Java ensures that attempting to access the index outside the bounds will throw an exception (for performance reasons, even if it was not found, this would require the JVM to track the length of each array). In C, this is just undefined behavior. For example, if the control value was not in the object (read "required available memory"), then example # 1 would lead to a buffer overflow.
However, there is nothing to prevent the use of sentinel values ​​in Java . Unlike form C with a sentinel value, it is also safe from IndexOutOfBoundExceptions (IOOB) because the length limit is the limit. Sentinel is just early.
// So we can add up to 2 extra names later String names[] = { "Fred", "Barney", null, null }; // This uses a sentinel *and* is free of an over-run or IOB Exception for (String n : names) { if (n == null) { break; } doStuff(n); }
Or perhaps allow an IOOB exception, because we are doing something stupid, how to ignore the fact that arrays know their length: (See wrt "performance" comments).
// -- THERE IS NO EFFECTIVE PERFORMANCE GAIN -- // Can ONLY add 1 more name since sentinel now required to // cleanly detect termination condition. // Unlike C the behavior is still well-defined, just ill-behaving. String names[] = { "Fred", "Barney", null, null }; for (int i = 0;; i++) { String n = strings[i]; if (n == null) { break; } doStuff(n); }
On the other hand, I would refuse to use such primitive code - it is better to just use the appropriate data type, such as List, in almost all cases.
Happy coding.