2009-07-06 157 views
6

重要:請參閱以下非常相關的問題:Return multiple values in C++從C函數返回多個值

我在如何在ANSI C中做同樣的事情?你會使用一個結構或傳遞函數中的參數地址嗎?即使是以可讀性爲代價,我仍然是在非常高效(快速)代碼(時間和空間)之後。

編輯:感謝所有的答案。好的,我認爲我欠缺了一些解釋:我正在撰寫關於某個特定域的某些算法子集的書。我已經爲自己設定了一個相當武斷的目標,即以可讀性和其他方式爲代價,爲我所有的算法提供最高效率(時間和空間)的實現。這部分是我的(一般)問題的性質。

:我希望我就直,從(可能)最快多見無意義的(這一切是先驗的,即沒有測試):在全球對象

  1. 商店outvalues(我)或
  2. 在函數中傳遞outvalues作爲參數(foo(int in,int * out1,int * out2)),或者
  3. 返回一個結構同時具有兩個outvals,或者
  4. (3)只有當這些值在語義上相關時。

這是否有意義?如果是這樣,我認爲傑森的迴應是最接近的,儘管他們都提供了一些「難題」。羅伯特的很好,但在這個時候語義並不是我所追求的(儘管他的建議被適當注意到)

謝謝大家。

+3

無情地編寫代碼和配置文件。我認爲你會發現struct-vs-reference對性能的影響與其他實現相比*非常小,甚至不值得考慮。 – 2009-07-06 19:55:31

+0

這也是很好的建議。謝謝。 (順便說一句,我的確讓你讚不絕口,所以恰巧我得到了更實際的答案,就是這樣。) – 2009-07-06 20:12:18

+0

我知道。謝謝。 – 2009-07-07 01:19:32

回答

5

正如尼爾說,你需要判斷它自己。

爲了避免傳遞任何東西的代價,請使用全局。接下來最好的是通過指針/引用傳遞的單個結構。之後是單獨的指針/參考參數。

但是,如果你將數據打包到結構,然後讀取它的電話後回來了,你可能會更好傳遞各個參數。

如果你不知道,只用兩種方法寫一點快速測試代碼,執行每幾十萬次,時間,看看哪一個是最好的。

3

您已經描述了兩種可能的解決方案和您感知的性能約束。你從哪裏出發真的取決於你 - 我們沒有足夠的信息做出明智的判斷。

1

最快Q & D我可以想到的方式是將值傳遞給全局對象,這樣就可以跳過堆棧操作,只要記住它不會是線程安全的。

0

我會將地址傳遞給結構體。如果要返回的信息不是很複雜,那麼只需將地址傳遞給值就可以。個人而言,它真的歸結爲界面會有多混亂。

void SomeFunction(ReturnStruct* myReturnVals) 
{ 
    // Fill in the values 
} 

// Do some stuff  
ReturnStruct returnVals; 
SomeFunction(&returnVals);  
// Do more stuff 
7

這兩種方法都是有效的,certianly,但我會考慮語義(結構VS參數指令),以決定哪種方式最好傳達你的意圖給程序員。

如果您返回的值緊密耦合,那麼可以將它們作爲結構返回。但是,如果只是簡單地創建人工機制以將值返回(作爲結構體),則應該使用參數引用(即傳遞變量的地址)將值返回給調用函數。

享受,

羅伯特C. Cartaino

3

最容易閱讀應該在函數傳遞地址,應該也快,持久性有機污染物,並推動價格便宜:

void somefunction (int inval1, int inval2, int *outval1, int *outval2) { 
    int x = inval1; 
    int y = inval2; 
// do some processing 
    *outval1 = x; 
    *outval2 = y; 
    return; 
} 
0

這大規模取決於你的架構,並且如果你還期望(或者可以有)內聯功能。我首先以最簡單的方式編寫代碼,然後擔心速度,如果這顯示爲代碼的昂貴部分。

1

我認爲,當你返回一個結構指針時,你可能需要手動找到一些內存。參數列表中的地址分配在堆棧上,速度更快。

0

無論哪種情況,您都要傳遞引用,所以性能應該類似。如果函數有可能實際上沒有返回值,那麼可以通過「return a struct」選項避免malloc的開銷,因爲您只需返回null。

我個人的偏好是返回一個動態分配的(malloc'd)結構。我避免使用函數參數來輸出,因爲我認爲它會使代碼更加混亂,並且長期維護更少。

1

請記住,有時是更快地通過值和更新參數的回報(或使堆棧上的本地副本)比參考...這是小結構或幾個參數和大量的訪問非常明顯。

-1

返回結構的本地副本是不好的,因爲如果該結構被宣佈爲在函數內部的非靜態,​​就變成零,一旦你退出函數void。

和所有鄉親暗示引用,以及在OP確實說過「C」,而C沒有他們(引用)。

和甜羽毛狀耶穌,我可以明天醒來,並沒有看到有關觸發器的電視國王什麼?