2010-06-09 66 views
2

亲爱的所有人。我想知道是否有一些情况的例子,你可以有意地用C语言的价值来传递一个论点。让我换个角度。你什么时候有意使用C的大值对象传递值?或者,您何时关心对象参数是否完全复制到局部变量中?何时按价值传递?

编辑:现在我想到了,如果你可以避免指针,那么做。如今,对于小应用程序中的大部分应用程序来说,“深度”复制都是可能的,浅度复制更容易出现指针错误。也许。

+3

你在谈论通过参数“按值”或“通过引用”。深浅复制是另一回事。 – 2010-06-09 16:08:34

+0

完成。 +15个字符 – 2010-06-09 16:40:55

回答

3

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

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

  • 如果值适合架构的寄存器,则按值传递会更便宜 - 如果编译器非常智能,则可能会寄存器。按值传递意味着不创建指针,并且不需要取消引用的值。虽然收益很小,但在某些情况下会累加。

  • 按值传递需要较少的输入。可以肯定的一个薄弱的原因,但是它确实存在。

const关键字否定了大部分理由1,但理由2仍然有优点,并且是我通过值传递的主要原因。

+0

有人应该说C无论如何都只支持按值。 – Rhangaun 2010-06-10 05:02:39

+0

不正确。你可以传递一个指向这个对象的指针,这个对象就是在引导下为你做的。 – 2010-06-10 15:08:37

1

那么,首先,如果你想改变它。

想象一下以下做作功能:

int getNextCharAndCount (char *pCh); 

每次调用它的时候,它通过从函数返回的计数和字符指针的方式设置人物返回从列表中的下一个最常见的字符。

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

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

你指的是传递值和传递引用。

+0

在这种情况下,你传递的是一个char指针,而不是char的拷贝,除非你的意思是你传递了一个char变量地址的副本,但这是一个浅拷贝,而不是一个深层拷贝。 – 2010-06-09 16:11:51

1

传递引用是比较便宜的,因为您不必创建对象的本地副本。如果该功能需要本地副本(出于任何目的) - 可能是一种情况。

+0

不一定。按引用传递意味着您需要创建一个指针并取消引用。如果要传递的元素适合架构的寄存器,那么它实际上更便宜。 – 2010-06-09 18:16:36

+0

这很明显。主题是关于大型对象。 – adf88 2010-06-10 07:28:38

0

我不认为你关于chars的论点持有水。尽管你的概念上是1个字节,但函数调用的每个参数通常会转换为整个(字大小)的寄存器,并且为了效率而转换为堆栈上相同的空间量。

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

+0

还有一个问题,如果有一点额外的空间使用是否重要。那个答案通常是(虽然当然不总是)“不”。 – 2010-06-09 17:13:49

0

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

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

 
CONST int ONE = 1; 
increment(*ONE); 
print ONE; 

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

+0

大多数编译器会给出一个警告或错误 - 如果“ONE”被声明为“const”(我假设'#define CONST const'有效),那么你会得到一个关于传递一个const的警告指针('&ONE')指向'increment()',它接受一个非const指针 - 或者如果'increment()'被错误地声明为一个'const'指针,那么将会有一个警告指向它通过该指针修改值的位置。 – psmears 2010-06-09 16:20:56

+0

增量可以复制它的参数,并将其转换为指针,非常数,然后解引用指针。有自杀技术可以做到这一点。 失败发生在某些语言(FORTRAN)中,并且是简单的情况。考虑1被替换为一个对象指针或一个持有引用的对象。这个问题更加普遍。引用越是间接,你就越有可能修改应该是静态的东西。 深层副本是内存和CPU密集型,但保护您的对象。 – BillThor 2010-06-12 02:15:27

1

我遵循一个规则:

  • 通内置类型的值(INT,CHAR,双,浮法...)
  • 通类和结构的(常量)参考。没有涉及任何指针处理。

从来没有任何问题,这种工作方式。

1

如果我们要讨论这个问题,C中的everyhing是传值。您可以按值传递一个指针,而不是按值传递实际对象,但它仍然是按值传递的。

无论如何,为什么要传递整个对象而不是指向对象的指针呢?那么,举个例子,你的编译器可能会优化这个调用,使得在封面下面只有一个地址被复制。另外/另外,一旦你引入了指针,你的编译器可能无法做到因为别名而对你的函数进行尽可能多的优化。这也不太容易出错,不必记住解除引用。调用者也可以确定他传入的内容没有被修改(const不能保证这一点,它可以被危险地抛弃)