2017-02-12 69 views
1

我有一個由幾個參數和一個唯一的id定義的元素數組,我創建了一個函數,它返回與某個唯一id關聯的元素,問題是如果輸入了一個無效的ID(一個沒有存儲的由數組)),沒有有效的值返回我的函數。當沒有有效的值返回時,在C中該做什麼?

我的問題是,如果該函數不一定返回某些東西,我的代碼將不會編譯,有沒有辦法告訴編譯器,這樣做可以嗎?

謝謝。

+0

發佈您的一些代碼。 – Jarvis

+0

代碼示例會幫助... –

回答

2

您必須定義一個無效值,這樣的值只是一個不屬於該組有效值的值。

例如:

如果有效值爲[0,INF)然後-1是一個很好的無效值

+0

好的,我會做這個,然後,謝謝! –

+0

我對這種方法有點勉強。因爲它只是爲了得到一個無效值而犧牲了大量的值。我經常嘗試使'0'成爲無效值,並且範圍內的所有其他無符號整數(某種大小)。 – StoryTeller

+0

@StoryTeller這種方法只有在有效值集合是真正有限且定義明確的情況下才有效。當然,還有其他的方法,但這個很簡單,因此很優雅。雖然,它一定不會一直工作。另外,我相信它被用在許多重要的應用程序中,例如用於字符串終止的''\ 0''和用於指針的'NULL'是最廣泛使用和標準化的。我可以繼續,'EOF'......但你明白了。 –

7

有幾種方法可以做到這一點。

最簡單的方法是返回一個不在有效值範圍內的值。

另一種方法是聲明另一個參數,該參數是指向作爲錯誤的變量的指針。或者返回一個錯誤值並返回有效值作爲參數聲明的參數。

例如

int /* error */ f(T *valid_value); 

還有一個方法是,返回兩個值的一個結構,該結構中的一個是其報告失敗或成功的一個布爾值。

1

我會返回一個指向元素的指針,而不是元素本身。如此。

struct Element* find(struct Element* elements, int count, int id) 
{ 
    for(int i = 0; i < count; i++) 
    { 
     if(elements[i].id == id) 
     return elements + i; //pointer to i'th element 
    } 
    return NULL; //if it makes it here return NULL since no element was found. 
} 

然後你可以做這樣的事情。

struct Element* e = find(elements, m, 1234); 
if(e) //check and see if it is not null 
{ 
    //handle found case 
} 
else 
{ 
    //handle not found case 
} 
+0

您的方法存在問題,您可以將'NULL'傳遞給'free()',但不能將此函數的返回值傳遞給'free()'。這與我所建議的幾乎一樣,但'NULL'有它自己的用例。也許,具有無效成員和'int element_is_valid(Element *)'函數的元素會這樣做。另外,將'*'附加到該類型是一個壞主意,並且使我想撕掉我的眼睛! –

+1

@IharobAlAsimi - 所以你會寫'struct Element * find(.....'? – 4386427

+1

我不相信「無法釋放返回值」是一個有效的投訴。 –

0

.....有沒有辦法告訴編譯器,這是確定要做到這一點嗎?

不,沒有辦法做到這一點。

函數必須始終返回一個相同類型的值(即您在聲明中給出的類型)或永不返回任何內容(即聲明爲void foo(...))。

在某些情況下,您不能返回值,並在其他情況下返回「nothing」。同樣,在某些情況下你不能返回一個整數,在其他情況下你不能返回一個結構體。所有情況下的返回值必須相同。

一般的解決方法是引入一種方法來告訴調用者該函數未能找到所請求的元素。如其他答案中所述,有多種方法可以做到這一點。哪種解決方案取決於您的代碼和需求。

我通常更喜歡該函數返回一個int其中零值意味着「失敗」,非零意味着「成功」。然後我會使用指針「返回」元素。像這樣的僞代碼:

int foo(struct MyStruct *p, .....) 
{ 
    if (found.....) 
    { 
      *p = the_found_element; 
      return 1; 
    } 
    return 0; 
} 


struct MyStruct ms; 
if (foo(&ms, ....)) 
{ 
    // okay - carry on using ms 
    ... 
} 
else 
{ 
    // failure - don't use ms as it is invalid 
    ... 
    } 
相關問題