2012-02-25 15 views
5

は、複素数の配列を繰り返し処理して合計したいとします。私はこれを行う2つの方法があります。より良い、なぜあるC++の配列ポインタ[]または++

A)

double sum (double * series, int size) { 
    double sum = 0.0; 
    for (int i = 0; i < size; i++) { 
     sum += *series++; 
    } 
    return sum; 
} 

B)

double sum (double * series, int size) { 
    double sum = 0.0; 
    for (int i = 0; i < size; i++) { 
     sum += series[i]; 
    } 
    return sum; 
} 

/Iは、他の上で1つ使用する必要が場合。

+0

私はBの方が好きです。なぜなら、ポインターの仕組みがわからないと、理解しやすくなります。 std :: accumulateでベクトルを使うこともできます。 – chris

+0

スタイルAはあなたが達成していることを私にはっきりと分かりません。個人的には、私は常にC#の背景から来るスタイルBを選択します。 –

+0

@Richard J.Ross III、 '* series'は、どのシリーズが指しているデータに含まれているかを評価します。ループは系列をインクリメントし、毎回配列の次の要素を指し示します。 – chris

答えて

6

これは可読性の問題です。パフォーマンスに影響しないはずです。私はBが最も読みやすく、したがって好ましいと思います。

Iはまた、(beginendとパラメータに注意してください)範囲ベースの第三の変形例を提案することができ:

double sum (double* begin, double* end) { 
    double sum = 0.; 
    for (double* it = begin; it != end; ++it) { 
     sum += *it; 
    } 
    return sum; 
} 

これは多くの場合、慣用のC++であり、より容易に一般化します。つまり、が常にであるとは限りません。可読性と保守性に関する疑問の別の変形です。

+0

ええ、これは基本的にstd :: accumulateがベクトルで行うことです。 – chris

+0

'begin' '<' 'end''を期待しましょう。 'begin'' ==' 'end''の場合はどうなりますか? –

+1

@SimonWright:それからループに入りません。すぐに0が返されます。ループ状態はボディに入る前にチェックされています:) –

4

いずれも本質的に他より優れていません。コードの意図を明確にするかどうかを選択する必要があります。最新のコンパイラでは、同じマシンコードに最適化する必要があります。


ただし、生の配列に生のポインタの周りに渡すと、C++での悪いスタイルと考えられていること。 std::vectorのようなコンテナクラスの使用を検討してください。

1

現代的な最適化コンパイルを使用すると、パフォーマンスの点で違いはありません。

間接自動インクリメントアドレッシングで処理するのに必要なサイクルが少なく、インデックス+オフセットを自動インクリメントに変換できるオプティマイザがないため、1978年の最初の方法はPDP-11ではやや高速でした。

P.S. seriesが値渡されるため、series -= size;を設定しても効果はありません。

+0

シリーズ - サイズ;シリーズを最初のアイテムの権利に戻すように設定しますか? –

+1

@PatrickLorioはい、それはポインタの*コピー*で行いますが、これは値渡しです。代入の後に 'series'にアクセスせずに次の行に戻るので、この代入は効果がありません。例えば、合計を見つけることに加えて、最大または最小の要素を見つけるために、そのポインタ*をもう一度使用する場合は意味があります。 – dasblinkenlight

+3

@PatrickLorioそれは問題ではありません。渡された実際のポインタは値によって渡されるので、サイズを ' - ='にすると、最初に渡された変数には影響しません。 –

5

私は同様のスタイルBを選んだだろうが、その後は、明示的なループ上の標準的なアルゴリズムを好む必要があります。

#include <numeric> 

double sum(const double* const series, const int size) { 
    return std::accumulate(series, series + size, 0.0); 
} 
0

あなただけの合計したくない場合(配列を反復処理するC++ 11の方法を彼らとその蓄積は、あなたの必要性に合わない)である:

double sum (const double * series, int size) { 
    double sum = 0.0; 
    for_each (series, series + size, [&](double v) { 
     sum += v; 
    }); 
    return sum; 
} 

注あなたはベクトルやリストを使用する場合は、ほとんど同じコード取得したいこと:

double sum (const vector<double>& series) { 
    double sum = 0.0; 
    for_each (begin(series), end(series), [&](double v) { 
     sum += v; 
    }); 
    return sum; 
}