110

私は現在 C++ を学んでおり、少し前にインクリメントについて学びました。「++x」を使用して前にインクリメントを行い、「x++」を使用して後でインクリメントできることを私は知っています。

それでも、いつ 2 つのどちらを使用すればよいかわかりません... 「++x」を実際に使用したことはなく、これまでのところ常に問題なく動作していました。

例: for ループで、"++x" を使用するのが望ましいのはいつですか?

また、さまざまな増分 (または減分) がどのように機能するかを誰かが正確に説明できますか? とても感謝しております。

4

12 に答える 12

150

これは好みの問題ではなく、論理の問題です。

x++現在のステートメントを処理した、変数 x の値をインクリメントします。

++x現在のステートメントを処理する前に、変数 x の値をインクリメントします。

したがって、作成するロジックを決定するだけです。

x += ++ii をインクリメントし、i+1 を x に加算します。 x += i++i を x に加算してから、i をインクリメントします。

于 2009-11-28T16:47:38.547 に答える
56

Scott Meyersは、後置が適切であるとロジックが指示する場合を除いて、前置を優先するように指示しています。

「より効果的な C++」項目 #6 - それは私にとって十分な権限です。

この本を所有していない人のために、ここに関連する引用を示します。32ページから:

C プログラマーとしての日々から、インクリメント演算子の前置形式は「インクリメントとフェッチ」と呼ばれることがあり、後置形式は「フェッチとインクリメント」と呼ばれることが多いことを思い出すかもしれません。この 2 つのフレーズは覚えておくことが重要です。なぜなら、それらはすべて正式な仕様として機能するからです...

そして、34ページに:

あなたが効率を心配するような人なら、後置インクリメント関数を最初に見たとき、おそらく汗をかいたでしょう。その関数は、その戻り値の一時オブジェクトを作成する必要があり、上記の実装では、構築および破棄する必要がある明示的な一時オブジェクトも作成します。プレフィックスインクリメント関数には、そのような一時的なものはありません...

于 2009-11-28T16:49:50.853 に答える
30

イテレータをインクリメントするときの cppreferenceから:

古い値を使用しない場合は、ポストインクリメント演算子 (iter++) よりもプレインクリメント演算子 (++iter) を優先する必要があります。ポストインクリメントは、一般に次のように実装されます。

   Iter operator++(int)   {
     Iter tmp(*this); // store the old value in a temporary object
     ++*this;         // call pre-increment
     return tmp;      // return the old value   }

明らかに、事前インクリメントよりも効率的ではありません。

プレインクリメントは、一時オブジェクトを生成しません。オブジェクトの作成に費用がかかる場合、これは大きな違いを生む可能性があります。

于 2009-11-28T16:57:42.087 に答える
8

セマンティック (事前/事後) が重要ではない事前/事後インクリメントを使用する場合、生成されたコードは同じであることに注意してください。

例:

pre.cpp:

#include <iostream>

int main()
{
  int i = 13;
  i++;
  for (; i < 42; i++)
    {
      std::cout << i << std::endl;
    }
}

post.cpp:

#include <iostream>

int main()
{

  int i = 13;
  ++i;
  for (; i < 42; ++i)
    {
      std::cout << i << std::endl;
    }
}

_

$> g++ -S pre.cpp
$> g++ -S post.cpp
$> diff pre.s post.s   
1c1
<   .file   "pre.cpp"
---
>   .file   "post.cpp"
于 2009-11-28T17:19:55.163 に答える
6

心に留めておくべき最も重要なことは、x++ はインクリメントが実際に行われる前に値を返す必要があるということです。したがって、オブジェクトの一時的なコピーを作成する必要があります (インクリメント前)。これは、その場でインクリメントされて返される ++x よりも効率的ではありません。

ただし、言及する価値のあるもう1つのことは、ほとんどのコンパイラは、可能な場合はそのような不要なものを最適化できることです。たとえば、両方のオプションが同じコードになります。

for (int i(0);i<10;++i)
for (int i(0);i<10;i++)
于 2009-11-28T22:56:09.233 に答える
5

私は@BeowulfOFに同意しますが、明確にするために、ロジックが完全に明確になるようにステートメントを分割することを常に提唱します。

i++;
x += i;

また

x += i;
i++;

したがって、私の答えは、明確なコードを書く場合、これが問題になることはめったにないということです (問題がある場合、コードはおそらく十分に明確ではありません)。

于 2009-11-28T16:57:03.897 に答える
2

もしもcount{5};

++count を使用すると、ステートメントの前に処理されます

total = --count +6;

合計は 10 になります

count++ を使用すると、ステートメントの後に処理されます

total = count-- +6;

合計は 11 になります

于 2021-09-16T09:15:37.613 に答える
2

++x はx++ よりも高速であることが期待される(特に x が任意の型のオブジェクトである場合) ことを再度強調したかったので、論理的な理由で必要でない限り、++x を使用する必要があります。

于 2009-11-28T16:57:10.493 に答える
1

あなたは違いを正しく説明しました。ループを実行するたびに x をインクリメントするか、その後にインクリメントするかによって異なります。何が適切かは、プログラムロジックによって異なります。

STL-Iterator (これらの演算子も実装する) を扱う際の重要な違いは、 it++ が iterator が指すオブジェクトのコピーを作成し、インクリメントしてからコピーを返すことです。++一方、最初にインクリメントを実行してから、イテレータが現在指しているオブジェクトへの参照を返します。これは、すべてのパフォーマンスが重要な場合、または独自の STL イテレータを実装する場合にのみ関連します。

編集:接頭辞と接尾辞の表記の混同を修正

于 2009-11-28T16:51:30.943 に答える