Lucia
Lucia

Reputation: 911

Returning function values in pair C

I am solving a problem in C, but I have difficulty in connecting parts of my script.

I define a type pair as follows:

typedef struct pair {
    double x, y;
} pair;

Now, I would like to return the values in the function as pairs but I don't understand how to do that.

pair predcorr(double t, double x, double y, double h) { 

    double Newx = x + 1.0/2.0 * h * (dxdt(t, x, y) + dxdt(t+h, x+(h*dxdt(t, x, y)), y+(h*dxdt(t, x, y))));
    double Newy = y + 1.0/2.0 * h * (dydt(t, x, y) + dydt(t+h, x+(h*dydt(t, x, y)), y+(h*dydt(t, x, y))));
    return ????,

How that would work, is it possible to provide me with some explanation?

Upvotes: 0

Views: 2862

Answers (4)

David C. Rankin
David C. Rankin

Reputation: 84569

The easiest way to explain passing and returning structure values is with an example. When passing complex data structures to/from functions, the struct is usually passed and returned as a pointer. This also requires that your function prototype return be consistent with the type you want returned. (this could just as well been declared as a void functions since the values for the pair are filled in during execution of the function itself.)

Note: to pass pair as a pointer, the struct address is passed to predcorr. So if you declare a static instance of pair you need to precede it with the & address of operator.

Here is a short example with made-up functions to show you how this would work with your code:

#include <stdio.h>

typedef struct pair {
    double x, y;
} pair;

double dxdt (double a, double b, double c)   /* totally made up functions */
{  return a*a + 2 * a * b + c * c;  }

double dydt (double a, double b, double c) 
{  return 2*a*a - 4 * a * b - 2 * c * c; }

/* function accepts and returns a pointer to struct pair */
pair *predcorr (pair *ptr, double t, double x, double y, double h) { 

    double Newx = x + 1.0/2.0 * h * (dxdt(t, x, y) + dxdt(t+h, x+(h*dxdt(t, x, y)), y+(h*dxdt(t, x, y))));
    double Newy = y + 1.0/2.0 * h * (dydt(t, x, y) + dydt(t+h, x+(h*dydt(t, x, y)), y+(h*dydt(t, x, y))));

    ptr-> x = Newx;
    ptr-> y = Newy;

    return ptr;
}

int main () {

    double t = 5;           /* made up initial example values   */
    double x = 2;
    double y = 7;
    double h = 3;

    pair mypair = {0,0};    /* declare instance of struct pair  */


    predcorr (&mypair, t, x, y, h); /* call predcorr pass ptr   */

    /* print the values as returned in mypair */
    printf ("\nThe Newx/Newy values are:\n\n");
    printf ("  Newx : %lf\n  Newy : %lf\n\n", mypair.x, mypair.y);

    return 0;
}

output of (made-up) values:

$./bin/dxyt

The Newx/Newy values are:

  Newx : 132336.500000
  Newy : -185504.000000

Your other option is to dynamically allocate new storage for a struct pair in predcorr each time it is called. You would not have to pass a pointer to the function, and you would simply assign the return of the function call to a pointer of struct pair in your main function. The only additional requirement is that you are now responsible for freeing the data associated with the return to prevent memory-leaks in your code. It's not hard, but takes just a little more effort that can confuse at this state of the game. Look it over and let me know if you have any questions.

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134346

In C, return can only return one variable. To return more than one value [variable], you need to

  1. either pass the variables as reference.
  2. Use a structure to hold all the variables required to return a value.

Using second approach, you can use something like..

in caller :

typedef struct pair {
double a, b;
} pair;
pair pr;
pr  = predcorr(m, n, o, p);

the function

pair predcorr(double t, double x, double y, double h) 
{ 
    pair result;

    result.a  = x + 1.0/2.0 * h * (dxdt(t, x, y) + dxdt(t+h, x+(h*dxdt(t, x, y)), y+(h*dxdt(t, x, y))));
    result.b  = y + 1.0/2.0 * h * (dydt(t, x, y) + dydt(t+h, x+(h*dydt(t, x, y)), y+(h*dydt(t, x, y))));

    return result;
}

Notice the return type specified for the function. So, you should obviously return a variable of type pair.

Upvotes: 0

Philipp Murry
Philipp Murry

Reputation: 1682

The function has pair as it's return type. Therefore, you must return something of type pair - this should already give you a hint on what to do. You have to create a variable of this type, fill it with values (Newx and Newy) and return it. It works the same way as if you wanted to return an integer: Create it, fill it, return it.

Upvotes: 3

Boyko Perfanov
Boyko Perfanov

Reputation: 3047

pair result;
result.x = ...;
result.y = ...;
return result;

Upvotes: 0

Related Questions