Bir döngüdeki artış öncesi ve artış sonrası arasındaki fark nedir?


303

Bir fark var mı ++ive i++bir de fordöngü? Bu sadece bir sözdizimi midir?



18
Sorunun amacını kaç cevapın tamamen kaçırdığına şaşırdım.
Graeme Perrow

3
Belki de kimsenin soruyu daha açık olması için düzenlemediğine şaşırmalıyız :)
Jon B

2
Bu soru C, Java, C ++, PHP, C #, Javascript, JScript, Amaç C için geçerli olabilir: en.wikipedia.org/wiki/Category:C_programming_language_family
Chris S

1
İyi yanıt burada yayınlanmıştır: stackoverflow.com/a/4706225/214296
Jim Fell

Yanıtlar:


233

a ++ postfix olarak bilinir.

a 1 eklenirse eski değeri döndürür.

++ a öneki olarak bilinir.

a 1 eklenirse, yeni değer döndürülür.

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++);
}

Çıktı:

1
2
3
4

0
1
2
3

foreachve whiledöngüler kullandığınız artış türüne bağlıdır. Aşağıdaki gibi döngüler için, i'nin dönüş değerini kullanmıyorsanız fark etmez:

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

Değerlendirildiği şekliyle değer kullanılırsa, artışın türü anlamlı hale gelir:

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

4
Bu kullanıcının istediği şey bile değil.
Dimitri

223

Ön artış ++ i , i değerini artırır ve yeni artan değere göre değerlendirir.

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

Artış sonrası i ++ , i değerini artırır ve orijinal artmamış değere göre değerlendirir.

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

C ++ 'da, her ikisini de kullanabileceğiniz yerlerde genellikle ön artış tercih edilir.

Çünkü artım sonrası kullanırsanız, derleyicinin fazladan bir geçici değişken oluşturan kod üretmesi gerekebilir. Bunun nedeni, artırılan değişkenin hem önceki hem de yeni değerlerinin bir yerde tutulması gerektiğidir, çünkü değerlendirilmekte olan ifadede başka bir yere ihtiyaç duyulabilir.

Yani, en azından C ++ 'da, hangisini kullanacağınıza karar veren bir performans farkı olabilir.

Bu, yalnızca artırılan değişken, geçersiz kılınmış bir ++ işlecine sahip kullanıcı tanımlı bir tür olduğunda yalnızca bir sorundur. İlkel tipler (int, vb.) İçin performans farkı yoktur. Ancak, artım sonrası operatör kesinlikle gerekli olmadığı sürece, ön artış operatörüne bir kılavuz olarak bağlı kalmaya değer.

Burada daha fazla tartışma var:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htm

C ++ 'da STL kullanıyorsanız yineleyiciler ile döngüler için kullanıyor olabilirsiniz. Bunlar esas olarak geçersiz kılınmış ++ operatörlerine sahiptir, bu nedenle ön artışa bağlı kalmak iyi bir fikirdir. Derleyiciler her zaman daha akıllı hale gelir ve daha yenileri performans farkı olmadığı anlamına gelen optimizasyonlar gerçekleştirebilir - özellikle artırılan tür başlık dosyasında satır içi olarak tanımlanırsa (STL uygulamaları sıklıkla olduğu gibi) yöntem uygulanır ve daha sonra hangi optimizasyonların güvenli bir şekilde gerçekleştirilebileceğini bilir. Yine de, büyük olasılıkla hala artmaya devam etmeye değer çünkü döngüler birçok kez idam edilir ve bu da küçük bir performans cezasının yakında yükseltilebileceği anlamına gelir.


++ operatörünün aşırı yüklenemediği C # gibi diğer dillerde performans farkı yoktur. Döngü değişkenini ilerletmek için bir döngüde kullanıldığında, öncesi ve sonrası artış işleçleri eşdeğerdir.

Düzeltme: C # 'da aşırı yüklenmeye ++ izin verilir. Görünüşe göre, C ++ ile karşılaştırıldığında, c # 'da ön ve son sürümleri bağımsız olarak aşırı yükleyemezsiniz. Bu nedenle, C # 'da ++ çağrılmasının sonucu bir değişkene atanmamışsa veya karmaşık bir ifadenin parçası olarak kullanılmamışsa, derleyicinin ++ öncesi ve sonrası sürümlerini eşdeğer performans gösteren koda indirgeyeceğini varsayarım.


102
C ++ kullanarak iyi optimize edilmiş bir kod yazabileceğinizi belirten ++ C olarak adlandırılmış olsaydı harika olmaz mıydı ..
Naveen

9
Sonuçta ortaya çıkan değer açık bir şekilde çöpe atılacaksa, modern derleyiciler bunu optimize edemez mi?
che

6
@che - basit bir tür olduğunda yaparlar, ancak operatörün ++ 'ı (yineleyiciler gibi) aşırı yükleyen sınıflar farklı bir hikayedir.
Ferruccio

7
@che: Bu iyi bir soru. C ++ derleyicilerinin "CustomType ++;" "++ CustomType;" çünkü her iki kullanıcı tanımlı fonksiyonun da aynı etkiye sahip olduğuna dair bir garanti yoktur. Onlar ... ... ama hiçbir garantisi yok.
Drew Dormann

2
@ michael.bartnett: İyi bir nokta, C # 'da aşırı yükleme ++ mevcut gibi görünüyor. Öyle görünüyor ki, c ++ ile karşılaştırıldığında, c # 'da ön ve son sürümleri bağımsız olarak aşırı yükleyemezsiniz. Bu nedenle, C # 'da ++ çağrılmasının sonucu bir değişkene atanmamışsa veya karmaşık bir ifadenin parçası olarak kullanılmamışsa, derleyicinin ++ öncesi ve sonrası sürümlerini eşdeğer performans gösteren koda indirgeyeceğini varsayarım.
Scott Langham

83

C # 'da bir for döngüsünde kullanıldığında fark yoktur .

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

ile aynı şeyi çıktılar

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

Diğerlerinin belirttiği gibi, genel olarak i ++ ve ++ kullanıldığında ince ama önemli bir fark var:

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

i ++, i'nin değerini okur ve sonra artırır.

++ i i değerini artırır sonra okur.


Sonuç: C ++ ile aynı post / pre artış öncesi anlambilim.
xtofl

@xtofl - amacınızın ne olduğundan emin değil misiniz? Ben sadece benim örnek için c # almak oldu.
Jon B

3
İlk noktanın alakalı olduğunu düşünmüyorum. For döngüsünde (c # veya değil) artış kısmı her zaman döngü gövdesinden sonra yürütülür. Yürütüldükten sonra değişken, gönderi veya ön artış kullanılıp kullanılmadığı değiştirilir.
MatthieuP

9
@MatthieuP - "for döngüsünde i ++ veya ++ i kullanmanızın önemi var mı?" Sorusunu okudum. Cevap "hayır, değil".
Jon B

1
@JonB Yanıttaki işlem sırası tam olarak doğru değil. Hem ++ive i++aynı sırada aynı işlemleri gerçekleştirin: Geçici kopya ait oluşturmak i; yeni bir değer üretmek için sıcaklık değerini arttırın (sıcaklığı geçersiz kılmamak için); yeni değeri i; şimdi ++isonuç döndürülürse yeni değer; o ise i++iade sonuç geçici kopyasıdır. Burada daha ayrıntılı cevap: stackoverflow.com/a/3346729/3330348
PiotrWolkowski

51

Soru:

Bir for döngüsünde ++ i ve i ++ 'da bir fark var mı?

Cevap: Hayır .

Neden her soru cevaplanmasa bile, ön ve son artışlarla ilgili ayrıntılı açıklamalara gitmek zorunda kalıyor?

Bu döngü için:

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

Döngüler kullanmadan bu koda çevirirsiniz:

int i = 0; // Initialization

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

   i++ or ++i; // Increment

   goto loopStart;
}

Şimdi buraya koymanız i++veya ++iartırmanız önemli mi? Hayır , arttırma işleminin dönüş değeri önemsiz olduğu için değildir. ikodun for döngüsü gövdesi içindeki yürütme SONRASI artırılacaktır.


2
Bu tam anlamıyla noktaya gelen ilk cevaptır. Teşekkürler.
Yassir

1
Bu en iyi yanıt değildir, çünkü for döngüsü karmaşık bir nesneyi arttırıyorsa (int dışında bir şey!) ++ x uygulaması x ++ 'dan daha hızlı olabilir ... (bkz. Otlarutter.com/2013/05/13/gotw -2-çözüm-geçici nesneler )
JCx

30

Bir döngüdeki farkı sorduğunuz için, sanırım demek istediniz

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

Bu durumda, çoğu dilde fark vardır: döngü olursa olsun yazdığınız bakılmaksızın aynı şekilde davranır i++ve ++i. C ++ ile, ++ işleçlerinin kendi sürümlerini yazabilir ve ikullanıcı tanımlı türdeyse (örneğin kendi sınıfınız) onlar için ayrı anlamlar tanımlayabilirsiniz .

Yukarıda önemli olmasının nedeni, değerini kullanmamanızdır i++. Başka bir şey,

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

Şimdi, bir diğerleri, işaret ettiği gibi, çünkü bir fark, i++aracı artırmak, ancak önceki değerine değerlendirmek , ama ++iaracı artış, ancak değerlendirmeki (böylece yeni değere değerlendirmek olacaktır). Yukarıdaki durumda, ai artırılırken i'nin önceki değeri atanır.


3
C ++ 'da, derleyicinin geçici yapmaktan kaçınması her zaman mümkün değildir, bu nedenle artış öncesi formu tercih edilir.
David Thornley

yazdığım gibi, eğer kullanıcı tanımlı tipte bir i varsa, farklı semantik olabilir. ancak ilkel tipte bir i kullanırsanız, ilk döngü için bir fark oluşturmaz. Bu bir dil agnostik soru olduğundan, C ++ belirli şeyler hakkında çok fazla yazmak değil düşündüm.
Johannes Schaub - litb

15

Bu kodun gösterdiği gibi (yorumlarda kaldırılmış MSIL'e bakın), C # 3 derleyicisi bir for döngüsünde i ++ ve ++ i arasında bir ayrım yapmaz. İ ++ veya ++ i değeri alınıyor olsaydı, kesinlikle bir fark olurdu (bu Visutal Studio 2008 / Release Build'da derlendi):

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

Bir (++ i) ön bölge, bir (i ++) ön bölge. Fark, ifadeden hemen döndürülen değerdir.

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

Düzenleme: Woops, şeylerin döngü tarafını tamamen görmezden geldi. 'Adım' kısmı ((...; ...;)) olduğunda döngüler için gerçek bir fark yoktur, ancak diğer durumlarda devreye girebilir.


7

Döngüdeki artıştan sonra değeri kullanmıyorsanız fark yoktur.

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

Her iki döngü de 0123 yazdıracaktır.

Ancak fark, döngünüzdeki artış / azalmadan sonraki değeri aşağıdaki gibi kullandığınızda ortaya çıkar:

Artış Öncesi Döngü:

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

Çıktı: 0 0 1 1 2 2 3 3

Artış Sonrası Döngü:

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

Çıktı: 0 0 1 0 2 1 3 2

Umarım çıktıyı karşılaştırarak fark açıktır. Burada dikkat edilmesi gereken nokta, artışın / azalmanın her zaman for döngüsünün sonunda gerçekleştirilmesidir ve bu nedenle sonuçlar açıklanabilir.


7

İşte bir Java Örneği ve Byte Kodu, post ve preIncrement Bytecode'da fark göstermiyor:

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;
        }
    }
}

Ve şimdi bayt kodu için (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

Evet var. Fark, dönüş değerindedir. "++ i" nin dönüş değeri, i'nin artırılmasından sonraki değer olacaktır . Dönüşü "i ++" değeri olacaktır önce artan. Bu, aşağıdaki gibi görünen kod anlamına gelir:

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.

Bu nedenle, a 2, b ve c'nin her biri 1 olacaktır.

Ben böyle kodu yeniden yazabilirsiniz:

int a = 0; 

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

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

4

Her iki durumda da gerçek bir fark yoktur ' i' 1 ile artırılacaktır.

Ancak bir ifadede kullandığınızda bir fark vardır, örneğin:

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

Döngülerden ve performans farklılıklarından daha fazla ++ i ve i ++ vardır. ++ i bir l değeri döndürür ve i ++ bir r değeri döndürür. Buna dayanarak, (++ i) için yapabileceğiniz, ancak (i ​​++) için yapabileceğiniz pek çok şey vardır.

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

Neden aklımı boğdur ki insanlar for-loop'ta artış ifadesini i ++ olarak yazabilir?

For-loop'ta, 3. bileşen basit bir artış ifadesi olduğunda,

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

veya

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

sonuçta gerçekleşen infazlarda bir fark yoktur.


Bu bir cevap mı, yoksa bir soru mu?
Palec

2
Farketmediği için neden birisinin i ++ yazıp yazmadığını aklınızdan çıkarmayın? Birinin ++ i yazmayı tercih etmesinin bir nedeni var mı?
Dronz

2

As @Jon B diyor, döngü için hiçbir fark yoktur.

Ancak bir whileveya do...whiledöngüsünde, ++iveya ile karşılaştırma yapıyorsanız bazı farklılıklar bulabilirsiniz.i++

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

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

iki aşağı oy? Yazdıklarımın nesi yanlış? Ve soru ile ilgilidir (olduğu kadar belirsiz).
crashmstr

2

Aşağıdaki i ++ nedeniyle javascript kullanmak daha iyi olabilir:

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.

Diziler (sanırım hepsi) ve diğer bazı işlevler ve çağrılar başlangıç ​​noktası olarak 0'ı kullanırken, döngüyü ++ i kullanırken dizi ile çalışmasını sağlamak için i'yi -1 olarak ayarlamanız gerekir .

İ ++ kullanırken aşağıdaki değer, artırılmış değeri kullanır. İ ++ diyebilirsin , insanlar sayılır, çünkü 0 ile başlayabilirsin .


2

FOR döngüsünün ne yaptığını anlamak için

resim açıklamasını buraya girin

Bu gösterileri Yukarıdaki görüntü İÇİN dönüştürülebilir WHILE'den en sonunda tamamen (en azından gcc'deki) aynı montaj kodu var gibi. Biz aşağı kırabilir Yani İÇİN parçalar bir çift içine, ne yaptığını undertand.

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

WHILE sürümüne eşittir

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
}

Size kullanabileceğiniz anlamına gelir FOR basit bir versiyonu olarak WHILE'den :

  1. FOR (int i) 'nin ilk argümanı dışarıda döngüden önce yürütülür.

  2. FOR (i ++ veya ++ i) öğesinin üçüncü argümanı , içeride, döngünün son satırında yürütülür .

TP: DR: olursa olsun ister i++ya++i , biz onlar bağımsız olduklarında kendileri üzerinde hiçbir fark ama +1 yapmak biliyoruz.

Okulda, genellikle i ++ yolunu öğretmek, ama bir sürü insan dolayı orada da ++ i yolu tercih ettiklerini göstermektedir çeşitli nedenlerden .

NOT: Geçmişte, i ++ 'ın performans üzerinde çok az etkisi vardır, çünkü yalnızca tek başına artı değil, aynı zamanda orijinal değeri kayıt defterinde tutar. Ancak şimdilik, derleyici artı bir parçayı aynı kıldığından hiçbir fark yaratmıyor.


1

Döngüler için bir fark olabilir. Bu, post / artımın pratik uygulamasıdır.

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

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

İlki 11'e ve 11 kez döngüye girerken, ikincisi sayılmaz.

Çoğunlukla bu basit bir süre kullanılır (x--> 0); - - Örneğin, bir dizinin tüm öğelerini yinelemek için döngü yapın (burada foreach-build'ler hariç).


1

Her ikisi de sayıyı arttırır. ++ieşittir i = i + 1.

i++ve ++içok benzer ancak tam olarak aynı değil. Her ikisi de sayıyı artırır, ancak ++igeçerli ifade değerlendirilmeden önce sayıyı i++artırır, ifade ifade edildikten sonraki sayıyı artırır.

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

Bu bağlantıyı kontrol edin .


0

Evet, olağandışı kullanım durumlarında olsa da, bir döngü içinde ++ive i++bir fordöngü arasında bir fark vardır ; for bloğunda veya döngü testi ifadesinde artış / azalma operatörüne sahip bir döngü değişkeni veya döngü değişkenlerinden biri ile kullanıldığında . Hayır, sadece bir sözdizimi işi değildir.

iBir kodda olduğu gibi ifadeyi değerlendirmek anlamına gelir ive operatör bir değerlendirme değil, sadece bir işlem anlamına gelir;

  • ++ideğeri i1 artar ve daha sonra değerlendirir i,
  • i++" 1" ideğerini değerlendirmek ve daha sonra değerini artırmak anlamına gelir i.

Dolayısıyla, her iki ifadeden elde edilenler farklılık gösterir, çünkü değerlendirilenler her birinde farklılık gösterir. Aynı Hepsi --ivei--

Örneğin;

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

Olağandışı kullanım durumlarında, ancak bir sonraki örnek yararlı görünüyor veya önemli değil, bir fark gösteriyor

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)
}

Bu mevcut cevaplara ne katar?
GManNickG

sorduğum sorulara okuduğum cevaplardan daha doğrudan cevap veriyor.
Selçuk

-2

İçin i'kullanıcı tanımlı türleri s, bu operatörler (could ama olmamalı ) bir döngü indeksi bağlamında anlamlı farklar sematics sahiptir ve bu (ancak olmamalıdır) döngü davranışı tarif etkileyebilir.

Ayrıca, daha kolay bir şekilde optimize edilebildiğinden, c++artım öncesi formu ( ++i) kullanmak genellikle en güvenlidir. (Scott Langham beni bu çöplükte dövdü . Lanet olsun, Scott)


Postfix'in anlambiliminin önekten daha büyük olması gerekiyordu . -1
xtofl

-2

Ben diğer diller için bilmiyorum ama Java ++ i bir olduğunu önek artım hangi araçlar: artırmak i 1 ile ve daha sonra hangi ifadesinde i yeni bir değer kullanmak i bulunduğu ve ben ++ bir olan sonek artışı şu demektir : ifadede i'nin geçerli değerini kullanın ve ardından 1 ile artırın. Örnek:

public static void main(String [] args){

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

} ve çıktı:

  • 4
  • 5
  • 6

-3

i ++; ++ i; her ikisi de bir ifadede kullanılmadıkları için benzerdir.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.