To expand a little bit on some of the answers here...
In C, when an array identifier appears in a context other than as an operand to either & or sizeof, the type of the identifier is implicitly converted from "N-element array of T" to "pointer to T", and its value is implicitly set to the address of the first element in the array (which is the same as the address of the array itself). That's why when you just pass the array identifier as an argument to a function, the function receives a pointer to the base type, rather than an array. Since you can't tell how big an array is just by looking at the pointer to the first element, you have to pass the size in 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 a couple of alternate ways of passing arrays to functions.
There is such a thing as a pointer to an array of T, as opposed to a pointer to T. You would declare such a pointer as
T (*p)[N];
In this case, p is a pointer to an N-element array of T (as opposed to T *p[N], where p is an N-element array of pointer to T). So you could pass a pointer to the array as opposed to 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 array size is fixed, since a pointer to a 10-element array of T is a different type from a pointer to a 20-element array of T.
A 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 aren't mucking around with pointers. The disadvantage is that the array size is fixed (again, a 10-element array of T is a different type from a 20-element array of T).