0

配列の境界をチェックする関数を作成しました。2 番目のソリューションが最初のソリューションと同じタスクを実行しないのはなぜですか? これは優先順位の問題ですか、それとも三項の不適切な使用ですか?

回避策 #1:

bool check_bounds(double* score, int size)
{
    bool result=false;
    for(int i=0; i<size; i++)
    {
        if(score[i] < 0.0 || score[i] > 100.0) 
        {
            result=true;
        }
    }
    return result;
}

// usage
if(check_bounds(score, size) { i--; }

回避策 #2:

bool check_bounds(double* score, int size)
{
    bool is_valid;
    for(int i=0; i<size; i++)
    {
        is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
    }

    return is_valid;
}
4

4 に答える 4

3

あなたの最初の例は早く壊れます:

for(int i=0; i<size; i++)   // loop until i = size
{
    if(score[i] < 0.0 || score[i] > 100.0) 
    {
        return true;   // but if we hit this condition, we leave now!
    }
}

2 番目の例は、if チェックでのみ変数を設定します。

for(int i=0; i<size; i++) // loop until i = size regardless
{
    is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
}

return is_valid; // return whatever was last set.
于 2013-06-04T16:28:59.773 に答える
3

for ループの各反復で is_valid がに基づいて割り当てられるため、2 番目の回避策は失敗しますscore[i]。これにより、基本的に関数全体が返されscore[size - 1] < 0 || score[size - 1] > 100ます。

三項演算子は常に評価され、 に新しい値を代入するため、ここではあまり適切ではありませんis_valid。最初のバージョンは、実際に何をしているかを示すために次のように書き直すことができます。

bool check_bounds(double*score, int size)
{
    bool is_valid = false;
    for(int i=0; i<size; i++)
    {
        if (score[i] < 0.0 || score[i] > 100.0)
        {
            is_valid = true;
        }
    }
    return is_valid;
}
于 2013-06-04T16:28:47.970 に答える
2

2 番目のバージョンは through の範囲全体を実行しscore[0]、テストの最後の値を返します。一方、最初のバージョンは、配列score[size - 1]のいずれかのメンバーが範囲外である場合、早期にループを終了します。2 番目のバージョンのループ内scoreのどこかにテストを追加する必要があります。is_validfor

is_validとにかく早く戻るかどうかを判断するためにテストする必要があるため、私見では、ここで三項演算子を使用してもまったく何も得られません (読みやすさの向上も、より簡潔なコードもありません)。

2 番目のバージョン (早期に返されるように修正された場合) はおそらく、コンパイラによって最初のバージョンと実質的に同じマシン コードに最適化されるため、パフォーマンスに関しても何も得られません。

スタイルに関しては、最初のバージョンの方が好きですが、それは個人的な好みの問題です。return一部の人々 (およびマネージャー!) は、任意の関数に1 つのステートメントのみを含める必要があると考えています。その標準に固執しようとしている場合は、別の可能なリファクタリングを次に示します。

bool check_bounds(double* score, int size)
{
    bool is_valid;
    for (int i=0; i<size; i++)
    {
        is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
        if (!is_valid)
            break;
    }

    return is_valid;
}
于 2013-06-04T16:39:01.457 に答える
0

回避策 #1 は、反復で条件が満たされた場合は true を返し、満たされない場合は false を返します。回避策 #2 は、反復ごとに true と false を繰り返し切り替え、最後の反復で条件が満たされているかどうかを返します。#1の機能を得るために、三項条件を実際に使用することはできません。

于 2013-06-04T16:30:49.627 に答える