Thread: Question on multiple return values

  1. #16
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    No you cannot return more than one thing from a function. Neither can you, as other people have put it, return an array. What you do with arrays is pass them in, like this:
    Code:
    int menu (int *myarray, size_t size);
    int myarray[] = { 0, /*principal */, 0 /* term */, 0 /* rate */ };
    menu(myarray, 3);
    Then menu would change the three values and when it returns those values are available in main(). The truth is, the variables never really left main() like they would at other times. You changed the variables through a pointer. You could also use multiple pointers for month, rate, and principle if you wanted.

    But I think menu() has more problems than that.

    Looking here:
    Code:
    switch (choice)
                  {
                         case 'a':
                              printf("What is the principal you wish to enter?:\n");
                              principal = getchar();
                              return principal;
                              break;
                         case 'b':
                              printf("What is the annual interest rate?:\n");
                              rate = getchar();
                              return rate;
                              break;
                         case 'c':
                              printf("How many months in which does the loan need to be paid?:\n");
                              months = getchar();
                              return months;
    I see that you're asking the user for input on his loan, but none of that data is being read exactly. It's highly unlikely that the loan data will fit in the integer that getchar returns. Read here:

    So unless the amounts are always ridiculously small... you know what, let's just admit you need numbers.

    Additionally, I think menu is responsible for far too much, or is at least poorly named. It should probably call at least one other function to calculate the loans and print them. I hope you're going in that direction and not trying to do everything in one function.

    HTH

    EDIT: You'll have to excuse me, it takes time to write posts, and sometimes things move along without me.

    You would read input into a normal variable first and then do something like:
    Code:
    array[0] = principal;
    array[1] = rate;
    array[2] = months;
    whiteflags.

    That definitely clears stuff up alot, thanks .
    As for calculation, you are right. I had planned to do that in the main function, however I never fixed my case, I was planning that after I started getting the variables to properly transfer back to main.

    As for::

    Code:
    int menu (int *myarray, size_t size);
    int myarray[] = { 0, /*principal */, 0 /* term */, 0 /* rate */ };
    menu(myarray, 3);
    I assume first line is prototype, second is declared variable under main, and third is the calling function?

    And then in my menu function, I define::

    Code:
    array[0] = principal;
    array[1] = rate;
    array[2] = months
    Each one of these after each of the latter variables are given a value such as this::

    Code:
     switch (choice)//Case used for gathering data
                  {
                         case 1://Gets data for principal
                              printf("What is the principal you wish to enter?:\n");
                              scanf("%d", &principal);
                              array[0] = principal;
                              break;
    And i definitely appreciate you taking time to write this out to help me understand, much obliged.
    Last edited by NinjaFish; 04-16-2011 at 07:05 PM.

  2. #17
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    I assume first line is prototype, second is declared variable under main, and third is the calling function?
    Yes, that's what I wanted to show you. The first line is a prototype, just to show what type an array becomes (a pointer to the first element). On the second line, the array is just an array from the calling function, and the third line is the actual call, like you guessed. And yes, you use this pointer just like you would an array.

  3. #18
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    Yes, that's what I wanted to show you. The first line is a prototype, just to show what type an array becomes (a pointer to the first element). On the second line, the array is just an array from the calling function, and the third line is the actual call, like you guessed. And yes, you use this pointer just like you would an array.
    I have a question on what size_t size represents in that. Never seen something like that before in examples and whatnot.

  4. #19
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by wikipedia
    size_t is an unsigned data type defined by several C/C++ standards (e.g., the C99 ISO/IEC 9899 standard) that is defined in stddef.h.[1] It can be further imported by inclusion of stdlib.h as this file internally sub includes stddef.h.[2]

    This type is used to represent the size of an object. Library functions that take or return sizes expect them to be of type or have the return type of size_t. Further, the most frequently used compiler-based operator sizeof should evaluate to a value that is compatible with size_t.
    Why I used it. Feel free to use another type you know, it really makes no difference here.

  5. #20
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    Why I used it. Feel free to use another type you know, it really makes no difference here.
    I guess this means I could simply just use int menu (int *myarray, int size_10) and it will give me the space I need to store them

    Also, do I need anything specific in my menu function for the pointer to use? I'm getting caught up on something and I think it's because I need to define the array, but it's using a pointer, and defining the pointer is getting it to hang on the myarray[0]=principal;
    Last edited by NinjaFish; 04-16-2011 at 07:40 PM.

  6. #21
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    size_t is just a number it isn't going to solve your memory allocation issues. Since we're passing in an array with three elements, I chose size_t as the type of variable to represent the value, 3, which the menu function can use to its own ends. It doesn't mean anything else.

  7. #22
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    size_t is just a number it isn't going to solve your memory allocation issues. Since we're passing in an array with three elements, I chose size_t as the type of variable to represent the value, 3, which the menu function can use to its own ends. It doesn't mean anything else.
    Oh alright.

  8. #23
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by NinjaFish View Post
    Also, do I need anything specific in my menu function for the pointer to use? I'm getting caught up on something and I think it's because I need to define the array, but it's using a pointer, and defining the pointer is getting it to hang on the myarray[0]=principal;
    You already have the pointer defined in the parameter list called int *myarray or whatever, and it should already have a value by the time you enter menu(). The idea is that myarray's value is the memory address of an array in main (the calling function) and when you do myarray[x] you're changing the xth element of the actual array.

  9. #24
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    You already have the pointer defined in the parameter list called int *myarray or whatever, and it should already have a value by the time you enter menu(). The idea is that myarray's value is the memory address of an array in main (the calling function) and when you do myarray[x] you're changing the xth element of the actual array.
    So keeping my int menu(void) function the same will still work?
    Because after changing each element in the array to what I want it to be, I return myarray[]; but the program will either compile and not even bring up the command prompt to show the program, or it will get compile errors on the first array-piece that pops up in my menu function.

  10. #25
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    So keeping my int menu(void) function the same will still work?
    No, you can't keep it like that. int menu (void) is a menu function empty parameter list that returns an int (whatever that means). You'd want to write it like I showed you before or it just doesn't work. Everything I've talked about was trying to teach you to avoid returning arrays from functions that you defined locally to those functions. By the time those functions return, those arrays are freed, they can't be used anymore. But you can pass a pointer to the first element of an array defined in the calling function. Specifically, you can do that because the array won't be freed until the calling function ends, and that won't happen before menu() ends.

    Let's try this:
    Code:
    int menu(int *myarray, size_t size);
    
    int main ( void )
    {
       int myarray[] = { 0, 0, 0 };
       menu(myarray, 3);
       return 0;
    }
    
    int menu ( int *myarray, size_t size )
    {
       int principal;
       int rate;
       int months;
       /* implement it here */
       myarray[0] = principal;
       myarray[1] = rate;
       myarray[2] = months;
       return 0;
    }
    This is a lot less compact then before, but nothing has really changed. Looking at main() alone, it is calling menu, so it is the calling function. menu is the called function that uses main()'s array.

  11. #26
    Registered User
    Join Date
    Feb 2011
    Posts
    62
    Quote Originally Posted by whiteflags View Post
    No, you can't keep it like that. int menu (void) is a menu function empty parameter list that returns an int (whatever that means). You'd want to write it like I showed you before or it just doesn't work. Everything I've talked about was trying to teach you to avoid returning arrays from functions that you defined locally to those functions. By the time those functions return, those arrays are freed, they can't be used anymore. But you can pass a pointer to the first element of an array defined in the calling function. Specifically, you can do that because the array won't be freed until the calling function ends, and that won't happen before menu() ends.

    Let's try this:
    Code:
    int menu(int *myarray, size_t size);
    
    int main ( void )
    {
       int myarray[] = { 0, 0, 0 };
       menu(myarray, 3);
       return 0;
    }
    
    int menu ( int *myarray, size_t size )
    {
       int principal;
       int rate;
       int months;
       /* implement it here */
       myarray[0] = principal;
       myarray[1] = rate;
       myarray[2] = months;
       return 0;
    }
    This is a lot less compact then before, but nothing has really changed. Looking at main() alone, it is calling menu, so it is the calling function. menu is the called function that uses main()'s array.
    Now I understand what you mean. I never realized that the values we're automatically passed into the main function this way. I thought you had to return the entire array back. But changing my return to return 0; and adding the int *myarray, int size_t size made it work. Thanks alot for all your help. Now that I understand it, fixing this up, adding the rest and doing the other part of it will be much easier. Thanks alot

  12. #27
    Registered User
    Join Date
    Sep 2010
    Posts
    69
    Quote Originally Posted by whiteflags View Post
    No you cannot return more than one thing from a function. Neither can you, as other people have put it, return an array. What you do with arrays is pass them in, like this:
    Well, saying that is not exactly correct either.
    From the perspective of the beginner, they don't care about the symantics.
    They just want to know if they can return multiple values.
    And, yes, you can return multiple values within an array.

    True, you can pass an array to a called function like so:
    Code:
        call_MyFunction(myarray);
    and yes,
    you can also return an array (or more specifically, a pointer to an array) to a calling function,
    like so:
    Code:
        myArray = call_MyFunction();
    we do it all the time.
    Whether we are returning an array or a pointer to an array, it's symantics to the beginner.
    The point is, it can be done and is done.
    To imply that C cannot return an array places a restriction on C which does not exist.

    Example:
    Code:
        float *ReturnFltArray(void);     // prototype: function which returns a pointer to an array
    
    int main()
    {
        float *array;             // declare a pointer to an array
    
        array = ReturnFltArray();    // call function which returns (values in an) array
    
        printf("array0=%f\n", array[0]);     // output data
        printf("array1=%f\n", array[1]);
        printf("array2=%f\n", array[2]);
    
        return 0;
    }
    
    
    float *ReturnFltArray()
    {
        static float MyArray[3];        // declare an array of 3 elements
    
        MyArray[0] = 1.1;         // assign values to array elements
        MyArray[1] = 2.2;
        MyArray[2] = 3.3;
    
        return MyArray;           // voila
    }

  13. #28
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Steve A. View Post
    Whether we are returning an array or a pointer to an array, it's symantics to the beginner.
    The point is, it can be done and is done.
    To imply that C cannot return an array places a restriction on C which does not exist.

    Example:
    Code:
        float *ReturnFltArray(void);     // prototype: function which returns a pointer to an array
    
    int main()
    {
        float *array;             // declare a pointer to an array
    
        array = ReturnFltArray();    // call function which returns (values in an) array
    
        printf("array0=%f\n", array[0]);     // output data
        printf("array1=%f\n", array[1]);
        printf("array2=%f\n", array[2]);
    
        return 0;
    }
    
    
    float *ReturnFltArray()
    {
        static float MyArray[3];        // declare an array of 3 elements
    
        MyArray[0] = 1.1;         // assign values to array elements
        MyArray[1] = 2.2;
        MyArray[2] = 3.3;
    
        return MyArray;           // voila
    }
    Yes but what you're not telling our beginner friends is that this only works because you've declared the array as static. You are not "returning the array" you are returning a pointer to a static variable inside your function and choosing to treat it as an array. Remove the static modifier and see what happens.

    C cannot return an actual array because it doesn't know how big it is. C does not track array sizes or the size of dynamically allocated memory. You as a programmer are required to keep track of that... or you can end up with lots of memory leaks and buffer overruns.

    Plus the one quirk I'm sure you didn't think about... once you declare an array or other variable as static, you have no way to dispose of it. It is stored as part of the program's executable image and will occupy memory until the program exits and the memory space is released back to the system... Think about what that means to a program with 100,000 static variables floating around.

    Finally.. what happens to your variables if you call the function a second time?

    It does these guys no good whatsoever to mislead them about the capabilities of the language.
    Last edited by CommonTater; 04-18-2011 at 01:49 PM.

  14. #29
    Registered User
    Join Date
    Sep 2010
    Posts
    69
    Quote Originally Posted by CommonTater
    Yes but what you're not telling our beginner friends is that this only works because you've declared the array as static.
    Not true.
    It's clearly in the code.

    You are not "returning the array" you are returning a pointer to a static variable inside your function and choosing to treat it as an array.
    No, it is an array.
    It is clearly declared as an array.

    Remove the static modifier and see what happens.
    All that is clearly indicated within the code.
    I'm not keeping any secrets here.
    The beginner is going to learn about scope eventually.

    C cannot return an actual array because it doesn't know how big it is.
    No, actually, its because an array doesn't fit into the EAX register, but, a pointer to the array does.
    But, that's being too technical, isn't it.

    C does not track array sizes or the size of dynamically allocated memory. You as a programmer are required to keep track of that... or you can end up with lots of memory leaks and buffer overruns.
    As any good programmer should.

    Plus the one quirk I'm sure you didn't think about... once you declare an array or other variable as static, you have no way to dispose of it.
    No, actually Tater, I did think about it. And I knew you would bring it up.
    I'm well aware of the consequences of static variables.
    However, they are an established part of the C programming language.
    And, nearly all programming languages.
    You cannot ignore that they do exist.

    It will occupy memory until the program exits and the memory space is released back to the system... Think about what that means to a program with 100,000 static variables floating around.
    A slight exaggeration, I'm sure.
    There can, in some instances where a function is called repetatively, be a slight advantage.

    Finally.. what happens to your variables if you call the function a second time?
    Absolutely nothing.
    The array is pre-existing and is used like a normal variable or array.

    It does these guys no good whatsoever to mislead them about the capabilities of the language.
    Mislead ??
    Explain then why the text books and documentation go to lengths to describe the usage of these "bad" features.
    Why then, are they part of the ANSI Standard ?
    Last edited by Steve A.; 04-18-2011 at 01:52 PM.

  15. #30
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I'd be more comfortable with calling menu like: menu(&principal, &rate, &months);, with those variables being defined in main.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how is it possible to return multiple values?
    By Masterx in forum C++ Programming
    Replies: 5
    Last Post: 05-04-2009, 06:49 PM
  2. How to use return values
    By Furious5k in forum C++ Programming
    Replies: 3
    Last Post: 02-05-2009, 09:07 PM
  3. Return values
    By pritin in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2007, 05:24 PM
  4. Replies: 4
    Last Post: 03-11-2005, 05:45 PM
  5. C++ .Net DLL return values
    By shuesty in forum C++ Programming
    Replies: 15
    Last Post: 01-19-2003, 05:39 PM