Sự khác biệt giữa tăng trước và tăng sau trong một vòng lặp?


303

Có một sự khác biệt trong ++ii++trong một forvòng lặp? Nó chỉ đơn giản là một điều cú pháp?



18
Tôi ngạc nhiên khi có nhiều câu trả lời hoàn toàn bỏ lỡ điểm của câu hỏi.
Graeme Perrow

3
Có lẽ chúng ta nên ngạc nhiên khi không ai chỉnh sửa câu hỏi để rõ ràng hơn :)
Jon B

2
Câu hỏi này có thể áp dụng cho C, Java, C ++, PHP, C #, Javascript, JScript, Objective C: en.wikipedia.org/wiki/Carget:C_programming_lingu_f Family
Chris S

1
Câu trả lời hay được đăng ở đây: stackoverflow.com/a/4706225/214296
Jim Fell

Câu trả lời:


233

a ++ được gọi là hậu tố.

thêm 1 vào a, trả về giá trị cũ.

++ a được gọi là tiền tố.

thêm 1 vào a, trả về giá trị mới.

C #:

string[] items = {"a","b","c","d"};
int i = 0;
foreach (string item in items)
{
    Console.WriteLine(++i);
}
Console.WriteLine("");

i = 0;
foreach (string item in items)
{
    Console.WriteLine(i++);
}

Đầu ra:

1
2
3
4

0
1
2
3

foreachwhilecác vòng lặp phụ thuộc vào loại tăng bạn sử dụng. Với các vòng lặp như bên dưới, sẽ không có gì khác biệt khi bạn không sử dụng giá trị trả về của i:

for (int i = 0; i < 5; i++) { Console.Write(i);}
Console.WriteLine("");
for (int i = 0; i < 5; ++i) { Console.Write(i); }

0 1 2 3 4
0 1 2 3 4

Nếu giá trị như được đánh giá được sử dụng thì loại gia tăng trở nên đáng kể:

int n = 0;
for (int i = 0; n < 5; n = i++) { }

4
Đây thậm chí không phải là những gì người dùng yêu cầu.
Dimitri

223

Gia tăng trước ++ i tăng giá trị của i và ước tính giá trị tăng mới.

int i = 3;
int preIncrementResult = ++i;
Assert( preIncrementResult == 4 );
Assert( i == 4 );

Tăng sau i ++ tăng giá trị của i và ước tính giá trị không tăng ban đầu.

int i = 3;
int postIncrementResult = i++;
Assert( postIncrementtResult == 3 );
Assert( i == 4 );

Trong C ++, phần tăng trước thường được ưa thích hơn ở nơi bạn có thể sử dụng.

Điều này là do nếu bạn sử dụng tăng sau, nó có thể yêu cầu trình biên dịch phải tạo mã tạo thêm một biến tạm thời. Điều này là do cả hai giá trị trước và mới của biến đang được tăng cần phải được giữ ở đâu đó vì chúng có thể cần ở nơi khác trong biểu thức được ước tính.

Vì vậy, trong C ++ ít nhất, có thể có sự khác biệt về hiệu năng hướng dẫn lựa chọn sử dụng của bạn.

Đây chủ yếu chỉ là một vấn đề khi biến được tăng lên là loại do người dùng xác định với toán tử ++ bị ghi đè. Đối với các kiểu nguyên thủy (int, v.v.) không có sự khác biệt về hiệu năng. Nhưng, nó đáng để gắn bó với toán tử tăng trước như một hướng dẫn trừ khi toán tử tăng sau chắc chắn là những gì được yêu cầu.

Có một số thảo luận thêm ở đây:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htmlm

Trong C ++ nếu bạn đang sử dụng STL, thì bạn có thể đang sử dụng các vòng lặp với các trình vòng lặp. Những thứ này chủ yếu có các toán tử ++ được ghi đè, vì vậy việc bám vào tiền tăng là một ý tưởng tốt. Trình biên dịch trở nên thông minh hơn mọi lúc, và các trình biên dịch mới hơn có thể thực hiện tối ưu hóa có nghĩa là không có sự khác biệt về hiệu suất - đặc biệt là nếu kiểu tăng được xác định nội tuyến trong tệp tiêu đề (như thường triển khai STL) để trình biên dịch có thể thấy phương pháp được thực hiện và sau đó có thể biết tối ưu hóa nào là an toàn để thực hiện. Mặc dù vậy, có lẽ vẫn đáng để gắn bó trước khi tăng vì các vòng lặp được thực thi rất nhiều lần và điều này có nghĩa là một hình phạt hiệu suất nhỏ có thể sớm được khuếch đại.


Trong các ngôn ngữ khác như C # nơi toán tử ++ không thể bị quá tải, không có sự khác biệt về hiệu năng. Được sử dụng trong một vòng lặp để tiến tới biến vòng lặp, các toán tử gia tăng trước và sau là tương đương.

Sửa chữa: quá tải ++ trong C # được cho phép. Dường như, so với C ++, trong c #, bạn không thể quá tải các phiên bản trước và sau một cách độc lập. Vì vậy, tôi sẽ giả sử rằng nếu kết quả của việc gọi ++ trong C # không được gán cho một biến hoặc được sử dụng như một phần của biểu thức phức tạp, thì trình biên dịch sẽ giảm các phiên bản trước và sau của ++ xuống mã thực hiện tương đương.


102
Sẽ không tuyệt sao nếu C ++ được đặt tên là ++ C chỉ ra rằng bạn có thể viết mã được tối ưu hóa tốt bằng cách sử dụng nó ..
Naveen

9
Không phải trình biên dịch hiện đại có thể tối ưu hóa điều này khi giá trị kết quả rõ ràng sẽ bị vứt đi không?
che

6
@che - họ làm khi đó là một loại đơn giản, tuy nhiên các lớp quá tải toán tử ++ (như trình lặp) là một câu chuyện khác.
Ferruccio

7
@che: Đó là một câu hỏi hay. Lý do các trình biên dịch C ++ không thay thế "CustomType ++;" với "++ CustomType;" là bởi vì không có gì đảm bảo rằng cả hai hàm do người dùng định nghĩa đều có tác dụng như nhau. Họ NÊN ... nhưng không có gì đảm bảo.
Drew Dormann

2
@ michael.bartnett: Điểm hay, quá tải ++ trong C # dường như không khả dụng. Dường như, so với c ++, trong c #, bạn không thể quá tải các phiên bản trước và sau một cách độc lập. Vì vậy, tôi sẽ giả sử rằng nếu kết quả của việc gọi ++ trong C # không được gán cho một biến hoặc được sử dụng như một phần của biểu thức phức tạp, thì trình biên dịch sẽ giảm các phiên bản trước và sau của ++ xuống mã thực hiện tương đương.
Scott Langham

83

Trong C # không có sự khác biệt khi được sử dụng trong một vòng lặp for .

for (int i = 0; i < 10; i++) { Console.WriteLine(i); }

xuất ra điều tương tự như

for (int i = 0; i < 10; ++i) { Console.WriteLine(i); }

Như những người khác đã chỉ ra, khi được sử dụng nói chung i ++ và ++ tôi có một sự khác biệt tinh tế nhưng quan trọng:

int i = 0;
Console.WriteLine(i++);   // Prints 0
int j = 0;
Console.WriteLine(++j);   // Prints 1

i ++ đọc giá trị của i sau đó tăng nó.

++ tôi tăng giá trị của i sau đó đọc nó.


Kết luận: cùng một ngữ nghĩa gia tăng bài / trước như trong C ++.
xtofl

@xtofl - không chắc quan điểm của bạn là gì? Tôi chỉ tình cờ chọn c # cho ví dụ của tôi.
Jon B

3
Tôi không nghĩ rằng điểm đầu tiên có liên quan. Trong một vòng lặp for (c # hoặc không), phần tăng luôn được thực hiện sau phần thân của vòng lặp. Sau khi thực hiện, biến được sửa đổi cho dù bài đăng hoặc gia tăng trước được sử dụng.
MatthieuP

9
@MatthieuP - Tôi đọc câu hỏi là "không quan trọng bạn sử dụng i ++ hay ++ i trong một vòng lặp for". Câu trả lời là "không, không".
Jon B

1
@JonB Thứ tự các thao tác trong câu trả lời không chính xác. Cả hai ++ii++thực hiện các hoạt động giống nhau theo cùng một thứ tự: tạo bản sao tạm thời của i; tăng giá trị tạm thời để tạo ra một giá trị mới (không ghi đè lên temp); lưu trữ giá trị mới trong i; bây giờ nếu ++ikết quả trả về là giá trị mới; nếu đó là i++kết quả trả về là bản sao tạm thời. Câu trả lời chi tiết hơn tại đây: stackoverflow.com/a/3346729/3330348
PiotrWolkowski

51

Câu hỏi là:

Có sự khác biệt trong ++ i và i ++ trong một vòng lặp for không?

Câu trả lời là: Không .

Tại sao mỗi câu trả lời khác phải đi vào giải thích chi tiết về việc tăng trước và sau khi điều này thậm chí không được hỏi?

Vòng lặp for này:

for (int i = 0; // Initialization
     i < 5;     // Condition
     i++)       // Increment
{
   Output(i);
}

Sẽ dịch sang mã này mà không cần sử dụng các vòng lặp:

int i = 0; // Initialization

loopStart:
if (i < 5) // Condition
{
   Output(i);

   i++ or ++i; // Increment

   goto loopStart;
}

Bây giờ có vấn đề gì nếu bạn đặt i++hoặc ++ităng dần ở đây? Không, nó không phải là giá trị trả về của hoạt động gia tăng là không đáng kể. isẽ được tăng sau khi thực thi mã bên trong thân vòng lặp for.


2
Đây thực sự là câu trả lời đầu tiên đi thẳng vào vấn đề. Cảm ơn.
Yassir

1
Đây không phải là câu trả lời tốt nhất vì nếu vòng lặp for đang tăng một đối tượng phức tạp (thứ gì đó không phải là int!) Thì việc thực hiện ++ x có thể nhanh hơn x ++ ... (xem Herbutter.com/2013/05/13/gotw -2-giải pháp-tạm thời-đối tượng )
JCx

30

Vì bạn hỏi về sự khác biệt trong một vòng lặp, tôi đoán ý bạn là

for(int i=0; i<10; i++) 
    ...;

Trong trường hợp đó, bạn không có sự khác biệt trong hầu hết các ngôn ngữ: Vòng lặp hoạt động giống nhau bất kể bạn viết i++++i. Trong C ++, bạn có thể viết các phiên bản toán tử ++ của riêng mình và bạn có thể xác định các ý nghĩa riêng cho chúng, nếu đó ilà loại do người dùng xác định (ví dụ: lớp của riêng bạn).

Lý do tại sao nó không quan trọng ở trên là vì bạn không sử dụng giá trị của i++. Một điều nữa là khi bạn làm

for(int i=0, a = 0; i<10; a = i++) 
    ...;

Bây giờ, có một sự khác biệt, bởi vì như những người khác chỉ ra, i++phương tiện tăng, nhưng đánh giá với giá trị trước đó , nhưng ++iphương tiện tăng, nhưng đánh giá đểi (như vậy, nó sẽ đánh giá với giá trị mới). Trong trường hợp trên, ađược gán giá trị trước đó của i, trong khi i được tăng lên.


3
Trong C ++, trình biên dịch không phải lúc nào cũng có thể tránh tạo tạm thời, vì vậy hình thức tăng trước được ưu tiên.
David Thornley

như tôi viết, nếu bạn có một loại i do người dùng định nghĩa, họ có thể có các ngữ nghĩa khác nhau. nhưng nếu bạn sử dụng i kiểu nguyên thủy, thì nó không tạo ra sự khác biệt cho vòng lặp đầu tiên. vì đây là một câu hỏi bất khả tri về ngôn ngữ, tôi đã tìm cách không viết quá nhiều về những thứ cụ thể của C ++.
Julian Schaub - litb

15

Như mã này hiển thị (xem MSIL bị phân tán trong các bình luận), trình biên dịch C # 3 không phân biệt giữa i ++ và ++ i trong một vòng lặp for. Nếu giá trị của i ++ hoặc ++ tôi đang được sử dụng, chắc chắn sẽ có một sự khác biệt (điều này đã được biên soạn trong Visutal Studio 2008 / Release Build):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PreOrPostIncrement
{
    class Program
    {
        static int SomethingToIncrement;

        static void Main(string[] args)
        {
            PreIncrement(1000);
            PostIncrement(1000);
            Console.WriteLine("SomethingToIncrement={0}", SomethingToIncrement);
        }

        static void PreIncrement(int count)
        {
            /*
            .method private hidebysig static void  PreIncrement(int32 count) cil managed
            {
              // Code size       25 (0x19)
              .maxstack  2
              .locals init ([0] int32 i)
              IL_0000:  ldc.i4.0
              IL_0001:  stloc.0
              IL_0002:  br.s       IL_0014
              IL_0004:  ldsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
              IL_0009:  ldc.i4.1
              IL_000a:  add
              IL_000b:  stsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
              IL_0010:  ldloc.0
              IL_0011:  ldc.i4.1
              IL_0012:  add
              IL_0013:  stloc.0
              IL_0014:  ldloc.0
              IL_0015:  ldarg.0
              IL_0016:  blt.s      IL_0004
              IL_0018:  ret
            } // end of method Program::PreIncrement             
             */
            for (int i = 0; i < count; ++i)
            {
                ++SomethingToIncrement;
            }
        }

        static void PostIncrement(int count)
        {
            /*
                .method private hidebysig static void  PostIncrement(int32 count) cil managed
                {
                  // Code size       25 (0x19)
                  .maxstack  2
                  .locals init ([0] int32 i)
                  IL_0000:  ldc.i4.0
                  IL_0001:  stloc.0
                  IL_0002:  br.s       IL_0014
                  IL_0004:  ldsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
                  IL_0009:  ldc.i4.1
                  IL_000a:  add
                  IL_000b:  stsfld     int32 PreOrPostIncrement.Program::SomethingToIncrement
                  IL_0010:  ldloc.0
                  IL_0011:  ldc.i4.1
                  IL_0012:  add
                  IL_0013:  stloc.0
                  IL_0014:  ldloc.0
                  IL_0015:  ldarg.0
                  IL_0016:  blt.s      IL_0004
                  IL_0018:  ret
                } // end of method Program::PostIncrement
             */
            for (int i = 0; i < count; i++)
            {
                SomethingToIncrement++;
            }
        }
    }
}

14

Một (++ i) là preincrement, một (i ++) là postincrement. Sự khác biệt là giá trị nào được trả về ngay từ biểu thức.

// Psuedocode
int i = 0;
print i++; // Prints 0
print i; // Prints 1
int j = 0;
print ++j; // Prints 1
print j; // Prints 1

Chỉnh sửa: Woops, hoàn toàn bỏ qua phía vòng lặp của sự vật. Không có sự khác biệt thực sự trong các vòng lặp khi đó là phần 'bước' (cho (...; ...;)), nhưng nó có thể phát huy tác dụng trong các trường hợp khác.


7

Không có sự khác biệt nếu bạn không sử dụng giá trị sau khi tăng trong vòng lặp.

for (int i = 0; i < 4; ++i){
cout<<i;       
}
for (int i = 0; i < 4; i++){
cout<<i;       
}

Cả hai vòng sẽ in 0123.

Nhưng sự khác biệt xuất hiện khi bạn sử dụng giá trị sau khi tăng / giảm trong vòng lặp của bạn như sau:

Vòng lặp tăng trước:

for (int i = 0,k=0; i < 4; k=++i){
cout<<i<<" ";       
cout<<k<<" "; 
}

Đầu ra: 0 0 1 1 2 2 3 3

Bài viết tăng vòng:

for (int i = 0, k=0; i < 4; k=i++){
cout<<i<<" ";       
cout<<k<<" "; 
}

Đầu ra: 0 0 1 0 2 1 3 2

Tôi hy vọng sự khác biệt là rõ ràng bằng cách so sánh đầu ra. Điểm cần lưu ý ở đây là tăng / giảm luôn được thực hiện ở cuối vòng lặp for và do đó kết quả có thể được giải thích.


7

Dưới đây là Mẫu Java và Mã byte, mã hậu và tiền mã hóa cho thấy không có sự khác biệt nào trong Mã byte:

public class PreOrPostIncrement {

    static int somethingToIncrement = 0;

    public static void main(String[] args) {
        final int rounds = 1000;
        postIncrement(rounds);
        preIncrement(rounds);
    }

    private static void postIncrement(final int rounds) {
        for (int i = 0; i < rounds; i++) {
            somethingToIncrement++;
        }
    }

    private static void preIncrement(final int rounds) {
        for (int i = 0; i < rounds; ++i) {
            ++somethingToIncrement;
        }
    }
}

Và bây giờ cho mã byte (javap -private -c PreOrPostIncrement):

public class PreOrPostIncrement extends java.lang.Object{
static int somethingToIncrement;

static {};
Code:
0:  iconst_0
1:  putstatic   #10; //Field somethingToIncrement:I
4:  return

public PreOrPostIncrement();
Code:
0:  aload_0
1:  invokespecial   #15; //Method java/lang/Object."<init>":()V
4:  return

public static void main(java.lang.String[]);
Code:
0:  sipush  1000
3:  istore_1
4:  sipush  1000
7:  invokestatic    #21; //Method postIncrement:(I)V
10: sipush  1000
13: invokestatic    #25; //Method preIncrement:(I)V
16: return

private static void postIncrement(int);
Code:
0:  iconst_0
1:  istore_1
2:  goto    16
5:  getstatic   #10; //Field somethingToIncrement:I
8:  iconst_1
9:  iadd
10: putstatic   #10; //Field somethingToIncrement:I
13: iinc    1, 1
16: iload_1
17: iload_0
18: if_icmplt   5
21: return

private static void preIncrement(int);
Code:
0:  iconst_0
1:  istore_1
2:  goto    16
5:  getstatic   #10; //Field somethingToIncrement:I
8:  iconst_1
9:  iadd
10: putstatic   #10; //Field somethingToIncrement:I
13: iinc    1, 1
16: iload_1
17: iload_0
18: if_icmplt   5
21: return

}

5

Có, có. Sự khác biệt là trong giá trị trả lại. Giá trị trả về của "++ i" sẽ là giá trị sau khi tăng i. Giá trị của "i ++" sẽ là giá trị trước khi tăng. Điều này có nghĩa là mã trông giống như sau:

int a = 0;
int b = ++a; // a is incremented and the result after incrementing is saved to b.
int c = a++; // a is incremented again and the result before incremening is saved to c.

Do đó, a sẽ là 2, và b và c sẽ là 1.

Tôi có thể viết lại mã như thế này:

int a = 0; 

// ++a;
a = a + 1; // incrementing first.
b = a; // setting second. 

// a++;
c = a; // setting first. 
a = a + 1; // incrementing second. 

4

Không có sự khác biệt thực tế trong cả hai trường hợp ' i' sẽ được tăng thêm 1.

Nhưng có một sự khác biệt khi bạn sử dụng nó trong một biểu thức, ví dụ:

int i = 1;
int a = ++i;
// i is incremented by one and then assigned to a.
// Both i and a are now 2.
int b = i++;
// i is assigned to b and then incremented by one.
// b is now 2, and i is now 3

3

Có nhiều hơn ++ i và i ++ hơn là các vòng lặp và hiệu suất khác nhau. ++ i trả về giá trị l và i ++ trả về giá trị r. Dựa trên điều này, có rất nhiều điều bạn có thể làm (++ i) nhưng không phải (i ++).

1- It is illegal to take the address of post increment result. Compiler won't even allow you.
2- Only constant references to post increment can exist, i.e., of the form const T&.
3- You cannot apply another post increment or decrement to the result of i++, i.e., there is no such thing as I++++. This would be parsed as ( i ++ ) ++ which is illegal.
4- When overloading pre-/post-increment and decrement operators, programmers are encouraged to define post- increment/decrement operators like:

T& operator ++ ( )
{
   // logical increment
   return *this;
}

const T operator ++ ( int )
{
    T temp( *this );
    ++*this;
    return temp;
}

3

Nó làm tôi suy nghĩ tại sao mọi người có thể viết biểu thức gia tăng trong vòng lặp for là i ++.

Trong vòng lặp for, khi thành phần thứ 3 là một câu lệnh tăng đơn giản, như trong

for (i=0; i<x; i++)  

hoặc là

for (i=0; i<x; ++i)   

không có sự khác biệt trong việc thực hiện kết quả.


Đó là một câu trả lời, hay nó là một câu hỏi?
Palec

2
Vì nó không thành vấn đề, tại sao nó lại làm lu mờ tâm trí của bạn cho dù ai đó đã viết i ++? Có một số lý do tại sao một người nào đó thích viết ++ i?
Dronz

2

Như @Jon B nói, không có sự khác biệt trong một vòng lặp for.

Nhưng trong một vòng lặp whilehoặc do...while, bạn có thể tìm thấy một số khác biệt nếu bạn đang so sánh với ++ihoặci++

while(i++ < 10) { ... } //compare then increment

while(++i < 10) { ... } //increment then compare

hai downvote? Điều gì là sai với những gì tôi đã viết? Và nó có liên quan đến câu hỏi (mơ hồ như nó là).
crashmstr

2

Trong javascript do i ++ sau đây có thể tốt hơn để sử dụng:

var i=1;
alert(i++); // before, 1. current, 1. after, 2.
alert(i); // before, 2. current, 2. after, 2.
alert(++i); // before, 2. current, 3 after, 3.

Trong khi các mảng (tôi nghĩ là tất cả) và một số hàm và cuộc gọi khác sử dụng 0 làm điểm bắt đầu, bạn sẽ phải đặt i thành -1 để làm cho vòng lặp hoạt động với mảng khi sử dụng ++ i .

Khi sử dụng i ++ , giá trị sau sẽ sử dụng giá trị tăng. Bạn có thể nói i ++ là cách con người đếm, vì bạn có thể bắt đầu bằng 0 .


2

Để hiểu vòng lặp FOR làm gì

nhập mô tả hình ảnh ở đây

Hình ảnh trên cho thấy FOR có thể được chuyển đổi thành WHILE , vì cuối cùng chúng có mã lắp ráp hoàn toàn giống nhau (ít nhất là trong gcc). Vì vậy, chúng ta có thể chia FOR thành một vài mảnh, để thực hiện những gì nó làm.

for (i = 0; i < 5; ++i) {
  DoSomethingA();
  DoSomethingB();
}

bằng với phiên bản WHILE

i = 0; //first argument (a statement) of for
while (i < 5 /*second argument (a condition) of for*/) {
  DoSomethingA();
  DoSomethingB();
  ++i; //third argument (another statement) of for
}

Điều đó có nghĩa là bạn có thể sử dụng FOR như một phiên bản đơn giản của WHILE :

  1. Đối số đầu tiên của FOR (int i) được thực thi, bên ngoài, trước vòng lặp.

  2. Đối số thứ ba của FOR (i ++ hoặc ++ i) được thực thi, bên trong, trong dòng cuối cùng của vòng lặp.

TL: DR: cho dù có i++hay không ++i, chúng tôi biết rằng khi chúng ở dạng độc lập, chúng không tạo ra sự khác biệt nào ngoài bản thân +1.

Ở trường, họ thường dạy cách i ++, nhưng cũng có nhiều người thích cách i ++ vì một số lý do .

LƯU Ý: Trước đây, i ++ có rất ít ảnh hưởng đến hiệu suất, vì nó không chỉ cộng với một mà còn giữ giá trị ban đầu trong thanh ghi. Nhưng bây giờ, nó không có sự khác biệt vì trình biên dịch làm cho phần cộng giống nhau.


1

Có thể có một sự khác biệt cho các vòng lặp. Đây là ứng dụng thực tế của bài / tăng trước.

        int i = 0;
        while(i++ <= 10) {
            Console.Write(i);
        }
        Console.Write(System.Environment.NewLine);

        i = 0;
        while(++i <= 10) {
            Console.Write(i);
        }
        Console.ReadLine();

Trong khi cái đầu tiên đếm đến 11 và vòng lặp 11 lần, thì cái thứ hai thì không.

Chủ yếu là điều này được sử dụng trong một thời gian đơn giản (x--> 0); - - Lặp lại để lặp lại ví dụ tất cả các phần tử của một mảng (miễn các cấu trúc foreach ở đây).


1

Cả hai đều tăng số lượng. ++itương đương với i = i + 1.

i++++irất giống nhau nhưng không hoàn toàn giống nhau. Cả hai đều tăng số, nhưng ++ităng số trước khi biểu thức hiện tại được ước tính, trong khi i++tăng số sau khi biểu thức được ước tính.

int i = 3;
int a = i++; // a = 3, i = 4
int b = ++a; // b = 4, a = 

Kiểm tra liên kết này .


0

Có, có một sự khác biệt giữa ++ii++trong một forvòng lặp, mặc dù trong các trường hợp sử dụng bất thường; khi một biến vòng lặp với toán tử tăng / giảm được sử dụng trong khối for hoặc trong biểu thức kiểm tra vòng lặp hoặc với một trong các biến vòng lặp . Không, nó không chỉ đơn giản là một điều cú pháp.

Như itrong một mã có nghĩa là đánh giá biểu thức ivà toán tử không có nghĩa là đánh giá mà chỉ là một hoạt động;

  • ++icó nghĩa là giá trị gia tăng của i1 và sau đó đánh giái ,
  • i++có nghĩa là đánh giá ivà tăng giá trị sau này ibằng 1.

Vì vậy, những gì thu được từ mỗi hai biểu thức khác nhau bởi vì những gì được đánh giá khác nhau ở mỗi biểu thức. Tất cả giống nhau cho--ii--

Ví dụ;

let i = 0

i++ // evaluates to value of i, means evaluates to 0, later increments i by 1, i is now 1
0
i
1
++i // increments i by 1, i is now 2, later evaluates to value of i, means evaluates to 2
2
i
2

Trong các trường hợp sử dụng bất thường, tuy nhiên ví dụ tiếp theo nghe có hữu ích hay không không quan trọng, nó cho thấy sự khác biệt

for(i=0, j=i; i<10; j=++i){
    console.log(j, i)
}

for(i=0, j=i; i<10; j=i++){
    console.log(j, i)
}

Điều này thêm gì vào câu trả lời hiện có?
GManNickG

nó trả lời trực tiếp hơn những gì được hỏi hơn những câu trả lời tôi đã đọc.
Selçuk

-2

Đối với icác loại do người dùng định nghĩa, các toán tử này có thể (nhưng không nên ) có các sơ đồ khác nhau một cách có ý nghĩa trong ngữ cảnh của một chỉ mục vòng lặp và điều này có thể (nhưng không nên) ảnh hưởng đến hành vi của vòng lặp được mô tả.

Ngoài ra, c++nói chung là an toàn nhất để sử dụng biểu mẫu tăng trước ( ++i) vì nó được tối ưu hóa dễ dàng hơn. (Scott Langham đánh tôi đến miếng ngon này . Nguyền rủa bạn, Scott)


Các ngữ nghĩa của postfix được cho là lớn hơn tiền tố. -1
xtofl

-2

Tôi không biết các ngôn ngữ khác nhưng trong Java ++ igia tăng tiền tố có nghĩa là: tăng i lên 1 và sau đó sử dụng giá trị mới của i trong biểu thức mà tôi cư trú và i ++gia tăng tiền tố có nghĩa là sau : sử dụng giá trị hiện tại của i trong biểu thức và sau đó tăng nó lên 1. Ví dụ:

public static void main(String [] args){

    int a = 3;
    int b = 5;
    System.out.println(++a);
    System.out.println(b++);
    System.out.println(b);

} và đầu ra là:

  • 4
  • 5
  • 6

-3

i ++; ++ tôi; cả hai đều tương tự nhau vì chúng không được sử dụng trong một biểu thức.

class A {

     public static void main (String []args) {

     int j = 0 ;
     int k = 0 ;
     ++j;
     k++;
    System.out.println(k+" "+j);

}}

prints out :  1 1
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.