Click here to Skip to main content
15,867,308 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I want to pass the return value of function A to function B, and pass the return value of function B to function C. I'm using struct. I can pass from struct to function and then main, but turn out I'm still confuse how to pass struct return to a function which return another struct as well.


When I put the first function as input of the second function, it expected input (indeed the first function needs input) but I wanted to call the return value not the function. I'm confuse. Any advice ? Thank you

What I have tried:

Here's how I define my struct
struct Credit {
    float A;
    float B;
    float C;
};

struct Intermediate {
   float math;
   float bio;
};


Then I have my first function, with manual input value from the user. And from this function I return the value of A, B and C
struct Credit course (float x1, float y1, float x2, float y2)
{ 
   // simple arithmetic calculation...
 
    struct Credit result;
    result.A = A;
    result.B = B;
    result.C = C; 
    return result;
}

In my second function, I need to get input from A,B,C from the previous function. And then return the value of math, bio as input from next function.
struct Intermediate grade (struct Credit point)
{
   // simple calculation involving return result of previous function (A, B, C)
   // I call the value using point.A , point.B and point.C
    
    struct Intermediate result;
    result.math = math;
    result.bio = bio;
    return result;
    //result from this function will be used for the next function
}

Here's my main :
course(12,10,10,8);
grade(course());
//next function using input from function grade.
Posted
Updated 20-Feb-19 21:40pm

Overlooking the fact that the code you've provided won't compile at all ...

Your function course() returns a struct, but that doesn't get assigned in the little bit of main() you've provided. Going back to basics - suppose we have a function f that takes an int as an argument, and returns an int value:
C++
int f(int x); /* declares a function taking an int which returns an int */

f(2);  /* calls f with value 2 as the parameter - return value is thrown away */
f();   /* ERROR: no parameter given to f() */

int i;
i = f(2);                    /* OK: assigns return value from f() to i */
printf("i = %d\n", i);       /* we can then use the i later */
printf("f(3) = %d\n", f(3)); /* OK : return value of f() is passed to printf() */ 

In your case, you want to do either of the following:
C++
struct Credit MyCredit;
struct Intermediate MyIntermediate;
MyCredit = course(12, 10, 10, 8);
MyIntermediate = grade(MyCredit);
or
C++
struct  Intermediate MyIntermediate = grade(credit(12, 10, 10, 8));

You would use the second example if you didn't need to use the return value of course() again later.

Normally, though, we do not pass or return structs to or from functions. That's because C uses pass-by-value, which means that when you pass or return a struct the compiler copies the struct to/from the stack as needed. For a small struct, that's generally not a problem. But if you have a large struct that takes up several kilobytes (or even megabytes!), you're copying that data for each function call or return. An alternative approach might be:
C++
void course(struct Credit *credit, float x1, float x2, float y1, float y2)
{
   credit->A = x1+x2;
   /* and so on for other members of credit */
}

int main()
{
   struct Credit MyCredit;
   course(&MyCredit, 12, 10, 10, 8); /* passes address of MyCredit to course() */
   /* more code here ... */
   return 0;
}

In this case, we never add more than the size of a pointer (normally 4 bytes for 32 bit system, 8 bytes for 64 bit systems) to the stack.
 
Share this answer
 
Comments
CPallini 20-Feb-19 17:12pm    
5.
Stefan_Lang 21-Feb-19 3:21am    
I don't agree with the last part. Check out GotW 90: factories ( https://herbsutter.com/2013/05/30/gotw-90-solution-factories/ ) which I happened to read yesterday. The course() function is clearly a factory function and the recommended way to return the factory-constructed object is exactly what the OP did: return the object by value. There is no performance hit!

Even though the article uses C++ terminology and refers to C++ mechanics, the exact same is true for C code with respect to performance: in the end there is no reason why the C compiler cannot be as performant as the C++ compiler.

Your solution introduces an additional problem that the OP code doesn't have: passing a null pointer to the factory. Easy to catch but you *have* to catch it. And you didn't.
Although solution 1 is essentially correct, this is what I would change, to make your code not only work, but work well:
C++
struct Credit course(...) // leave this function as is
...
struct Intermediate grade(struct Credit& credit) { //pass by reference!
 ... // leave the function code as is
}
int main () {
   Intermediate my_grade = grade(course(12, 10, 10, 8));
   ...
}

Explanation:
- the call to course constructs a struct of type Credit and returns it
- the compiler makes sure that the struct which was created locally is reused rather than copied; there is no performance hit for creating a copy!
- a reference to this Credit struct is directly passed into the call stack for the call to grade(); again, no copy is needed - only a reference is passed
- like course(), grade() returns the internally constructed Intermediate struct and returns it without a copy

Other benefit: no need to declare a variable of type Credit in main - if you ever decide to change the return type, you don't need to change your main function!
 
Share this answer
 
v2
Comments
lock&_lock 21-Feb-19 9:03am    
Hi, thanks ! The first solution provided me with pointer, I don't quite understand pointer yet eventhough it's more beneficial, that's why I stick with struct.
I'm aware that the issue is how I call them in my main. I'm going with "struct Intermediate grade (struct Credit point)" (without passing reference) and call it with "struct Intermediate i = grade(course(12,10,10,8));". It works now. Also, of course I tried your solution with passing with reference, unfortunately I encountered many errors. Since there's many benefit with passing reference, I'll try to address the errors on it and see if it works. Thanks again.
Stefan_Lang 21-Feb-19 10:43am    
I think a lot of the details explained in both solutions are beyond your current level of programming.

For now, all you need to know is that when a function returns a value, you must take care to actually use that value when you call the function. Either assign it to a local variable (in your example, the variable i which gets assigned the return value from the call to grade()), or use it in a place where the return value is expected within an expression, or as a function argument (in your example, grade() expects an argument of type Credit, which the call to course() conveniently provides as a return value).
Stefan_Lang 21-Feb-19 10:54am    
As for using pointers and references, these are very important concepts in C and C++. If you plan to improve your programming skills, do look up tutorials and articles on these topics.

In short, both do not contain a full object (struct or otherwise), but only point to where the object can be found in memory. Therefore it can be more efficient to pass a pointer or reference to a function (or back as a return value) than passing a struct, if the struct is very large.

However, Pointers are also one of the biggest sources of programming errors in C/C++. Therefore you really should spend some time learning to use them correctly.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900