0

I'm new to C++ and am more used to Python. I have found posts answering this question, but I haven't been able to modify what I've found to work in my code. The goal of my function is simple, I want it to give me an array with x, y, and z coordinates where I give it polar coordinates. Here's what I have that isn't working:

double coordinate_finder(double coordinates[], double radius)
{
    double x = radius * sin(radians(90 - coordinates[0])) * cos(radians(coordinates[1]));
    double y = radius * sin(radians(90 - coordinates[0])) * sin(radians(coordinates[1]));
    double z = radius * cos(radians(90 - coordinates[0]));

    double XYZ[] = { x,y,z };
    return XYZ;

}

I feel like what I want it to do reads pretty easily but I'd like it to return XYZ when the function is called later in the code. By the way radians() is a function I made which converts degrees to radians.

4
  • Use std::array or std::vector instead. Commented Dec 12, 2022 at 19:38
  • you should look into the concept of pointer, if you want to do in the c way Commented Dec 12, 2022 at 19:38
  • 2
    use a point struct with x, y, and z members :/ Commented Dec 12, 2022 at 19:48
  • You can just overwrite the three values in coordinates if you want. But make sure to make internal copies if necessary. Commented Dec 12, 2022 at 19:49

2 Answers 2

7

You can't return a C-style array as-is, but you can return a pointer to a dynamically allocated array, eg:

double* coordinate_finder(double coordinates[], double radius)
{
    ...

    double *XYZ = new double[3];
    XYZ[0] = x;
    XYZ[1] = y;
    XYZ[2] = z;

    return XYZ;
}

And then the caller will have to free it:

double* xyz = coordinate_finder(...);
...
delete[] xyz;

This can be made safer for the caller using std::unique_ptr:

#include <memory>

std::unique_ptr<double[]> coordinate_finder(double coordinates[], double radius)
{
    ...

    auto XYZ = std::make_unique<double[]>(3);
    XYZ[0] = x;
    XYZ[1] = y;
    XYZ[2] = z;

    return XYZ;
}

Or std::vector:

#include <vector>

std::vector<double> coordinate_finder(double coordinates[], double radius)
{
    ...

    std::vector<double> XYZ(3);
    XYZ[0] = x;
    XYZ[1] = y;
    XYZ[2] = z;

    return XYZ;
}

Or a static variable (or thread_local, if multi-threading is a factor):

double* coordinate_finder(double coordinates[], double radius)
{
    static double XYZ[3];
    // thread_local double XYZ[3];

    ...

    XYZ[0] = x;
    XYZ[1] = y;
    XYZ[2] = z;

    return XYZ;
}

However, it would be better to simply return a std::array instead:

#include <array>

std::array<double,3> coordinate_finder(double coordinates[], double radius)
{
    ...
    std::array<double,3> XYZ = { x,y,z };
    return XYZ;
}

Or, a std::tuple:

#include <tuple>

std::tuple<double,double,double> coordinate_finder(double coordinates[], double radius)
{
    ...
    std::tuple<double,double,double> XYZ{ x,y,z };
    return XYZ;
}

Or, a custom struct/class:

struct xyz
{
    double x;
    double y;
    double z;
};

xyz coordinate_finder(double coordinates[], double radius)
{
    ...
    xyz XYZ{ x,y,z };
    return XYZ;
}
Sign up to request clarification or add additional context in comments.

2 Comments

You can return a C-style array that is malloc'ed by the function. You need to free it later. (But passing it as an argument is even simpler.)
May also want to include a vector<double> example, mentioning copy elision, as that'll be "cheap" creation as well. And/or std::move and how that would work.
1

The only way to return a C-style array from a function is to wrap it in a struct. Which is basically what std::array does.

auto coordinate_finder(double coordinates[], double radius)
{
    double x = radius * sin(radians(90 - coordinates[0])) * cos(radians(coordinates[1]));
    double y = radius * sin(radians(90 - coordinates[0])) * sin(radians(coordinates[1]));
    double z = radius * cos(radians(90 - coordinates[0]));

    struct {
        double XYZ[3];
    } ret = { {x, y, z} };

    return ret;
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.