2011-08-28 74 views

回答

1

函數不能返回數組類型。您可以返回指向數組第一個元素的指針(類型爲void **),或者可以返回指向整個數組的指針(類型void (*)[N])。請注意,地址值是相同的(數組的第一個元素的地址也是數組的地址),這只是類型上的差異。

要返回一個指向指針的SIZE-元件陣列void,函數簽名將是

void *(*func())[SIZE] 

其分解爲

 func    -- func 
     func()   -- is a function 
     *func()   -- returning a pointer 
     (*func())[SIZE] -- to a SIZE-element array 
    *(*func())[SIZE] -- of pointer 
void *(*func())[SIZE] -- to void. 

記住後綴運算符,如[]()比一元運算符(如*)具有更高的優先級,所以*a[]是一個指針數組,而(*a)[]是一個指向數組的指針。

對於C89及更早版本,SIZE必須是編譯時常量表達式。對於C99,您可以使用變量表達式。

不管你做什麼,嘗試返回一個指針數組這是本地的功能,如

void *(*func())[SIZE] 
{ 
    void *foo[SIZE]; 
    ... 
    return &foo; 
} 

void **func() 
{ 
    void *foo[SIZE]; 
    ... 
    return foo; 
} 

一旦函數退出,foo不再存在,並且返回的指針值不再有意義的任何地方。你要麼將不得不聲明數組爲static在你的函數,或者你將不得不動態地分配它:

void *(*func())[SIZE] 
{ 
    void *(*foo)[SIZE] = malloc(sizeof *foo); 
    ... 
    return foo; 
} 

void **func() 
{ 
    void **foo = malloc(sizeof *foo * SIZE); 
    ... 
    return foo; 
} 
+0

這幫助我真正理解它。 – Django

1

正如其他人所說,你不能這樣做,因爲數組會降級爲指針。要做到這一點的標準方法是返回一個struct

struct array { 
    void* ptrs[5]; 
} 

那麼你的程序將被宣佈像

struct array foo() {...} 
+0

這遠非「標準」方式。許多人反對用價值而不是指針來返回這樣一個大對象。 –

+0

確實,返回大型數組會產生副本開銷,因此在大型副本和管理堆分配對象的所有權之間進行權衡。但它是一個折衷。所以如果你想要做的只是通過值傳遞小數組,它將非常有效,因爲在棧上覆制值將具有良好的緩存局部性。如果它很大,那麼系統調用的開銷可能是值得的。 – luke

+0

除了性能問題之外,還有語義問題,因爲結構只能包含* fixed-size *數組。 –

1

例子:

void **function(int c) 
{ 
    void **arrayOfVoidStars = (void **)malloc(c*sizeof(void *)); 
    /* fill the array */ 
    return arrayOfVoidStars; 
} 
+1

很多人(包括我在內)認爲在C中使用'malloc'的返回值並使用'sizeof(type)'作爲參數是一種不好的做法。我更喜歡'type * p = malloc(sizeof * p);'因爲它只重複一次類型名稱。如果稍後再更改它,我只需要在一個地方修改代碼。 –

+1

@Chris:或者,在這種情況下,'malloc(COUNT * sizeof * p)'。 –

+0

@凱斯 - 當然,對不起。我從手機上寫下了這個信息,所以我沒有回過頭去查看。 –

相關問題