# Thread: Returning more than one value from a function

1. ## Returning more than one value from a function

Hey!
I am fairly new to C so forgive me if things arent extremely clear

but basically I'm trying to figure out the full scope of what I can and cant do.

I have a program that takes the longitude and latitude in degrees and then
sends it to a function which then calculates its rectangular co-ordinates ..x,y,z

the problems lies here. im sending two double values lat and longitude to the function.. and i want to return 3 double values x,y,z i know i could write it to a data file then retrieve it outside the function etc.. but i would like to know how to do this with pointers and arrays... if it can be done at all
here is the main function... the programer defined function is "rectangle"

Code:
```#include "stdafx.h"
#include <stdio.h>
#include <math.h>

#define PI 3.14159265

int main(void)
{
double lat1,*lat[4], long1, lat2, long2, x1, y1, z1, x2, y2, z2, theta, rho, lengtha, lengthb;
double gc_distance(double x);
double rectangle(double *str);
double retrive[4];
double *ptr1;
double ptr2[4];
ptr1=retrive;
printf("enter latitude and longitude of the first city\n");
scanf("%f%f",&lat1,&long1);

retrive[1]=lat1;
retrive[2]=lat2;

ptr2 = rectangle(ptr1);

printf("\n\n%.2f %.2f %.2f\n",ptr2[1],ptr2[2],ptr2[3]);

printf("enter latitude and longitude of the second city\n");
scanf("%f%f",&lat2,&long2);

return 0;
}```
and the rectangle function is

Code:
```double rectangle(double *str)
{
double phi, theta, rho, x1, y1, z1, x2, y2, z2;
double test[4];
double *ptr;
ptr = test;

phi= (90 - str[1])*(PI/180);
theta=(360 - str[2])*(PI/180);
rho= 3960;

x1 = rho*sin(phi)*cos(theta);
y1 = rho*sin(phi)*sin(theta);
z1 = rho*cos(phi);

printf("%.2f %.2f %.2f\n\n", x1,y1,z1);
test[1] = x1;
test[2] = y1;
test[3] = z1;
printf("%.2f %.2f %.2f\n\n", str[1],str[2],str[3]);
return (*ptr);
}```

the way it is set up right now is not working... it wont let me assign ptr2 = rectangle(ptr1) it says expression must be modifieable value...
any help would be much appreciated.. thanks

2. You need a struct. Create the struct and fill in its x, y, z and then return it.
There are also lots of unnecessary variables in your functions.
Warnings:
Code:
```Warning	1	warning C4101: 'y2' : unreferenced local variable		11
Warning	2	warning C4101: 'x2' : unreferenced local variable		11
Warning	3	warning C4101: 'y1' : unreferenced local variable		11
Warning	4	warning C4101: 'lat' : unreferenced local variable		11
Warning	5	warning C4101: 'z2' : unreferenced local variable		11
Warning	6	warning C4101: 'rho' : unreferenced local variable		11
Warning	7	warning C4101: 'lengtha' : unreferenced local variable		11
Warning	8	warning C4101: 'x1' : unreferenced local variable		11
Warning	9	warning C4101: 'lengthb' : unreferenced local variable		11
Warning	10	warning C4101: 'theta' : unreferenced local variable		11
Warning	11	warning C4101: 'z1' : unreferenced local variable		11
Warning	12	warning C4101: 'y2' : unreferenced local variable		35
Warning	13	warning C4101: 'x2' : unreferenced local variable		35
Warning	14	warning C4101: 'z2' : unreferenced local variable		35
Warning	17	warning C6001: Using uninitialized memory 'lat2': Lines: 11, 12, 14, 16, 17, 19, 20		20
Warning	18	warning C4700: uninitialized local variable 'lat2' used		20
Warning	19	warning C4700: uninitialized local variable 'ptr2' used		24```
I also removed some variables that are unnecessary:
Code:
```#include "stdafx.h"
#include <stdio.h>
#include <math.h>

#define PI 3.14159265
double gc_distance(double x);
double rectangle(double *str);

int main(void)
{
double lat1,*lat[4], long1, lat2, long2, x1, y1, z1, x2, y2, z2, theta, rho, lengtha, lengthb;
double retrive[4];
//double *ptr1;
double ptr2[4];
//ptr1=retrive;
printf("enter latitude and longitude of the first city\n");
scanf("%f%f",&lat1,&long1);

retrive[1]=lat1;
retrive[2]=lat2;

rectangle(retrive);

printf("\n\n%.2f %.2f %.2f\n",ptr2[1],ptr2[2],ptr2[3]);

printf("enter latitude and longitude of the second city\n");
scanf("%f%f",&lat2,&long2);

return 0;
}

double rectangle(double *str)
{
double phi, theta, rho, x1, y1, z1, x2, y2, z2;
double test[4];
//double *ptr;
//ptr = test;

phi= (90 - str[1])*(PI/180);
theta=(360 - str[2])*(PI/180);
rho= 3960;

x1 = rho*sin(phi)*cos(theta);
y1 = rho*sin(phi)*sin(theta);
z1 = rho*cos(phi);

printf("%.2f %.2f %.2f\n\n", x1,y1,z1);
test[1] = x1;
test[2] = y1;
test[3] = z1;
printf("%.2f %.2f %.2f\n\n", str[1],str[2],str[3]);
//return (*ptr);
return 0.0;
}```

3. Or you could pass in a pointer to an array of three doubles, put the values you want to return into the array when you get them. If you passed the array by reference, they will be available to the calling function.

4. Thanks for the quick reply, yes the variables, it was at a point where i was just trying everything got quite frustrated so singed up for this and posted it before cleaning everything out sorry..

would it be possible to post a brief example of setting up a structure in that situation?

5. Usually I would leave that as an exercise. Have you looked up structs?

6. yes I have, I have not got the chance to work with them much and to be honest if Kbriggs says it can be done with a pointer and an array thats what im really trying to do right now to better understand pointers and arrays...

I'm haveing a hell of a time with them i've tried passing the point to an array and it continually says the data types dont mach this or that

7. Arrays work too, but they're more work and more error prone.
Example:
Code:
```bool rectangle(double* str, double* buffer, size_t buffer_size)
{
if (buffer_size / sizeof(*buffer) < 3)
return false; // ERROR! POSSIBLE OVERFLOW!
...
buffer[0] = x;
buffer[1] = y;
buffer[2] = z;
return true;
}

//How to call it:
double buffer[3];
rectangle(indata, buffer, sizeof(buffer));```
Vs structs:
Code:
```coord_t rectangle(double* str)
{
...
coord_t coord = { x, y, z };
return coord;
}

//How to call it:
coord_t coords = rectangle(indata);```

8. thanks elysia that worked perfectly I swear i tried very similar steps before but instead of haveing the function defined as a boolean i had it a double.. maybe this is what was causeing a large part of my problems?
new code excludeing the error handling.. would haveing rectangle function defined as a double cause the issues?

Code:
```#include "stdafx.h"
#include <stdio.h>
#include <math.h>

#define PI 3.14159265

int main(void)
{
double lat1,*lat[4], long1, lat2, long2;
double gc_distance(double x);
double buffer[3];
bool rectangle(double* str, double* buffer);
double array1[3];

printf("enter latitude and longitude of the first city\n");
scanf("%lf%lf",&lat1,&long1);
printf("enter latitude and longitude of the second city\n");
scanf("%lf%lf",&lat2,&long2);
array1[0]= lat1;
array1[1]= long1;
rectangle(array1,buffer);

printf("%.2f  %.2f  %.2f",buffer[0],buffer[1],buffer[2]);

getchar();
getchar();
return 0;
}

bool rectangle(double* str, double* buffer)
{

double phi, theta, rho, x1, y1, z1, gamma, dot, dist1, dist2;

/* first city */
phi= (90 - str[0])*(PI/180);
theta=(360 - str[1])*(PI/180);
rho= 3960;
buffer[0] = rho*sin(phi)*cos(theta);
buffer[1] = rho*sin(phi)*sin(theta);
buffer[2] = rho*cos(phi);

return true;```

9. Changing the return type would change little, if anything. But if you're going to pass an array to a function then you literally must pass its size and do a sanity check so that you won't write outside the array. I included this check in my example.
This is critical for computer security: http://cpwiki.sourceforge.net/buffer_overrun

10. Structures are definitely better. In Elysia's example you could use coord.x, coord.y, coord.z. Which seems better than coord[0], coord[1], coord[2]. You might easily confuse an index. Structures offer much greater clarity.