如果我有这样的结构:
struct S
{
int arr[10];
int x;
}
如果我有功能
void some_fun( struct S myS );
当我将结构S传递给该函数时,数组会被正确复制吗?还是必须将函数更改为:
void some_fun( struct S * myS ); ?
我已经测试过了(它在没有指针的情况下工作),但我对C/C++有点不安全,有时即使它是错误的,它也能工作。
当我将结构S传递给函数时,数组会被正确复制吗
是的,它将被复制。
我必须把函数改为:
void some_fun( struct S * myS )
吗
你可能想这么做有三个原因:
- 您希望避免复制-传递指针更便宜
-
您想要对
some_fun
内部的结构进行更改-指针允许您这样做;传递值不会 - 您希望降低堆栈溢出的风险-如果数组很大,传递值可能会使堆栈溢出。通过指针大大降低了这种风险
编辑:由于这是C++,您可以选择通过引用传递struct
:
void some_fun( S& myS ) // struct keyword is optional in C++
或
void some_fun( const S& myS ) // Do this if you do not plan on modifying myS
通过引用传递可以避免复制,类似于通过指针传递。与通过指针传递不同,通过引用传递向读取器指示传入的struct
引用了内存中的某个位置,而指针则为您提供了传递NULL
的选项。
如果您按值传递,就像您当前所做的那样,您的数组将由默认的复制构造函数复制(例如,请参阅此处:如何在复制控制函数中处理C++数组成员?)。
如果您决定通过指针传递,那么只有指向同一结构的指针才会传递到其中,因此您的数组不会被复制,您对数组(或结构的任何其他成员)所做的任何更改都会反映回您在函数之外访问的对象。
最终,决定选择哪种方法可以归结为以下几点:
- 你需要一份复印件吗?如果不是,通过const-reference会更好
- 是否需要修改与函数外的结构完全相同的结构?然后使用指针方法(或引用)
- 您是否需要函数中的副本,因为您想修改函数中的结构,但这些更改不应反映回调用位置?然后使用您当前使用的按值传递方法
您有3个选项:
本地复制版本:
void some_fun( struct S myS );
指针版本:
void some_fun( struct S* myS );
参考版本:
void some_fun( struct S& myS );
在后一个2中,对myS所做的更改将是持久的(影响原始实例)。在第一种情况下,您将获得本地副本。
它将传递数据结构的副本。这很好,除非您希望some_fun
更改传入的实际数据结构,否则您需要一个指针或引用。
当你放置一个带有const边界的数组时,它在运行时不再决定结构的大小。所以在你的情况下,数组是结构的一部分,而不是存储在不同的地方。简单地说:是的,它将被解析为函数!