Thread: How to correctly call struct return as input for other struct functions ?

  1. #1
    Registered User
    Join Date
    Oct 2018
    Posts
    14

    How to correctly call struct return as input for other struct functions ?

    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.

    Here's how I define my struct

    Code:
    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

    Code:
    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.

    Code:
    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 :
    Code:
    course(12,10,10,8); grade(course()); //next function using input from function grade.
    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



  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Either will do.
    Code:
        // assign as you go
        struct Credit c = course(12,10,10,8);
        struct Intermediate i = grade(c);
    
        // merge calls
        struct Intermediate i2 = grade(course(12,10,10,8));
        //next function using input from function grade.
        // foo(bar(baz(grade(course(12,10,10,8)))));
    But you're not saving anything by squashing everything together.
    Given grade(course(12,10,10,8)), the compiler is going to create an invisible struct Credit temp to make it look as if you split things out.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Returning or taking structures as arguments to a function, by value, is valid. But "by value" puts some pressure on the stack and tends to create less optimized code. Usually is more efficient to use pointers... For exemple:
    Code:
    struct S
    {
      float a, b, c, d;
    };
    
    // returning the structure
    struct S f ( float x1, float y1, float x2, float y2 )
    {
      struct S result;
    
      result.a = x1;
      result.b = y1;
      result.c = x2;
      result.d = y2;
    
      return result;
    }
    
    void g ( struct S *resultptr, float x1, float y1, float x2, float y2 )
    {
      resultptr->a = x1;
      resultptr->b = y1;
      resultptr->c = x2;
      resultptr->d = y2;
    }
    The increase in complexity of g() has its advantages:

    1. If your structure is big, only a pointer is used as argument, i.e, the structure contents will not be copied to stack. This means less stack usage;
    2. You can keep only one instance of structure object on memory all times...

    Depending on the level of optimization and if your structure is short enough, these functions are almost identical. Try to compile the example with and without optimizations enabled and compare the created code in assembly.

    []s
    Fred

  4. #4
    Registered User
    Join Date
    Oct 2018
    Posts
    14
    Quote Originally Posted by flp1969 View Post
    Returning or taking structures as arguments to a function, by value, is valid. But "by value" puts some pressure on the stack and tends to create less optimized code. Usually is more efficient to use pointers... For exemple:
    Code:
    struct S
    {
      float a, b, c, d;
    };
    
    // returning the structure
    struct S f ( float x1, float y1, float x2, float y2 )
    {
      struct S result;
    
      result.a = x1;
      result.b = y1;
      result.c = x2;
      result.d = y2;
    
      return result;
    }
    
    void g ( struct S *resultptr, float x1, float y1, float x2, float y2 )
    {
      resultptr->a = x1;
      resultptr->b = y1;
      resultptr->c = x2;
      resultptr->d = y2;
    }
    The increase in complexity of g() has its advantages:

    1. If your structure is big, only a pointer is used as argument, i.e, the structure contents will not be copied to stack. This means less stack usage;
    2. You can keep only one instance of structure object on memory all times...

    Depending on the level of optimization and if your structure is short enough, these functions are almost identical. Try to compile the example with and without optimizations enabled and compare the created code in assembly.

    []s
    Fred
    Hi, thanks !
    I was aware I can use pointer as well. But to be honest I think I still don't fully understand pointer. For pointer, I passed the written exam but failed at coding exam. That's why I choose to use struct and I'm not working on complex data so as of now memory won't be a problem, but I'm working on understanding more about pointer. I'll try the example, thanks again !

  5. #5
    Registered User
    Join Date
    Oct 2018
    Posts
    14
    Quote Originally Posted by Salem View Post
    Either will do.
    Code:
        // assign as you go
        struct Credit c = course(12,10,10,8);
        struct Intermediate i = grade(c);
    
        // merge calls
        struct Intermediate i2 = grade(course(12,10,10,8));
        //next function using input from function grade.
        // foo(bar(baz(grade(course(12,10,10,8)))));
    But you're not saving anything by squashing everything together.
    Given grade(course(12,10,10,8)), the compiler is going to create an invisible struct Credit temp to make it look as if you split things out.
    I'm going with the first way to call them, since it's easier for me to understand. Thank you, it's working now.
    Last edited by pixie_laluna; 02-21-2019 at 08:06 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can't get input correctly with file functions
    By telmo_d in forum C Programming
    Replies: 3
    Last Post: 06-02-2015, 09:26 AM
  2. Call a CPP struct in c
    By biswa in forum C Programming
    Replies: 3
    Last Post: 03-05-2015, 01:18 PM
  3. Do I use struct correctly?
    By soawperL25 in forum C Programming
    Replies: 6
    Last Post: 12-15-2013, 07:28 PM
  4. char** within struct not printing correctly.
    By aj74 in forum C Programming
    Replies: 1
    Last Post: 11-12-2011, 11:11 AM
  5. How To Correctly Output of Struct Objects
    By NuNn in forum C Programming
    Replies: 10
    Last Post: 02-13-2009, 08:32 AM

Tags for this Thread