2013-01-04 78 views
3

我正在爲我的一些C庫工作C語言技能。在完成第一個工作實現之後,我現在將通過代碼來使其更高效。目前,我正在通過引用或值傳遞函數參數的主題。爲什麼我會按C中的值傳遞函數參數?

我的問題是,爲什麼我會通過C中的值傳遞任何函數參數?代碼可能看起來更清晰,但是不會總比通過引用傳遞效率更低?

+11

**每個**參數都通過C中的值傳遞。如果它不大於指針,傳遞一個副本肯定不是那麼低效。 –

+0

更不用說這會是多麼不方便:'int get_int(); void process_int_A(const int x); void process_int_B(const int * const x);'。比較:'void foo(){process_int_A(get_int()); }'''void foo(){const int result = get_int(); process_int_A(結果); }'。爲每個返回值需要明確的中間存儲將是殺手。在C++中這不是一個問題,在那裏你可以綁定到臨時值的「真實」引用。 – GManNickG

回答

5

在C中,所有參數都是按值傳遞的。一個真正的通過引用傳遞的是當你看到一個修改的,沒有任何明確的間接所有的效果:使用值,而不是指針雖然

void f(int c, int *p) { 
    c++; // in C you can't change the original paramenter passed like this 
    p++; // or this 
} 

,常常需要:

int sum(int a, int b) { 
    return a + b; 
} 

你不會寫如:

int sum(int *a, int *b) { 
    return *a + *b; 
} 

因爲它不安全,效率低下。效率低下,因爲存在額外的間接性。而且,在C中,指針參數表明調用者將通過指針修改該值(特別是當指針類型的大小小於或等於指針本身時)。

+0

這可能是一個愚蠢的問題,但爲什麼是'''int sum(int * a,int * b){return * a + * b; }'''函數不安全? – c00kiemonster

+0

,因爲那樣你就有了間接指向NULL /懸空指針的風險。 – perreal

+3

調用者現在需要爲a和b創建變量,不能傳遞常量。調用者還必須決定是否需要'malloc'值或傳遞變量的地址,並假定值可能會被修改,因爲它們不是'const'(可能需要複製值)。如果調用者傳遞NULL,未初始化的指針和/或指向無效內存位置的指針,則取消引用指針也不安全。 – Joe

1

請參閱Passing by reference in C。按引用傳遞是C中的一個用詞不當,它指的是傳遞變量的地址而不是變量,但是您將指針傳遞給值爲的變量。這就是說,如果你要將變量作爲指針傳遞,那麼是的,它會稍微更有效率,但主要原因是能夠修改它指向的原始變量。如果您不希望這樣做,建議您以價值爲目的,以明確您的意圖。

當然,就Cs較重的數據結構之一而言,所有這些都沒有意義。無論你喜不喜歡,數組都通過指向第一個變量的指針傳遞。

+3

感謝**所有**信息**。 – Joe

0

兩個原因:

  1. 很多時候,你將不得不取消引用您在很多時候已經通過指針(認爲長for循環)。你不想每次都想取消引用那個地址的值。直接訪問速度更快。

  2. 有時候你想修改函數內部的傳入值,但不是調用者。例如:

    void foo(int count){ 
        while (count>0){ 
         printf("%d\n",count); 
         count--; 
        } 
    } 
    

如果你想要做上述的東西按引用傳遞,你會haev創建自己的函數中另一個變量來存儲它第一次。

+0

取消引用變量與直接訪問的性能損失是多少?它是在數量級的土地? – c00kiemonster

+0

它可以是3個週期而不是1個週期。如果您正在編寫一個四核機器,誰在乎(主要)?如果你正在構建任何基於性能的(實時應用程序,嵌入式系統),這可能會產生巨大的差異。 – Phonon

+0

個人資料,個人資料,個人資料!這個答案的第一部分非常具有推測性,並且不考慮編譯器優化。 – Dan

5

因爲代碼爲計算機編寫下一代人並不重要。如果您傳遞引用,則任何讀者都必須假定任何調用的函數都可以更改其參數的值,並且在調用之前有義務檢查它或複製參數。

你的函數簽名是一個合約,並將你的代碼分開,這樣你就不必將整個代碼庫放入頭部,以便理解某些領域正在發生什麼,通過傳遞引用你正在做的下一個人的生活變得更糟,作爲程序員的最大的工作應該是讓下一個人的生活變得更好 - 因爲下一個人可能會成爲你。

+1

很好的答案。另外,傳遞值實際上可以更快,因爲編譯器知道參數不會互相混淆,因此可能會生成更好的代碼。 – Nemo

+0

「讓下一個人的生活變得更糟」的例子是一個很好的例子,這是我忽略的。 – c00kiemonster

+0

我一直認爲下一個傢伙是一個知道你地址的殺人狂。 –

相關問題