2009-03-31 8 views
3

私は職場で従来のCコードベースを持っていますが、私は以下のようなスタイルの関数実装がたくさんあります。私はそれはかなり鈍角見つけ、私は同様の機能を実装する必要があるときに私がやって終わるCはパラメータを過度に使用していますか?

myOutPtr = DoStuff(myInPtr, myOutPtr, myError, &myAmount); 

NewDoStuffを使用して
long NewDoStuff(char *inPtr, char *error) 
{ 
    long amount = 0; 
    *error = 0; 

    // Read bytes from inPtr and decode them as a long storing in amount. 

    return amount; 
} 

を:

myAmount = NewDoStuff(myInPtr, myError); 
myOutPtr += sprintf (myOutPtr, "%d", myAmount); 
DoStuffを使用して

char *DoStuff(char *inPtr, char *outPtr, char *error, long *amount) 
{ 
    *error = 0; 
    *amount = 0; 

    // Read bytes from inPtr and decode them as a long storing in amount 
    // before returning as a formatted string in outPtr. 

    return (outPtr); 
} 

私はできませんpがありますが、私が一番上の例で欠けているものがあるのだろうかと疑問に思っているのですが、そのタイプのアプローチを使う良い理由はありますか?

+0

+ = sprintfは何ですか? – Uri

+0

http://msdn.microsoft.com/en-us/library/ybk95axf(VS.71).aspxは、文字列を書き込み、次にポインタを書き込まれたバイト数だけ前方に移動します。 – sipwiz

+0

+ =ではなく、+ =でないはずですか? –

答えて

1

1つの利点は、コード内でこれらの関数を頻繁に呼び出すと、sprintf呼び出しを何度も繰り返す必要があることがすぐに面倒になることです。

アウトポインタを返すことは、それが可能あなたがのようなものを行うようになりまた、:あなたの新しいアプローチで

DoOtherStuff(DoStuff(myInPtr, myOutPtr, myError, &myAmount), &myOther); 

を、同等のコードはかなり多くの冗長です:

myAmount = DoNewStuff(myInPtr, myError); 
myOutPtr += sprintf("%d", myAmount); 
myOther = DoOtherStuff(myInPtr, myError); 
myOutPtr += sprintf("%d", myOther); 
1

これはC標準ライブラリスタイルです。関数呼び出しの連鎖を助ける戻り値があります。

また、DoStuffはクリーナーIMOです。そして、あなたは本当にsnprintfを使用するべきです。また、バッファ管理の内部の変更はコードに影響しません。しかし、これはもはやNewDoStuffには当てはまりません。

+0

バッファ管理の内部の変更に関するビットは何を意味しますか?私は間違っている可能性がありますが、私は両方のアプローチですべてのポインタが同じように終わると信じています。 – sipwiz

+0

@sipwiz:「DoStuff」は、「myOutPtr + = sprintf(myOutPtr、 "%d"、myAmount); "部。それは上記の声明を促した。 – dirkgently

0

あなたが提示したコードが少し不明である(例えば、なぜあなたはsprintfの結果とmyOutPtrを追加している。

をしかし、一般的に、それはあなたが、本質的に記述しているようだ何1の内訳であります一つのことをする関数と他のことをするコード(連結)の2つのことを行う関数です。

責任を2つの関数に分けることは良い考えですが、あなたはこれに対して別の関数連結や書式設定など、実際には明確ではありません。

Iさらに、関数呼び出しを複数の呼び出しに分割するたびに、コード複製を作成しています。コードの複製は決して良い考えではないので、あなたはそれを行うための関数が必要になります。そして、あなたはオリジナルのDoStuffのようなもので終わるでしょう(これはCです)。

あなたはこれについて多くのことができるとは確信していません。非OOP言語の限界の1つは、(構造体を使用しない限り)膨大な量のパラメータを送信する必要があることです。巨大なインターフェースを避けることができないかもしれません。

0

NewDoStuffを呼び出すたびにsprintf呼び出しを実行する必要がある場合は、自分自身を繰り返しているため、DRYの原則に違反しています。フォーマットを違うものにする必要があることが分かったら、それだけでなくすべての場所で変更する必要があります。

0

として、経験則として、私の関数の1つのインターフェースが110列を超える場合、構造を使用することを強く見ています(もし私が最良の方法をとっているなら)。私が(今までに)したくないことは、関数内のいくつかの機能が有用であるだけでなく、それ自身で必要とされない限り、5つの機能を5つの機能に分割する機能をとることです。

私は最初の機能を好むだろうが、私は標準Cスタイルにもかなり慣れている。

関連する問題