2012-11-20 106 views
4

考慮以下代碼:如何從函數中的數組返回結構體? (指針)

typedef struct fruits_s 
{ 
    char* key; 
    char value; 
} fruits_t; 

static fruits_t fruit_array[] = { 
{ "Apple", 1 }, 
{ "Banana", 2 }, 
{ "Grape", 3 }, 
{ "Orange", 4 } }; 

static fruits_t* getFruitFromValue(char value) 
{ 
    int i; 
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++){ 
     if (value == fruit_array[i].value){ 
      return fruit_array[i]; 
     } 
    } 
} 

我是新來的C和指針時需要/使用還在學習。我來自Java背景。所以,在上面的代碼中,我感到困惑的是該函數應該返回一個指針fruits_t*?或者是其他東西?當我做fruit_array[i]是一個指向我的結構,或結構本身?

話雖這麼說,後來在我的代碼時,我想使用的功能,是這樣的:

fruits_t* temp = getFruitFromValue(1); 

fruits_t temp = getFruitFromValue(1); 

fruits_t temp = &getFruitFromValue(1); 
+0

我認爲這將是回報與fruit_array [I] – dchhetri

+2

'fruit_array [i]'是結構體,如果你想返回一個指針,'&fruit_array [i]'或者等價的'(fruit_array + i)'。 –

+0

我想這是我的問題的一部分...我想返回一個指針,或不? –

回答

4

的功能,可以返回 - 您的選擇。你說過你會返回一個指針;沒關係,只要你這樣做。

當你寫:

static fruits_t *getFruitFromValue(char value) 
{ 
    int i; 
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++){ 
     if (value == fruit_array[i].value){ 
      return fruit_array[i]; 
     } 
    } 
} 

有幾個問題:

  1. fruit_array[i]是一個結構,而不是一個指針。使用return &fruit_array[i];
  2. 如果循環退出,則根本不返回該函數的值。

解決了那些導致:

static fruits_t *getFruitFromValue(char value) 
{ 
    int i; 
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++) 
    { 
     if (value == fruit_array[i].value) 
      return &fruit_array[i]; 
    } 
    return NULL; 
} 

這是可以的,因爲你返回的指針是會活得比的功能的靜態數據。如果你試圖返回一個指向非靜態數據的指針,除非你使用了動態內存分配(通過malloc()等),否則你可能會(可能)在你手上有一個錯誤。

您也可以返回結構;處理錯誤返回變得更加困難。如果你有C99,您可以使用「複合文字」:

static fruits_t getFruitFromValue(char value) 
{ 
    int i; 
    for (i = 0; i < sizeof(fruit_array)/sizeof(fruit_array[0]); i++) 
    { 
     if (value == fruit_array[i].value) 
      return fruit_array[i]; 
    } 
    return (fruits_t){ .key = "", .value = 0 }; 
} 
+0

感謝您的詳細回覆。我理解你的大部分觀點。我想我想知道的是,爲什麼我會返回一個指向這個數據的指針與結構本身?正如你所說的,結構超越了函數,所以我知道它是否沒有指向它的指針會是一個壞主意。但你有其他想法嗎? –

+0

對於這樣的小型結構,返回結構副本是合理的。如果結構很大(比如說數百字節或更大),那麼返回指針比返回值更明智。確保指針指向實時數據總是很重要的;返回一個值很大程度上擺脫了這個問題(儘管在這裏,你在結構中有一個'char *';由於結構被分配的方式是安全的,但遇到問題並不難)。你可以使用'struct fruits_s {char key [11]; char值; };'以避免結構中的指針。 –

+0

'對於像這樣的小型結構,返回結構副本是合理的。' 那麼是創建副本並執行隱式「malloc」,爲此副本分配內存?像這樣使用更多的內存而不是返回指針,對嗎? –