2

私はC関数の範囲を持っています:

const char* find_string(uint8_t id);
int32_t find_int32(uint8_t id);
uint32_t find_uint32(uint8_t id);
uint64_t find_uint64(uint8_t id);

見つかったアイテムを(リンクリストで)返します。文字列の場合、null文字列を返すことができます。しかし、整数値については、整数値が見つかったかどうかを示したいと思います。これを行うためのCイディオムの方法は何ですか?

このような: ?

uint32_t find_uint32(uint8_t id, int* success);
4

2 に答える 2

9

これを達成する方法は1つではありませんが、一般的な解決策は次のとおりです。

int find_uint32(uint8_t id, uint32_t *result)

関数に結果ではなくステータスコードを返すようにします。実際の結果は、ポインタを介して「返されます」。ここでは意見が異なりますが、次のようなことができるように、関数が失敗したときにゼロを返すようにすることをお勧めします。

if (!find_uint32(42, &out)) {
    /* error */
}

逆の場合、つまり、ポインタパラメータを介してステータスコードを返し、その結果を関数の戻り値として返す理由の1つは、NULLエラーを無視する場合にステータスコードを渡すことができるためです。そうすれば、何らかの理由でエラーを心配する必要がない場合でも、コードが読みやすくなります。検討:

uint32_t val = find_uint32(42, NULL /* don't care */);

場合によっては、エラーインジケータとして「魔法の値」を予約できます。あなたが言ったように、NULLポインタは文字列に対して機能します。ある整数値が決して有効な結果ではないことが確実な場合は、エラーを示すようにすることができます。たとえば、 0x7FFFFFFFを超えることのない符号なしの値を返す関数がある場合、31番目のビットにエラーを示し、残りの31ビットにデータまたはエラーコードを最初のビットの値に応じて運ぶことができます。

私は一般的にこの方法をお勧めしません。その理由は、魔法のエラー番号を使用すると、エラーフラグを明示的に返すよりも、コードの読み取りと保守が難しくなるためです。

于 2012-06-30T16:00:22.297 に答える
1

どうですか:

int find_uint32(uint8_t id, uint32_t *val);

結果へのポインタを渡し、0成功と!= 0エラーの場合に戻ります。

式での使用の便利さが好きな場合はfind_uint32、要素へのポインター(またはノードへのリンクリスト)を返すこともできます。値にアクセスするにはポインターを逆参照する必要がありますがNULL、結果ポインターでエラーを示すために使用することもできます。

uint32_t *find_uint32(uint8_t id);
于 2012-06-30T15:59:46.400 に答える