Function returning fixed size array (coordinates) - How?

Hi!

I'm writing a program for Arduino, and I have a function which takes values from a few input functions, does some math and supposed to giva an array of x, y, z coordinates. Unfortunately I ran into the "cannot convert float* to float" problem, and I'm not too good with pointers.
Here is the relevant part of the code:

float ChToCoord (int ChA_T, int ChB_T, int ChA_S, int ChB_S, int ChA_Z, int ChB_Z)
{
  float coord[3];
  //Here comes the math part
 //Generating result
  coord[0] = x;
  coord[1] = y;
  coord[2] = z;
  return coord; 
}

What should I do to solve this problem. I'd appreciate any explanation about the solution.
Thank you in advance.

You'd need to return a structure here, because you CANNOT return the automatic array "coord", or a pointer to it.
Or you could pass "coord" into your function:

void ChToCoord (float* coord, int ChA_T, int ChB_T, int ChA_S, int ChB_S, int ChA_Z, int ChB_Z)
{
  //Here comes the math part
 //Generating result
  coord[0] = x;
  coord[1] = y;
  coord[2] = z;
}

the return value of your function is Float, you are trying to give it a float array

you cannot return an array from a function easily in c so the solution is to return a pointer to the array like so... (just add a star to the return value and return the address of the result)

(i haven't tested this to see if it will compile)

float* ChToCoord (int ChA_T, int ChB_T, int ChA_S, int ChB_S, int ChA_Z, int ChB_Z)
{
  float coord[3];
  //Here comes the math part
 //Generating result
  coord[0] = x;
  coord[1] = y;
  coord[2] = z;
  return (float*) &coord; 
}

To get a value you should use something like this

float* myXYZ = ChToCoord (1,2,3,4,5,6);
(float) myXYZ[0]; //will get x

@djabailey: Just because something compiles does not mean it is a good idea; returning a pointer to an automatic variable is ALWAYS a bad idea.

float* ChToCoord (int ChA_T, int ChB_T, int ChA_S, int ChB_S, int ChA_Z, int ChB_Z)
{
  float coord[3];
  //Here comes the math part
 //Generating result
  coord[0] = x;
  coord[1] = y;
  coord[2] = z;
  return (float*) &coord; // DON'T TRY THIS AT HOME, KIDS
}

AWOL:
@djabailey: Just because something compiles does not mean it is a good idea; returning a pointer to an automatic variable is ALWAYS a bad idea.

I suppose this is true but all you would need to do to solve that problem is allocate the memory manually with malloc();. (and free it later)

If it was done this way then you would need no variable definitions outside of the function.
Edit: I thought the result was somewhere else, nvm.

I'm a bit confused now. Is there a solution among the replies which can be used securely?
However djabailey-s solution compiles, I just don't understand what are the risks.
(To put it short: should I use it or no)

Thank you for your help.

Is there a solution among the replies which can be used securely?

Yes. See reply # 1.

However djabailey-s solution compiles, I just don't understand what are the risks.

Compiles and works are two completely different things. The space being pointed to by the value returned by djabailey's method no longer exists when the function ends. The pointer still points somewhere, but that space is subject to being overwritten at any time.

OK, thank you.
Although I don't understand if a function takes the pointer as a parameter, how does the result appear in this pointer, and how can I refer to this result.
(I am aware that I'm asking noob questions, but I'd like to understand how it works)

Although I don't understand if a function takes the pointer as a parameter, how does the result appear in this pointer, and how can I refer to this result.

That would all depend on what the pointer points to. In other words, the type of the pointer determines how you access what is pointed to.

Pointers to basic types are dereferenced using the * operator.
If int *p is an argument, int v = *p or *p = v will allow you to get/set the value that p points to.

If the pointer is to an array, standard array notation works just fine.

If the pointer is to an object, the -> operator is used.

The simplest and safest thing is to pass in the array by reference:

void ChToCoord (float (& coord) [3], int ChA_T, int ChB_T, int ChA_S, int ChB_S, int ChA_Z, int ChB_Z)
{
  //Here comes the math part
 //Generating result
  coord[0] = ChA_T;   // whatever
  coord[1] = ChB_T;
  coord[2] = ChA_S;
}

void setup ()
{
  float coord [3];
  ChToCoord (coord, 1, 2, 3, 4, 5,6 );
}

void loop () {}

That compiles, and works. It is safe because the array is declared by the caller. It works because it is passed by reference so ChToCoord can change it.

Well, the compiler says 'expected initializer before 'PortCoord'.
Here is the current code:

void PortCoord (float (& coord)[3], float RadT, float RadS, float Depth)
{
  float P_x = 0;
  float P_y = 0;
  float P_z = 0;
  //Some math
  //Generating result
  coord[0] = P_x;
  coord[1] = P_y;
  coord[2] = P_z;
}

void loop()
{
  //Computing coordinates
  float Coord_A[3]
  PortCoord (Coord_A, Ang_AT, Ang_AS. Depth_AZ);  //Compiler marks the error at this line
  float Coord_B[3]
  PortCoord (Coord_B, Ang_BT, Ang_BS. Depth_BZ);
}

The IDE doesn't like functions with reference arguments.
I think you have to explicitly supply a formal prototype.
It probably won't like the fact that you don't have a "setup" either.
Or a semicolon after the declaration of Coord_A.

Of course this is not the complete source code, I just copied the relevant parts.
Anyway, the semicolon was a good solution. Shame on me.
But after correctinc all these errors the compiler says ''PotCoord was not declared in this scope'
This function is declared after the loop, I don't know if this could be a problem.

the compiler says ''PotCoord was not declared in this scope'

I'm not surprised :wink:

See my earlier comment about functions with references.
If you declare "PortCoord" abouve "setup" and "loop", you should be good.

Batka:
But after correctinc all these errors the compiler says ''PotCoord was not declared in this scope'
This function is declared after the loop, I don't know if this could be a problem.

PortCoord, I hope you mean.

It is a good habit to get into, to declare functions before you use them. The IDE tries to generate function prototypes for you, but in the case of the function with references it failed (IDE bug, huh?).

If you don't want to move the whole function higher, then you put a "prototype" higher, like this:

void PortCoord (float (& coord)[3], float RadT, float RadS, float Depth);

Providing the prototype is earlier in the code than when you use it, you should be good.

If you are going to copy and paste snippets, at least paste them in the original order, that make the problem clearer.