लूप में प्री-इन्क्रीमेंट और पोस्ट-इन्क्रीमेंट के बीच अंतर?


303

वहाँ में एक फर्क है ++iऔर i++एक में forपाश? क्या यह केवल एक वाक्य रचना है?



18
मुझे आश्चर्य है कि कितने उत्तर पूरी तरह से प्रश्न के बिंदु से चूक गए।
ग्रीम पेरो

3
शायद हमें आश्चर्यचकित होना चाहिए कि किसी ने भी प्रश्न को अधिक स्पष्ट होने के लिए संपादित नहीं किया :)
जॉन बी

2
: यह सवाल सी, जावा, सी ++, पीएचपी, सी #, जावास्क्रिप्ट, JScript, उद्देश्य सी के लिए आवेदन कर सकता है en.wikipedia.org/wiki/Category:C_programming_language_family
क्रिस एस

1
अच्छा जवाब यहां पोस्ट किया गया: stackoverflow.com/a/4706225/214296
जिम फेल

जवाबों:


233

एक ++ को पोस्टफिक्स के रूप में जाना जाता है।

1 को जोड़ें, पुराना मान लौटाता है।

++ a को उपसर्ग के रूप में जाना जाता है।

1 को जोड़ें, नया मान लौटाता है।

सी#:

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

आउटपुट:

1
2
3
4

0
1
2
3

foreachऔर whileलूप इस बात पर निर्भर करते हैं कि आप किस इंक्रीमेंट प्रकार का उपयोग करते हैं। नीचे के छोरों की तरह इसमें कोई अंतर नहीं है क्योंकि आप 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 0 2 2 4 4

यदि मूल्यांकन किए गए मान का उपयोग किया जाता है तो वेतन वृद्धि का प्रकार महत्वपूर्ण हो जाता है:

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

4
यह वह भी नहीं है जो उपयोगकर्ता ने मांगा था।
दिमित्री

223

पूर्व वेतन वृद्धि ++ मैं i के मूल्य में वृद्धि करता है और नए वेतन वृद्धि मूल्य का मूल्यांकन करता है।

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

पोस्ट-इन्क्रीमेंट i ++ i के मूल्य में वृद्धि करता है और मूल गैर-संवर्धित मूल्य का मूल्यांकन करता है।

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

C ++ में, पूर्व-वेतन वृद्धि आमतौर पर पसंद की जाती है जहां आप या तो उपयोग कर सकते हैं।

ऐसा इसलिए है क्योंकि यदि आप पोस्ट-इन्क्रीमेंट का उपयोग करते हैं, तो उसे कोड उत्पन्न करने के लिए कंपाइलर की आवश्यकता हो सकती है जो एक अतिरिक्त अस्थायी चर बनाता है। इसका कारण यह है कि परिवर्ती होने के पिछले और नए दोनों मूल्यों को कहीं न कहीं रखा जाना चाहिए क्योंकि मूल्यांकन किए जा रहे अभिव्यक्ति में उन्हें कहीं और की आवश्यकता हो सकती है।

इसलिए, C ++ में, कम से कम, एक प्रदर्शन अंतर हो सकता है जो आपकी पसंद का मार्गदर्शन करता है कि किसका उपयोग करना है।

यह मुख्य रूप से केवल एक समस्या है जब परिवर्तन किया जा रहा चर एक उपयोगकर्ता परिभाषित प्रकार है जो ओवरराइड ++ ऑपरेटर के साथ होता है। आदिम प्रकारों (int, आदि) के लिए कोई प्रदर्शन अंतर नहीं है। लेकिन, जब तक पोस्ट-इन्क्रीमेंट ऑपरेटर की आवश्यकता नहीं है, तब तक यह दिशानिर्देश के रूप में पूर्व-वेतन वृद्धि ऑपरेटर से चिपके रहने के लायक है।

यहाँ कुछ और चर्चा है:
https://web.archive.org/web/20170405054235/http://en.allexperts.com/q/C-1040/Increment-operators.htm

C ++ में यदि आप STL का उपयोग कर रहे हैं, तो आप पुनरावृत्तियों के साथ उपयोग कर सकते हैं। ये मुख्य रूप से ++ ऑपरेटरों को ओवरराइड करते हैं, इसलिए प्री-इंक्रीमेंट से चिपके रहना एक अच्छा विचार है। हालांकि कंपाइलर हर समय होशियार हो जाते हैं, और नए लोग अनुकूलन का प्रदर्शन करने में सक्षम हो सकते हैं, जिसका अर्थ है कि कोई प्रदर्शन अंतर नहीं है - खासकर यदि टाइप किए जा रहे प्रकार को हेडर फ़ाइल में इनलाइन के रूप में परिभाषित किया गया है (जैसा कि एसटीएल कार्यान्वयन अक्सर होता है) ताकि कंपाइलर देख सकें विधि कार्यान्वित की जाती है और तब पता चल सकता है कि प्रदर्शन करने के लिए कौन से अनुकूलन सुरक्षित हैं। फिर भी, यह शायद अभी भी पूर्व-वेतन वृद्धि से चिपके रहने के लायक है क्योंकि लूप को कई बार निष्पादित किया जाता है और इसका मतलब है कि एक छोटा प्रदर्शन जुर्माना जल्द ही प्रवर्धित हो सकता है।


अन्य भाषाओं में जैसे कि C # जहां ++ ऑपरेटर को ओवरलोड नहीं किया जा सकता है, कोई प्रदर्शन अंतर नहीं है। लूप चर को आगे बढ़ाने के लिए एक लूप में उपयोग किया जाता है, पूर्व और बाद के वेतन वृद्धि ऑपरेटर बराबर हैं।

सुधार: C # में ओवरलोडिंग की अनुमति है। हालांकि ऐसा लगता है, कि C ++ की तुलना में, c # में आप पूर्व और बाद के संस्करणों को स्वतंत्र रूप से अधिभारित नहीं कर सकते हैं। इसलिए, मुझे लगता है कि अगर C # में कॉलिंग का परिणाम एक चर को नहीं सौंपा गया है या एक जटिल अभिव्यक्ति के हिस्से के रूप में उपयोग किया जाता है, तो संकलक ++ के पूर्व और बाद के संस्करणों को कम कर देगा जो कोड के बराबर होता है।


102
क्या यह बहुत अच्छा नहीं होता अगर C ++ का नाम ++ C होता। यह दर्शाता है कि आप इसका उपयोग करके एक अच्छा अनुकूलित कोड लिख सकते हैं ..
नवीन

9
क्या आधुनिक संकलक इसे अनुकूलित करने में सक्षम नहीं होना चाहिए जब परिणामी मूल्य स्पष्ट रूप से वैसे भी ट्रैश किए जा रहे हों?
चे

6
@che - वे तब करते हैं जब यह एक सरल प्रकार होता है, हालांकि कक्षाएं जो अधिभार ऑपरेटर ++ (जैसे कि पुनरावृत्त) एक अलग कहानी हैं।
फेरेकियो

7
@che: यह एक अच्छा सवाल है। कारण है कि C ++ कंपाइलर "CustomType ++;" "++ कस्टम टाइप?" ऐसा इसलिए है क्योंकि कोई भी गारंटी नहीं है कि दोनों उपयोगकर्ता-परिभाषित कार्यों का एक ही प्रभाव है। वे चाहिए ... लेकिन इसकी कोई गारंटी नहीं है।
ड्रू डॉर्मन

2
@ michael.bartnett: अच्छा बिंदु, C # में ओवरलोडिंग उपलब्ध होना प्रतीत होता है। हालाँकि ऐसा लगता है, कि c ++ की तुलना में, c # में आप पूर्व और बाद के संस्करणों को स्वतंत्र रूप से अधिभारित नहीं कर सकते हैं। इसलिए, मुझे लगता है कि अगर C # में कॉलिंग का परिणाम एक चर को नहीं सौंपा गया है या एक जटिल अभिव्यक्ति के हिस्से के रूप में उपयोग किया जाता है, तो संकलक ++ के पूर्व और बाद के संस्करणों को कम कर देगा जो कोड के बराबर होता है।
स्कॉट लैंगहम

83

C # में लूप के लिए उपयोग किए जाने पर कोई अंतर नहीं है ।

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

के रूप में एक ही बात का उत्पादन

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

जैसा कि दूसरों ने बताया है, जब सामान्य i ++ और ++ में उपयोग किया जाता है, तो सूक्ष्म रूप से महत्वपूर्ण अंतर होता है:

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

i ++ मैं i का मान पढ़ता है, फिर इसे बढ़ाता है।

++ मैं i का मान बढ़ाता हूं, फिर इसे पढ़ता हूं।


समापन: C ++ की तरह ही पोस्ट / प्री इंक्रीमेंट शब्दार्थ।
xtofl

@xtofl - निश्चित नहीं है कि आपकी बात क्या है? मैं सिर्फ अपने उदाहरण के लिए c # लेने के लिए हुआ था।
जॉन बी

3
मुझे नहीं लगता कि पहला बिंदु प्रासंगिक है। लूप के लिए (c # या नहीं) लूप के शरीर के बाद वेतन वृद्धि वाला भाग हमेशा निष्पादित होता है। एक बार निष्पादित होने के बाद, चर को संशोधित किया जाता है कि क्या पोस्ट या पूर्व वेतन वृद्धि का उपयोग किया गया था।
MatthieuP

9
@ मैथ्यूएईपीपी - मैंने सवाल पढ़ा "क्या यह मायने रखता है कि क्या आप एक लूप में i ++ या ++ i का उपयोग करते हैं"। जवाब "नहीं यह नहीं है"।
जॉन बी २

1
@JonB उत्तर में संचालन का क्रम बिल्कुल सही नहीं है। दोनों ++iऔर i++एक ही क्रम में वही कार्यवाही: की अस्थायी प्रतिलिपि बनाने के i; नया मान उत्पन्न करने के लिए अस्थायी मान बढ़ाएँ (अस्थायी को ओवरराइड न करें); में नए मूल्य की दुकान i; अब अगर यह ++iपरिणाम वापस आ गया है तो नया मूल्य है; यदि यह i++परिणाम लौटा है तो अस्थायी प्रतिलिपि है। यहां अधिक विस्तृत जवाब: stackoverflow.com/a/3346729/3330348
PiotrWolkowski

51

प्रश्न है:

क्या लूप के लिए ++ आई और आई ++ में अंतर है?

जवाब है: नहीं

जब यह भी नहीं पूछा जाता है, तो प्रत्येक और प्रत्येक उत्तर को पूर्व और बाद के वेतन वृद्धि के बारे में विस्तृत स्पष्टीकरण में क्यों जाना पड़ता है?

यह लूप के लिए:

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

लूप का उपयोग किए बिना इस कोड में अनुवाद करेंगे:

int i = 0; // Initialization

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

   i++ or ++i; // Increment

   goto loopStart;
}

अब इससे कोई फ़र्क पड़ता है कि आप यहाँ वेतन वृद्धि करते हैं i++या नहीं ++i? नहीं, यह नहीं है क्योंकि वेतन वृद्धि का रिटर्न वैल्यू महत्वहीन है। iको बढ़ाया जाएगा कोड के निष्पादन के बाद जो लूप बॉडी के अंदर है।


2
यह वस्तुतः पहला उत्तर है जो सही बिंदु पर जाता है। धन्यवाद।
यासिर

1
यह सबसे अच्छा जवाब नहीं है क्योंकि अगर लूप के लिए एक जटिल वस्तु (एक इंट के अलावा कुछ और) बढ़ रही है तो ++ x का कार्यान्वयन x ++ की तुलना में तेज हो सकता है ... ( जड़ी बूटी देखें.कॉम 2013/05/13/gotw -2-समाधान-अस्थायी-वस्तुएं )
JCx

30

चूंकि आप एक लूप में अंतर के बारे में पूछते हैं, इसलिए मुझे लगता है कि आपका मतलब है

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

उस मामले में, आपको अधिकांश भाषाओं में कोई अंतर नहीं है: लूप समान व्यवहार करता है चाहे आप लिखें i++और ++i। C ++ में, आप ++ ऑपरेटरों के अपने स्वयं के संस्करण लिख सकते हैं, और यदि आप उनके लिए अलग-अलग अर्थों को परिभाषित कर सकते हैं, तोi उपयोगकर्ता परिभाषित प्रकार (आपकी खुद की कक्षा, उदाहरण के लिए) का है।

उपरोक्त कारण से कोई फर्क नहीं पड़ता क्योंकि आप के मूल्य का उपयोग नहीं करते हैं i++। एक और बात है जब आप करते हैं

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

अब, वहाँ है एक अंतर है, क्योंकि के रूप में दूसरों, का कहना है i++साधन बढ़ाने के लिए, लेकिन पिछले मान का मूल्यांकन है, लेकिन ++iइसका मतलब है वेतन वृद्धि, लेकिन करने के लिए मूल्यांकनi (इस प्रकार यह नया मान का मूल्यांकन होगा)। उपरोक्त मामले में, aमुझे पहले का मान दिया गया है, जबकि मुझे वेतन वृद्धि मिली है।


3
सी ++ में, हमेशा संकलक के लिए अस्थायी बनाने से बचने के लिए संभव नहीं होता है, इसलिए प्री-इंक्रीमेंट फॉर्म को प्राथमिकता दी जाती है।
डेविड थॉर्नले

जैसा कि मैं लिखता हूं, यदि आपके पास उपयोगकर्ता परिभाषित प्रकार का एक i है, तो उनके पास अलग-अलग शब्दार्थ हो सकते हैं। लेकिन यदि आप एक आदिम प्रकार का उपयोग करते हैं, तो यह पहले लूप के लिए कोई फर्क नहीं पड़ता है। जैसा कि यह एक भाषा अज्ञेय प्रश्न है, मुझे लगा कि C ++ के विशिष्ट सामान के बारे में बहुत अधिक नहीं लिखना चाहिए।
जोहान्स शहाब -

15

जैसा कि इस कोड से पता चलता है (टिप्पणियों में असंतुष्ट MSIL देखें), C # 3 संकलक एक लूप के लिए i ++ और ++ i के बीच कोई अंतर नहीं करता है। यदि i ++ या ++ i का मान लिया जा रहा है, तो निश्चित रूप से अंतर होगा (यह Visutal Studio 2008 / रिलीज़ बिल्ड में संकलित किया गया था):

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

एक (++ i) प्रीइंकेमिनेशन है, एक (i ++) पोस्टइनक्रीमेंट है। अंतर यह है कि किस मूल्य को तुरंत अभिव्यक्ति से वापस कर दिया जाता है।

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

संपादित करें: वाह, पूरी तरह से चीजों के पाश पक्ष को नजरअंदाज कर दिया। छोरों के लिए कोई वास्तविक अंतर नहीं है जब यह 'स्टेप' भाग ((...; ...;)) के लिए है, लेकिन यह अन्य मामलों में चलन में आ सकता है।


7

यदि आप लूप में वृद्धि के बाद मूल्य का उपयोग नहीं कर रहे हैं तो कोई अंतर नहीं है।

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

दोनों लूप 0123 प्रिंट करेंगे।

लेकिन अंतर तब आता है जब आप अपने लूप में वेतन वृद्धि / कमी के बाद मूल्य का उपयोग करते हैं:

पूर्व वृद्धि लूप:

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

आउटपुट: 0 0 1 1 2 2 3 3

पोस्ट वृद्धि लूप:

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

आउटपुट: 0 0 1 0 2 1 3 3 2

मुझे उम्मीद है कि आउटपुट की तुलना करने से अंतर स्पष्ट है। यहां ध्यान देने वाली बात यह है कि वेतन वृद्धि / क्षरण हमेशा लूप के अंत में किया जाता है और इसलिए परिणामों को समझाया जा सकता है।


7

यहां एक जावा-सैंपल और बाइट-कोड, पोस्ट- और प्री-इन्क्रिमेंट बाइटकोड में कोई अंतर नहीं दिखाया गया है:

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

और अब बाइट-कोड के लिए (javap -pStreet -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

हाँ वहाँ है। अंतर रिटर्न वैल्यू में है। "++ i" का वापसी मूल्य irementing i के बाद का मान होगा । "I ++" की वापसी वेतन वृद्धि से पहले होगी । इसका मतलब है कि कोड जो निम्न की तरह दिखता है:

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.

इसलिए, ए 2 होगा, और बी और सी प्रत्येक 1 होगा।

मैं इस तरह कोड को फिर से लिख सकता हूं:

int a = 0; 

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

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

4

दोनों मामलों में कोई वास्तविक अंतर नहीं है ' i' 1 से बढ़ेगा।

लेकिन एक अंतर है जब आप इसे एक अभिव्यक्ति में उपयोग करते हैं, उदाहरण के लिए:

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

लूप और प्रदर्शन अंतर की तुलना में ++ i और i ++ से अधिक है। ++ मैं एक L- मान लौटाता है और i ++ एक r-value देता है। इसके आधार पर, कई चीजें हैं जो आप (++ 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

यह मेरे दिमाग को चकरा देता है कि क्यों लोग i- लूप में वृद्धि की अभिव्यक्ति i ++ के रूप में लिख सकते हैं।

फॉर-लूप में, जब तीसरा घटक एक साधारण वेतन वृद्धि कथन है, जैसा कि

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

या

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

परिणामी निष्पादनों में कोई अंतर नहीं है।


यह एक जवाब है, या यह एक सवाल है?
पालेक

2
चूंकि यह कोई फर्क नहीं पड़ता, इसलिए यह आपके दिमाग को चकरा देगा कि क्या किसी ने i ++ लिखा है? क्या कोई कारण है कि कोई व्यक्ति ++ i लिखना पसंद करेगा?
द्रोणज

2

जैसा कि @ जोंन बी कहते हैं, लूप में कोई अंतर नहीं है।

लेकिन whileया do...whileलूप में, आप कुछ अंतर पा सकते हैं यदि आप के साथ तुलना कर रहे हैं ++iयाi++

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

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

दो डाउनवोट? मैंने जो लिखा है, उसमें गलत क्या है? और यह प्रश्न से संबंधित है (जैसा कि अस्पष्ट है)।
क्रैश

2

निम्नलिखित i ++ के कारण जावास्क्रिप्ट में इसका उपयोग करना बेहतर हो सकता है:

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.

सरणियों (मैं सब लगता है) और कुछ अन्य कार्य करता है और कॉल एक प्रारंभिक बिंदु के रूप में 0 का उपयोग करते हैं आप मैं करने के लिए -1 सेट करने के लिए सरणी के साथ पाश काम करने के लिए उपयोग करते समय होता ++ मैं

I ++ का उपयोग करते समय निम्नलिखित मूल्य बढ़े हुए मूल्य का उपयोग करेगा। आप कह सकते हैं कि मैं ++ इंसानों की गिनती का तरीका है, क्योंकि आप 0 से शुरू कर सकते हैं ।


2

यह समझने के लिए क्या एक के लिए पाश करता है

यहां छवि विवरण दर्ज करें

ऊपर दी गई छवि से पता चलता है कि फॉर को परिवर्तित किया जा सकता है WHILE में , क्योंकि उनके पास अंततः एक ही असेंबली कोड (कम से कम gcc) में है। इसलिए हम बंद कर सकता है के लिए टुकड़े के एक जोड़े में, undertand करने के लिए यह क्या करता है।

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

के बराबर है 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
}

इसका मतलब है कि आप उपयोग कर सकते हैं के लिए का एक सरल संस्करण के रूप में जबकि :

  1. का पहला तर्क के लिए (int i) निष्पादित किया जाता है, बाहर, पाश से पहले।

  2. का तीसरा तर्क FOR (i ++ या ++ i) के , लूप की अंतिम पंक्ति में, अंदर, निष्पादित किया जाता है।

TL: DR: कोई फर्क नहीं पड़ता कि i++या++i , हम जानते हैं कि जब वे स्टैंडअलोन होते हैं, तो उन्हें कोई फर्क नहीं पड़ता है लेकिन खुद पर +1।

स्कूल में, वे आमतौर पर i ++ तरीका सिखाते हैं, लेकिन बहुत से लोग ++ i रास्ता पसंद करते हैं कई कारणों

नोट: अतीत में, i ++ के प्रदर्शन पर बहुत कम प्रभाव पड़ता है, क्योंकि यह न केवल स्वयं एक से अधिक होता है, बल्कि रजिस्टर में मूल मूल्य भी रखता है। लेकिन अब के लिए, यह कोई फर्क नहीं पड़ता क्योंकि कंपाइलर प्लस एक हिस्से को समान बनाता है।


1

छोरों के लिए एक अंतर हो सकता है। यह पोस्ट / प्री-इन्क्रीमेंट का व्यावहारिक अनुप्रयोग है।

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

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

जबकि पहले वाले को 11 गिना जाता है और 11 बार छोरों को, दूसरा नहीं करता है।

अधिकतर यह एक साधारण समय में उपयोग किया जाता है (x--> 0); - - उदाहरण के लिए एक सरणी के सभी तत्वों के लिए लूप करें (यहाँ foreach-constructs को छूट देता है)।


1

वे दोनों संख्या बढ़ाते हैं। ++iके बराबर हैi = i + 1

i++और ++iबहुत समान हैं लेकिन बिल्कुल समान नहीं हैं। दोनों संख्या में वृद्धि करते हैं, लेकिन ++iवर्तमान अभिव्यक्ति का मूल्यांकन करने से पहले संख्या में वृद्धि करते हैं, जबकि i++अभिव्यक्ति के मूल्यांकन के बाद संख्या में वृद्धि होती है।

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

चेक इस लिंक


0

हां, एक लूप के बीच ++iऔर एक अंतर है , हालांकि असामान्य उपयोग के मामलों में; जब वेतन वृद्धि / कमी ऑपरेटर के साथ एक लूप वेरिएबल का उपयोग ब्लॉक या लूप टेस्ट एक्सप्रेशन के लिए , या लूप वैरिएबल्स में से एक के साथ किया जाता हैi++for । नहीं, यह केवल एक वाक्य रचना नहीं है।

जैसा कि iएक कोड में अभिव्यक्ति का मूल्यांकन होता है iऔर ऑपरेटर का मूल्यांकन नहीं होता है, बल्कि सिर्फ एक ऑपरेशन होता है;

  • ++ii1 से वृद्धि मूल्य और बाद में मूल्यांकन का मतलब हैi ,
  • i++1 से मूल्यांकन iऔर बाद में वेतन वृद्धि का मतलब है i

इसलिए, प्रत्येक दो अभिव्यक्तियों से जो प्राप्त होता है वह भिन्न होता है क्योंकि मूल्यांकन किया गया प्रत्येक में भिन्न होता है। सभी के लिए समान--i औरi--

उदाहरण के लिए;

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

असामान्य उपयोग के मामलों में, हालांकि अगला उदाहरण उपयोगी लगता है या कोई फर्क नहीं पड़ता, यह एक अंतर दिखाता है

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

यह मौजूदा उत्तरों पर क्या जोड़ता है?
GManNickG

यह मेरे द्वारा पढ़े गए उत्तरों की तुलना में अधिक सीधे उत्तर देता है।
सेल्कुक

-2

के लिए i'उपयोगकर्ता-निर्धारित प्रकार के है, इन ऑपरेटरों सकता है (लेकिन नहीं करना चाहिए ) एक पाश सूचकांक के संदर्भ में सार्थक रूप से विभिन्न sematics है, और यह (लेकिन नहीं होना चाहिए) को प्रभावित कर सकता पाश के व्यवहार का वर्णन किया।

इसके अलावा, c++इसमें आम तौर पर प्री-इंक्रीमेंट फॉर्म ( ++i) का उपयोग करना सबसे सुरक्षित होता है क्योंकि यह अधिक आसानी से अनुकूलित होता है। (स्कॉट लैंगहम ने मुझे इस tidbit पर हराया । आपको अभिशाप है, स्कॉट)


पोस्टफ़िक्स के शब्दों रहे हैं चाहिए उपसर्ग से भी बड़ा हो सकता है। -1
xtofl

-2

मैं अन्य भाषाओं के लिए नहीं जानता, लेकिन जावा ++ में मैं एक उपसर्ग वृद्धि है, जिसका अर्थ है: मैं 1 से बढ़ाता हूं और फिर मैं जिस भाव में रहता हूं , उसमें i के नए मूल्य का उपयोग करता हूं , और i ++ एक उपसर्ग वृद्धि है जिसका अर्थ है निम्नलिखित : अभिव्यक्ति में i के वर्तमान मूल्य का उपयोग करें और फिर इसे 1 से बढ़ाएं। उदाहरण:

public static void main(String [] args){

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

} और आउटपुट है:

  • 4
  • 5
  • 6

-3

मैं ++; ++ मैं; दोनों समान हैं क्योंकि वे एक अभिव्यक्ति में उपयोग नहीं किए जाते हैं।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.