简体   繁体   中英

Passing structure as an argument in function

I have a question about passing arguments in function. Like I discovered that I can pass arguments of structure in two ways:

First :

name_t* foo(name_t* foo)
{
    //do some changes with structure
    return foo->something
}

Second :

name_t foo(name_t foo)
{
    //do some changes with structure
    return foo.something
}

What is difference between this approaches?

How does it put in memory?

Whether there are underwater rocks when I use first approach with second in the same function? For example, when two arguments passed in same function and first would equal to second and vice versa.

Like that:

name_t* foo(name_t* foo, name_t foo2)
{
    //do some changes with structures
    foo->something = foo2.something;
    return foo;
}

Thanks.

The First version passes a pointer to the caller's structure. Any changes made through the pointer will affect the caller's structure.

The Second version passes a copy of the caller's structure, because C is a call-by-value language. Any changes only affect the local copy, not the caller's structure. However, it's a shallow copy; if the structure contains pointer to other structures, they are not copied recursively, and changes to those referenced structures will affect the originals.

The last example should be fine. foo2 is a copy of the caller's structure, you can make changes to it without affecting the caller. Then you can modify the caller's structure when you assign through the foo pointer. There's no aliasing problem since one is a copy.

In addition to the vary important points raised in above comments (parameter name hides function name, and inconsistent function signature in first and second clips).

I would like to offer that you should consider the physical size of your structure when deciding how to create and pass instances of structures:

typedef struct name_t {
  char title[256];
  int something;
} name_t;

int my_function(name_t n) {
    // this function cannot change the sender's copy of n
    return strlen(n.title);
}

int my-by_ref(name_t * n) {
    // this function has the ability to change n and reflect changes back
    // do work
    return ...
}

On a system that represents int as 4 bytes, each instance of this structure will occupy 260 bytes.

name_t person = {"John Doe", 1}; // 260 bytes on stack
int len_title = my_function(person); // pushes another 260 bytes onto the stack
int result = my_by_ref(&person); // pushes the number of bytes a pointer takes 
...

This is a contrived example, but sending by reference will require the CPU to copy the address of person (typically 8 bytes, but depends on you OS), rather than 260 bytes. That can add up if this structure needs to be processed frequently.

There are many more efficient ways to implement such a task, each of which carries certain responsibilities, such as making sure you do not return pointers to data that will go out of scope after the function completes, which are outside the scope of your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM