簡體   English   中英

“++”和“+= 1”運算符有什么區別?

[英]What is the difference between "++" and "+= 1 " operators?

在 C++ 的循環中,我通常會遇到使用+++=1的情況,但我無法分辨它們的區別。 例如,如果我有一個整數

int num = 0;

然后我循環執行:

num ++;

要么

num += 1;

它們都增加了num的值,但它們有什么區別? 我懷疑num++能否比num+=1工作得更快,但如何呢? 這種差異是否細微到可以忽略?

num += 1相當於++num

所有這些表達式( num += 1num++++num )都會將num的值遞增 1,但num++的值是num在遞增之前的值。

插圖:

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因為它更短。

前綴后綴操作是考題的完美候選。

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一起使用時,它們主要充當前綴操作。 事實上,在我的機器上,它們生成相同的機器代碼。 您可以使用示例程序來嘗試此操作,例如:

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.

正如您所看到的,即使沒有打開編譯器優化,它們也會生成相同的機器代碼,除了第一種情況,它在mov之后有addl 這意味着您應該使用任何您喜歡的用戶,讓編譯器人員完成剩下的工作。

最后,請注意表親運算符*=/=沒有對應的后綴前綴

++前綴或后綴運算符更改變量值。

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

第二個案例

int n=5;
n+=1;
new_var=n;
print("%d",new_var);

輸出=6

這與預增量運算符的結果非常相似。

使用預增量運算符的第二種情況

int n=5;

new_var=++n;
print("%d",new_var);

輸出=6

這兩個運算符可能看起來很相似,但它們是完全不同的。

對於原始類型(指針、整數等),它們都將值遞增 1。 但是,對於 C++ 類,它們調用不同的運算符( operator+=operator++ ); 實際上,對於某些類,例如list<T>::iteratori += 1不起作用,必須使用i++

此外,它們產生不同的價值。 i += 1在遞增之后產生i (類似於預遞增),而i++在遞增之前產生i 因此,

int a = 0, b = 0;
cout << (a+=1) << " " << b++ << endl;

打印1 0 因為i += 1等同於預增量,所以在某些情況下, i += 1可能導致與i++不同的行為。

因此,雖然它們對於遞增變量是相同的,但應該意識到它們並不是在所有情況下的完美替代品。

它們大體上是相同的,澄清它們之間的區別沒有意義。 但是這兩個語句的實現實際上是不同的。 例如,a+=1 編譯為匯編是
添加一個,1
而 a++ 或 ++a 是
公司
由於它們是兩個不同的 CPU 操作,因此效率可能略有不同。

你們中的一些人正在接近差異,但應該非常清楚地說明:

他們是非常不同的運營商。

preincrement 和 postincrement 運算符旨在用於 INSIDE EXPRESSIONS 以在變量值用於包含它的任何表達式之前或之后更改變量值。 使用后增量運算符時,變量的舊值用於計算封閉表達式,並且僅在此之后變量才會遞增。

例如:

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 誕生時以及之后的一兩年) += 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,而使用 += 可以遞增另一個值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM