2010-06-09 95 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不能保證這一點,它可以被危險地拋棄)