C++のループでは、通常++
または+=1
を使用する状況に遭遇しますが、それらの違いはわかりません。たとえば、整数がある場合
int num = 0;
そして、ループで:
num ++;
または
num += 1;
両方ともnum
の値を増やしますが、それらの違いは何ですか? num++
はnum+=1
よりも高速に動作するのではないかと疑っていますが、どのようにすればよいですか?この違いは無視できるほど微妙ですか?
num += 1
は++num
とかなり同等です。
これらのすべての式(num += 1
、num++
および++num
)は、num
の値を1つ増やしますが、num++
の値はnum
had beforeインクリメントされました。
図:
int a = 0;
int b = a++; // now b == 0 and a == 1
int c = ++a; // now c == 2 and a == 2
int d = (a += 1); // now d == 3 and a == 3
好きなものを使ってください。 ++num
よりもnum += 1
の方が好きです。
prefixおよびpostfix操作は、試験問題の完璧な候補です。
a = 0;
b = a++; // use the value and then increment --> a: 1, b: 0
a = 0;
b = ++a; // increment and then use the value --> a: 1, b: 1
+=
操作とその姉妹-=
は、主に異なる番号で使用することを目的としたより一般的なソリューションです。 1
とともに使用すると冗長であるとさえ言うかもしれません。 1
とともに使用すると、ほとんどの場合prefix操作として機能します。実際、私のマシンでは同じマシンコードを生成します。次のようなプログラム例を使用して、これを試すことができます。
void foo() {
int a, b;
a = 0;
// use one of these four at a time
b = a++; // first case (different)
b = ++a; // second case
b = (a += 1); // third case
b = (a = a + 1); // fourth case
}
int main() {
foo();
return 0;
}
gdb
で分解すると、次の結果が得られます。
a++
)(異なる)(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: Push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: mov -0x8(%rbp),%eax
0x00000000004004c2 <+14>: mov %eax,-0x4(%rbp)
0x00000000004004c5 <+17>: addl $0x1,-0x8(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
++a
)(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: Push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
a += 1
)(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: Push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
a = a + 1
)(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004b4 <+0>: Push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: movl $0x0,-0x8(%rbp)
0x00000000004004bf <+11>: addl $0x1,-0x8(%rbp)
0x00000000004004c3 <+15>: mov -0x8(%rbp),%eax
0x00000000004004c6 <+18>: mov %eax,-0x4(%rbp)
0x00000000004004c9 <+21>: pop %rbp
0x00000000004004ca <+22>: retq
End of assembler dump.
ご覧のとおり、コンパイラの最適化を有効にしなくても、addl
sの後にmov
がある最初のケースを除き、同じマシンコードを生成します。これは、ユーザーとして好きなものを使用し、コンパイラーに残りを任せることを意味します。
最後に、いとこ演算子*=
と/=
にはpostfixとprefixの対応するものがないことに注意してください。
++
プレフィックスまたはポストフィックス演算子変更変数値。
int a = 0;
int b = a++; // b is equal to 0, a is equal to 1
またはプレフィックス:
int a = 0;
int b = ++a; // b = 1, a = 1
このように使用する場合、それらは同じです:
int a = 0;
++a; // 1
a++; // 2
a += 1; // 3
両方の演算子はnの値を1増やします。代入演算子とともに演算子を使用すると、両者の違いが存在します。
例えば:
最初のケース-ポストインクリメント演算子
int n=5;
int new_var;
new_var=n++;
print("%d",new_var);
出力= 5
2番目のケース
int n=5;
n+=1;
new_var=n;
print("%d",new_var);
出力= 6
これは、プリインクリメント演算子の結果と非常に似ています。
事前インクリメント演算子を使用した2番目のケース
int n=5;
new_var=++n;
print("%d",new_var);
出力= 6
それらは一般的に同じであり、それらの違いを明確にする意味はありません。しかし、これら2つのステートメントの実装は実際には異なります。たとえば、a + = 1はassemberにコンパイルされます
a、1を追加
and a ++または++ aは
inc a
2つの異なるCPU動作であるため、効率に若干の違いが生じる可能性があります。
これらの2つの演算子は似ているように見えるかもしれませんが、まったく異なっています。
プリミティブ型(ポインター、整数など)の場合、どちらも値を1ずつ増やします。ただし、C++クラスの場合、異なる演算子(operator+=
vs. operator++
)を呼び出します。実際、list<T>::iterator
などの一部のクラスでは、i += 1
は機能せず、i++
を使用する必要があります。
さらに、それらは異なる値を生成します。 i += 1
は(プリインクリメントのように)インクリメント後にi
を生成しますが、i++
はインクリメント前にi
を生成します。したがって、
int a = 0, b = 0;
cout << (a+=1) << " " << b++ << endl;
1 0
を出力します。 i += 1
はプリインクリメントと同等であるため、場合によってはi += 1
が生じる可能性があります
したがって、変数の増分については同じですが、すべての条件で完全な代替物ではないことに注意してください。
一部の人は違いに近づいていますが、非常に明確に述べる必要があります。
彼らは非常に異なる演算子です。
プリインクリメント演算子とポストインクリメント演算子は、変数の値がそれを囲む式で使用される前または後に変数の値を変更するために、INSIDE EXPRESSIONSで使用されるように設計されています。 postincrement演算子を使用する場合、変数のOLD値を使用して囲み式が評価され、その後で変数がインクリメントされます。
例えば:
i = 10;
j = i++; // This causes j to be 10 while i becomes 11.
これが、ポストインクリメント演算子と呼ばれる理由です。変数はインクリメントされますPOST(AFTER)その値はより大きい式(ここでは代入式)で使用されます。
ただし、次の場合:
i = 10;
j = ++i; // Now both i and j will be 11 because the increment
// of i occurs PRE (BEFORE) its value is used in the greater expression.
少なくとも古いコンパイラー/コンピューター(基本的にCが生まれて10年か2年後)について+= 1
がかなり++
より遅いことに誰も言及していないことに驚いています。 ++
は、CPUが単一の命令を持っている可能性が最も高い増分です。 += 1
は、値1をレジスターにロードし(その値をどこかに保存する可能性があります...どこかに)、追加を呼び出す必要があります。現在のコンパイラがこれを最適化するかどうかは言えませんが、そうだと思います。
Stackoverflowは初めてですが、ここに2ペンスの価値があります。
質問が+ = 1ではなく+ =に関するものである場合。投稿された声明は
私は通常++または+ = 1を使用する状況に遭遇しますが、それらの違いはわかりません。
1は簡単に別の数字になったり、おそらく+ =?
結果に関しては、違いはありません(ポスターの値を使用)。両方とも1ずつ増加しますが、++は1だけ増加しますが、+ =はコーダーによって指定された値だけ増加します。edermanの例では1になります。例:
// Example 1:
num = 0;
num = ++;
// the result of num will be 1
// Example 2:
num = 0;
num = += 1;
// the result of num will be 1 the same as example 1
// Example 3:
num = 0;
num = += 2;
// the result of num will be 2.
// Example 4:
num = 0;
num = ++ 2;
// this would not compile as ++ will not except any value for the increment step it is assumed
// you will always want to increment by the value of 1
したがって、値を1だけ増やす場合は++を使用しますが、1だけ増やす必要がある場合は+ =を使用します
それが役に立つことを願っています。
++は値を1増やすために使用され、+ =を使用すると別の量だけ増やすことができます。