This is not how you pass an array to a function:
for (i = 0; i < n; i++) {
dist(x[i], y[i]);
}
You probably thought that you were calling the function dist
once with an array containing all the values from x[0..n-1]
(and likewise for y
). This is not so. Since you are in a loop, you are calling the function for as many times as the loop runs, which in this case is n
times.
Furthermore, the values you are passing as parameters to the function are elements of type double
. It is not the array that you thought you were providing.
And I know that the error message seems strange. "Where is double*
coming from?" you may have asked yourself. Well the answer is simple:
Arrays cannot be passed to function.
Because of something called "type decay", arrays are converted into pointers to their first element (the base address) when they are used in expressions. The parameter types for dist
(dist(double x[3], double y[3]
) are exactly equivalent to dist(double* x, double* y)
. This means while you were incorrectly trying to pass double
's to the function the compiler reported that you couldn't convert them to pointers.
Passing the name of the array will pass a pointer to the first element. This will solve your main issue:
dist(x, y);
The reason you can still use the subscript operator x[n]
on a pointer is because the subscript operator is syntactical sugar for *(x + n)
. That is, a pointer offset by n
plus a dereference to give you the value at that address.
This type decay also entails another problem: since the array is being converted into a pointer, the size information that comes along with its type can't be determined. You can have a function that takes a double[100]
and pass it an array that holds 1 element because when the array decays to a pointer their types match exactly. There are a few ways around this:
- Make the parameter a reference/pointer to a function
- Use a standard library array class
Now, a pointer and a reference are two different things, but they can still be used to solve this problem. Using a reference to an array is different than actually passing in an array itself. References act as aliases to objects, and they are basically a pointer under the hood with a few exceptions (see the provided link). A reference is good enough for our example however, here is what it looks like:
double dist(double (&x)[3], double (&y)[3]);
Type decay will not occur here, and you have a guaranteed size because the compiler will report an error if an array of any other size was passed in.
A reference is useful, but it can be off putting for first timers. Fortunately the standard library provides us with an array class std::array
. No strange syntax is needed and it has a cleaner interface - no pointers!
#include <array>
double dist(std::array<double, 3> x, std::array<double, 3> y);
std::array<double, 3> x, y;
dist(x, y);