1

次のようなコードがあるとします。

int foo(int a, int b, int c)
{
    int tmp1, tmp2, tmp3;
    ...
    some_calculation0(&tmp1, a, b); // stores the result in tmp1
    some_calculation1(&tmp2, b, c);
    some_calculation2(&tmp3, tmp1, tmp2);

    return tmp3;
}

最近、私はこれを次のように書きます:

int foo(int a, int b, int c)
{
    int tmp[3];
    ...
    some_calculation0(&tmp[0], a, b); // stores the result in tmp[0]
    some_calculation1(&tmp[1], b, c);
    some_calculation2(&tmp[2], tmp[0], tmp[1]);

    return tmp[2];
}

このようなことをしない理由はありますか?誰かがそれを悪い習慣だと思いますか?

この場合、tmpすべての関数が参照によって渡された入力変数の1つで結果を返すため、値は一連の計算の実際の中間値です。私にはそれらをグループ化することは理にかなっていますが、これまでのところ応答がそれに反対していることを考えると、別々の変数を使用することに何の反対もありません。

4

3 に答える 3

4

これは、コードの可読性を妨げます。変数名は、それらの使用法に関する情報を提供する必要があります。

変数名として使用tmpすると便利で合理的な場合もありますが、このようにtmpの配列を使用しても、変数がどのように使用されているかはわかりません。計算の詳細が不透明な名前/構造の背後に隠れています。さらに、コードで何が起こっているのかを把握するためにインデックスを追跡する必要があります。これは混乱を招き、プログラマーのエラーが発生しやすくなります。

特定の変数名を選択するのにこれ以上の労力は必要ありません。変数の名前が実際に、よりも優れている場合は、イテレータとして、またはインデックスなどのtmpX一般的な規則を優先します。xyzindexidx

于 2012-07-02T19:12:25.937 に答える
0

これは非常に主観的ですが、私は確かに2番目のスニペットのスタイルに反対します。配列の機能(つまり、連続ストレージ+配列ポインターの減衰)が必要でない限り、すべての変数をスカラーにして、適切な名前を付ける必要があると思います。したがって、ではtmp1ありtmp2ませんtmp3。2番目のスニペットは、入力が少し難しく、読みにくい(そしてエラーの可能性が高い)と思います。

于 2012-07-02T19:15:13.410 に答える
0

別の変形があります:それが意図されたものの戻り値を使用します:

int foo(int a, int b, int c)
{
    int part_a, part_b, result;
    ...
    part_a = some_calculation0( a, b);
    part_b = some_calculation1( b, c);
    result = some_calculation2( part_a, part_b);

    return result;
}

そして、別の、かなり不可解なバージョンが可能です(これは、some_calculation [01]が純粋関数であり、副作用がないことを信頼しています):

int foo(int a, int b, int c)
{
    int result;
    ...

    result = some_calculation2( some_calculation0( a, b)
                              , some_calculation1( b, c));

    return result;
}

あるいは:

int foo(int a, int b, int c)
{
    ...
    return some_calculation2( some_calculation0( a, b)
                            , some_calculation1( b, c));
}

戻り値を使用する論理的な「パフォーマンス」の理由があります。呼び出された関数の最後、戻りの直前に、コンパイラーはレジスターのどこかに結果を準備します。ほとんどの場合、呼び出し元の関数は、すべての汎用レジスターがサブ関数によって使用される(およびその内容が破棄される)ことを想定しています。ただし、戻り値ではありません。ほとんどのアーキテクチャでは、レジスタに戻り値を返すための規則としてあります(AX、またはx86のDX + AX)。これは、呼び出し元と呼び出し先にとって便利な安価なランデブーポイントです...

于 2012-07-02T20:34:15.810 に答える