To expand some answers a bit here ...
In C, when an array identifier appears in a context other than the operand for either or sizeof, the identifier type is implicitly converted from an "N-element array T" to a "pointer to T" and its value is implicitly set to the address of the first element in the array (which matches the address of the array itself). Therefore, when you simply pass an array identifier as an argument to a function, the function gets a pointer to the base type, not the array. Since you cannot determine how large the array is, just by looking at the pointer to the first element, you must pass the size as a separate parameter.
struct Coordinate { int x; int y; }; void SomeMethod(struct Coordinate *coordinates, size_t numCoordinates) { ... coordinates[i].x = ...; coordinates[i].y = ...; ... } int main (void) { struct Coordinate coordinates[10]; ... SomeMethod (coordinates, sizeof coordinates / sizeof *coordinates); ... }
There are several alternative ways to pass arrays to functions.
There is such a thing as a pointer to an array from T, unlike a pointer to T. You would indicate a pointer like
T (*p)[N];
In this case, p is a pointer to an N-element array from T (unlike T * p [N], where p is an N-element array of a pointer to T). Thus, you can pass a pointer to an array, rather than a pointer to the first element:
struct Coordinate { int x; int y }; void SomeMethod(struct Coordinate (*coordinates)[10]) { ... (*coordinates)[i].x = ...; (*coordinates)[i].y = ...; ... } int main(void) { struct Coordinate coordinates[10]; ... SomeMethod(&coordinates); ... }
The disadvantage of this method is that the size of the array is fixed, since a pointer to a 10-element array T is different from a pointer to a 20-element array T.
The third method is to wrap the array in a struct:
struct Coordinate { int x; int y; }; struct CoordinateWrapper { struct Coordinate coordinates[10]; }; void SomeMethod(struct CoordinateWrapper wrapper) { ... wrapper.coordinates[i].x = ...; wrapper.coordinates[i].y = ...; ... } int main(void) { struct CoordinateWrapper wrapper; ... SomeMethod(wrapper); ... }
The advantage of this method is that you do not twitch with pointers. The disadvantage is that the size of the array is fixed (again, the 10-element array T is another type from the 20-element array T).