将结构作为参数传递给函数
Passing structure as an argument in function
我对在函数中传递参数有疑问。就像我发现我可以通过两种方式传递结构参数:
第一个:
name_t* foo(name_t* foo)
{
//do some changes with structure
return foo->something
}
第二:
name_t foo(name_t foo)
{
//do some changes with structure
return foo.something
}
这两种方法有什么区别?
它是如何放入内存的?
当我在同一个函数中使用first方法和second方法时是否有水下岩石?例如,当两个参数在同一个函数中传递时,第一个等于第二个,反之亦然。
像这样:
name_t* foo(name_t* foo, name_t foo2)
{
//do some changes with structures
foo->something = foo2.something;
return foo;
}
谢谢。
First 版本传递一个指向调用者结构的指针。通过指针所做的任何更改都会影响调用者的结构。
Second 版本传递调用者结构的副本,因为 C 是一种 call-by-value 语言。任何更改只会影响本地副本,不会影响调用者的结构。但是,它是一个浅拷贝;如果结构包含指向其他结构的指针,则不会递归复制它们,对那些引用结构的更改将影响原始结构。
最后一个例子应该没问题。 foo2
是调用者结构的副本,您可以对其进行更改而不影响调用者。那么通过foo
指针赋值的时候就可以修改调用者的结构体了。没有别名问题,因为一个是副本。
除了上面评论中提出的不同重点(参数名称隐藏函数名称,以及第一和第二个片段中的函数签名不一致)。
我想建议您在决定如何创建和传递结构实例时应考虑结构的物理大小:
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 ...
}
在将 int
表示为 4 个字节的系统上,此结构的每个实例将占用 260 个字节。
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
...
这是一个人为的例子,但通过引用发送将需要 CPU 复制人的地址(通常为 8 个字节,但取决于您 OS),而不是 260 个字节。如果需要经常处理此结构,则可以加起来。
有许多更有效的方法来实现这样的任务,每一种方法都承担着特定的责任,例如确保您没有 return 指向函数完成后将超出范围的数据的指针,这不在你的问题范围内。
我对在函数中传递参数有疑问。就像我发现我可以通过两种方式传递结构参数:
第一个:
name_t* foo(name_t* foo)
{
//do some changes with structure
return foo->something
}
第二:
name_t foo(name_t foo)
{
//do some changes with structure
return foo.something
}
这两种方法有什么区别?
它是如何放入内存的?
当我在同一个函数中使用first方法和second方法时是否有水下岩石?例如,当两个参数在同一个函数中传递时,第一个等于第二个,反之亦然。
像这样:
name_t* foo(name_t* foo, name_t foo2)
{
//do some changes with structures
foo->something = foo2.something;
return foo;
}
谢谢。
First 版本传递一个指向调用者结构的指针。通过指针所做的任何更改都会影响调用者的结构。
Second 版本传递调用者结构的副本,因为 C 是一种 call-by-value 语言。任何更改只会影响本地副本,不会影响调用者的结构。但是,它是一个浅拷贝;如果结构包含指向其他结构的指针,则不会递归复制它们,对那些引用结构的更改将影响原始结构。
最后一个例子应该没问题。 foo2
是调用者结构的副本,您可以对其进行更改而不影响调用者。那么通过foo
指针赋值的时候就可以修改调用者的结构体了。没有别名问题,因为一个是副本。
除了上面评论中提出的不同重点(参数名称隐藏函数名称,以及第一和第二个片段中的函数签名不一致)。
我想建议您在决定如何创建和传递结构实例时应考虑结构的物理大小:
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 ...
}
在将 int
表示为 4 个字节的系统上,此结构的每个实例将占用 260 个字节。
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
...
这是一个人为的例子,但通过引用发送将需要 CPU 复制人的地址(通常为 8 个字节,但取决于您 OS),而不是 260 个字节。如果需要经常处理此结构,则可以加起来。
有许多更有效的方法来实现这样的任务,每一种方法都承担着特定的责任,例如确保您没有 return 指向函数完成后将超出范围的数据的指针,这不在你的问题范围内。