Thread: Need help with returning variables from a function

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    11

    Need help with returning variables from a function

    hi guys, I need a little help with this program I'm writing. I need it to send the information in My_Temp to the main function. But the problem I'm having is it's in an array so I'm a little loss. Any help would be appreciated! Thank you!

    Code:
    #include <stdio.h>
    #include <math.h>
    double input ()
    
    
    int main ()
    
    
    {
        
    
    
        double input ();
    
    
        return 0; //End Program
    }
    
    
    double input () //Input Array
    {
        int My_Temp; //Declare Variables
        double fahr[25];    
        
        printf("Please input the number of temperatures you would like to enter: "); //User Input
        scanf("%i", &My_Temp);
            
            if (My_Temp < 0 || My_Temp > 25) //Check User Input
                
                {
                printf("Invalid Entry");
                scanf("%i", &My_Temp);
                }
        
        printf("Please enter %i temperatures", My_Temp); //User Input
        scanf("%lf", fahr[My_Temp]);
            
            if (fahr[My_Temp] > 175.0 || fahr[My_Temp] < -175.0) //Check User Input
                
                {
                printf("Invalid Entry");
                scanf("%lf", fahr[My_Temp]);
                }
            
            return (fahr[My_Temp]); //Return Temperatures
    }

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    There is no way to directly return an array in C. The quick explanation is arrays aren't "first class citizens" in C, meaning you can't treat them like "normal" variables, such as a single int, double, char, etc. When you return an array that is local to a function you are actually returning a pointer to the beginning of the array. Since the function is done, all it's local variables cease to exist, so your pointer doesn't actually point to the array anymore, just to where it was. The data there is unreliable, accessing it is undefined. In general, for "returning" arrays in C you have a few options:

    1. Declare an array in main, and pass it into your input() function.
    2. Have input() return a pointer to a double (double *), and allocate memory for the array inside input(), via malloc/calloc. Pass back the pointer to that allocated memory.
    3. Declare fahr to be static. That means that the array is local (only visible within the function), but it's storage duration (a.k.a. lifespan) is the whole time the program is running. This means the pointer you return is valid after the function is done.


    For your situation, however, you only have one good option, #1. The second option is no good because you don't want to keep allocating a new array every time you call the function and it's hard to keep track of whether you already allocated memory for the array. The third option would work for a simple program like this (you only need to put the word 'static' at the beginning of the declaration of 'fahr'), it's just not as ideal as #1.

    Also, it's a good idea to #define some constants instead of using magic numbers.
    Code:
    #define NUM_TEMPS     25
    #define MAX_TEMP       175.0
    
    // void here isn't necessary, but I like to be specific
    int main(void)
    {
        double fahr[NUM_TEMPS];
    
        input(fahr);  // call input() and pass it the array to store data in
        return 0;
    }
    
    // void here means return nothing -- we pass in the array to fill, so no need to return anything
    void input(double fahr[])
    {
        ...
        if (My_temp < 0 || My_temp > NUM_TEMPS)
        ...
        if (fahr[My_temp] < -MAX_TEMP
    }
    I think you get the idea.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    11
    Quote Originally Posted by anduril462 View Post
    There is no way to directly return an array in C. The quick explanation is arrays aren't "first class citizens" in C, meaning you can't treat them like "normal" variables, such as a single int, double, char, etc. When you return an array that is local to a function you are actually returning a pointer to the beginning of the array. Since the function is done, all it's local variables cease to exist, so your pointer doesn't actually point to the array anymore, just to where it was. The data there is unreliable, accessing it is undefined. In general, for "returning" arrays in C you have a few options:

    1. Declare an array in main, and pass it into your input() function.
    2. Have input() return a pointer to a double (double *), and allocate memory for the array inside input(), via malloc/calloc. Pass back the pointer to that allocated memory.
    3. Declare fahr to be static. That means that the array is local (only visible within the function), but it's storage duration (a.k.a. lifespan) is the whole time the program is running. This means the pointer you return is valid after the function is done.


    For your situation, however, you only have one good option, #1. The second option is no good because you don't want to keep allocating a new array every time you call the function and it's hard to keep track of whether you already allocated memory for the array. The third option would work for a simple program like this (you only need to put the word 'static' at the beginning of the declaration of 'fahr'), it's just not as ideal as #1.

    Also, it's a good idea to #define some constants instead of using magic numbers.
    Code:
    #define NUM_TEMPS     25
    #define MAX_TEMP       175.0
    
    // void here isn't necessary, but I like to be specific
    int main(void)
    {
        double fahr[NUM_TEMPS];
    
        input(fahr);  // call input() and pass it the array to store data in
        return 0;
    }
    
    // void here means return nothing -- we pass in the array to fill, so no need to return anything
    void input(double fahr[])
    {
        ...
        if (My_temp < 0 || My_temp > NUM_TEMPS)
        ...
        if (fahr[My_temp] < -MAX_TEMP
    }
    I think you get the idea.

    But the thing is is I need Num_Temps to be able to change. So if the user wants to be able to in out on 16 temperatures they would only have to put 16. With it being stuck as 25 then I'm can't have it changed.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Quote Originally Posted by alias View Post
    But the thing is is I need Num_Temps to be able to change. So if the user wants to be able to in out on 16 temperatures they would only have to put 16. With it being stuck as 25 then I'm can't have it changed.
    If you need it to be dynamic, your only option is to malloc an array. I don't recommend allocating in the input function, but rather passing a pre-allocated block with the size as the second parameter to input. Another possible option is to make a struct that contains the allocated block and size. This helps to keep malloc and frees from being scattered all over. If you malloc and free within the same general location, you'll be able to manage memory better.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Cynic View Post
    If you need it to be dynamic, your only option is to malloc an array.
    Actually, C99 allows for variable length arrays, where the length in your declaration can be any integer variable. That variable must be declared and set to something useful before you do this of course (good thing C99 doesn't require all your variable declarations at the top of the function). For example:
    Code:
    int num_temps;
    get_num_temps(&num_temps);
    double fahr[num_temps];
    input(num_temps, fahr);
    Whether those features are supported by the compiler/implementation (a surprising number of compilers still aren't totally C99 compliant, after 13 years), and whether the OP's professor allows such constructs is unknown.

    @alias:
    The following is very good advice if you go the malloc route.
    Quote Originally Posted by Cynic View Post
    I don't recommend allocating in the input function, but rather passing a pre-allocated block with the size as the second parameter to input. Another possible option is to make a struct that contains the allocated block and size. This helps to keep malloc and frees from being scattered all over. If you malloc and free within the same general location, you'll be able to manage memory better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 09-06-2011, 02:59 PM
  2. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM
  3. Returning two variables?
    By Twig in forum C Programming
    Replies: 2
    Last Post: 07-08-2006, 09:59 AM
  4. Returning 2 Variables?
    By mr_spanky202 in forum C Programming
    Replies: 8
    Last Post: 04-06-2003, 03:01 AM
  5. Returning Variables
    By drdroid in forum C++ Programming
    Replies: 6
    Last Post: 09-08-2002, 02:37 PM