0

I need a function to return a 2x2 rotation matrix, something like:

float matrix(float phi){
  float R[2][2] = { {cos(phi), -sin(phi)}, 
                    {sin(phi),  cos(phi)} };
return R;
}

But it doesn't work obviously. What is the best way to write this function?

0

2 Answers 2

-1

One way would be to make the function return a pointer to float ie create a new array and return it

float** matrix(float phi){
   float** R= (float **)malloc(2 * 2 * sizeof(float));
   R[0][0]= cos(phi);
   R[0][1]= -sin(phi);
   R[1][0]= sin(phi);
   R[1][1]= cos(phi);
   return R;
}

Do not forget to free the memory once you do not need it any more!

However, I would advise you not to do it but rather pass the array to the function. See How can I declare an array of variable size (Globally) and Is using malloc() and free() a really bad idea on Arduino? for an explanation why it might not be a good idea to allocate the memory in the function (in an embedded aka Arduino environment)

3
  • This is not how you create a 2D array. Here, R[0] and R[1] are uninitialized float * pointers, and R[0][0] is dereferencing one such pointer. This is undefined behavior likely to crash the program. Apr 26, 2019 at 11:46
  • Wow... C++ is too hard to program.
    – 2012User
    Apr 26, 2019 at 12:11
  • @ Edgar Bonet, so how can I write this function?
    – 2012User
    Apr 26, 2019 at 12:13
1

You cannot return an array from a function. There are several alternatives, though. One of them is to allocate the memory for the array within the function, as suggested by user2912328's answer. I would not recommend this approach though, for the reasons already stated in that answer.

For an overview of the other possible options, see this response to the question “Returning an int array from a function”.

Now, your problem is slightly different, as you have a 2D array. The C/C++ syntax for dealing with those is tricky, but here we go.

If you opt for the “static array” solution (make sure you understand the implications), you could write:

float (*matrix(float phi))[2]
{
    static float R[2][2];
    R[0][0] = cos(phi);
    R[0][1] = -sin(phi);
    R[1][0] = sin(phi);
    R[1][1] = cos(phi);
    return R;
}

and you would use it like this:

float (*M)[2] = matrix(angle);

If you instead let the caller manage the allocation, then

float (*matrix(float phi, float (*R)[2]))[2]
{
    R[0][0] = cos(phi);
    R[0][1] = -sin(phi);
    R[1][0] = sin(phi);
    R[1][1] = cos(phi);
    return R;
}

Or maybe forgo the return value to make the syntax simpler:

void matrix(float phi, float (*R)[2])
{
    R[0][0] = cos(phi);
    R[0][1] = -sin(phi);
    R[1][0] = sin(phi);
    R[1][1] = cos(phi);
}

and you could use it like:

float M[2][2];
matrix(angle, M);

The “array in a struct” solution is more straightforward.

If the syntax for dealing with 2D arrays bothers you (which would be understandable), you can instead use arrays of pointers to 1D arrays. This are easier to deal with but trickier to allocate. That approach could warrant another answer...


Edit: One common way to simplify a convoluted array syntax is to use typedefs. As an identifier for a 2x2 array decays to a pointer to an array of 2 floats, you can name that type:

typedef float (*pmatrix)[2];  // pointer to an array of 2 floats

Then, instead of

float (*matrix(float phi))[2] { ... }
...
float (*M)[2] = matrix(angle);

you would write

pmatrix matrix(float phi) { ... }
...
pmatrix M = matrix(angle);
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.