Thread: Returning more than one value from a function

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    16

    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. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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;
    }
    Last edited by Elysia; 06-03-2010 at 01:04 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    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. #4
    Registered User
    Join Date
    Jun 2010
    Posts
    16
    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. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Usually I would leave that as an exercise. Have you looked up structs?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2010
    Posts
    16
    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. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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);
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Jun 2010
    Posts
    16
    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. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    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
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  3. returning pointers from a function
    By curlious in forum C++ Programming
    Replies: 2
    Last Post: 12-28-2003, 11:37 PM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM