什么时候通过值?

亲爱的大家。 我想知道是否有一些情况你会有目的地通过C中的值传递一个参数。让我重新说一下。 你什么时候有目的地使用C的大对象传值? 或者,您何时关心对象参数是否完全复制到局部变量中?

编辑 :现在我考虑一下,如果你可以避免指针,那么。 如今,“深度”复制对于小型应用程序中的大部分内容都是可能的,而浅层复制更容易出现指针错误。 也许。

在C(sans const引用)中,您通过值传递有3个原因。

  • 您不希望接收函数在其上下文之外修改源。 这是学校教授的标准理由,因为它为什么要通过价值。

  • 如果值适合于体系结构的寄存器中,则按值传递会更便宜 – 如果编译器非常智能,则可能会寄存。 按值传递意味着没有指针创建,也没有取消引用来获取传入的值。这是一个很小的收益,但在某些情况下会增加。

  • 按值传递需要更少的输入。 一个很容易确定的理由,但确实如此。

const关键字否定了大多数原因1,但原因2仍然有价值,是我通过值传递的主要原因。

嗯,首先,如果你想改变它。

想象一下以下人为的function:

int getNextCharAndCount (char *pCh); 

每次调用它时,它通过从函数返回计数并通过字符指针设置字符,从列表中返回下一个最常用的字符。

我很难找到另一个需要指针的用例,如果你只想使用(但不是改变)底层角色。 这并不意味着当然不存在:-)

另外,我不确定你所讨论的是深层/浅层复制。 这往往适用于具有指针的结构,其中浅拷贝仅复制顶层,而深拷贝则复制所有层。

你所指的是传值和传递参考。

传递引用更便宜,因为您不必创建对象的本地副本。 如果函数需要本地副本(出于任何目的) – 可能就是这种情况。

我遵循以下规则:

  • 按值传递内置类型(int,char,double,float …)
  • 通过(const)引用传递类和结构。 没有涉及指针处理。

从来没有遇到过这种工作方式的任何问题。

如果我们要对此迂腐,那么C中的每一个都是值得传递的。 您可以按值传递指针,而不是按值传递实际对象,但它仍然是按值传递。

无论如何,为什么要传递整个对象而不是指向对象的指针? 好吧,首先,您的编译器可能能够优化调用,以便在封面下只复制一个地址。 另外/或者,一旦引入指针,由于别名,编译器可能无法对函数进行尽可能多的优化。 它不易出错,不必记住取消引用。 调用者也可以确定他传入的内容没有被修改(const并不能真正保证这一点,它可以被 – 危险地抛弃)

我不认为你关于字符的争论有用。 即使您的char在概念上是1个字节,函数调用的每个参数通常都会转换为整个(字大小的)寄存器,并且为了提高效率而转换到堆栈上相同的空间量。

如果你真的想要(并且我相信,也可以返回它们),你可以在栈上传递一个完整的struct作为参数。 这是避免分配内存和不必担心指针卫生的一种方法。

根据调用堆栈的构建方式,char和char *可能占用相同的空间。 通常,在字边界上对齐值是更好的。 访问字边界上的32位指针的成本可能远低于在非字边界上访问它的成本。

如果您不希望修改值,则按值传递会更安全。 通过引用传递可能是危险的。 考虑通过参考传递

 CONST int ONE = 1;
增量(* ONE);
打印ONE;

如果常量被修改,则输出为2。