सी में, उपयोग करने में क्या अंतर है ++i
और i++
, और जिसका उपयोग for
लूप की वृद्धि के ब्लॉक में किया जाना चाहिए ?
सी में, उपयोग करने में क्या अंतर है ++i
और i++
, और जिसका उपयोग for
लूप की वृद्धि के ब्लॉक में किया जाना चाहिए ?
जवाबों:
++i
का मान बढ़ाएगा i
, और उसके बाद बढ़े हुए मान को लौटाएगा।
i = 1;
j = ++i;
(i is 2, j is 2)
i++
के मूल्य में वृद्धि होगी i
, लेकिन मूल मूल्य को i
बढ़ाए जाने से पहले आयोजित किया जाएगा।
i = 1;
j = i++;
(i is 2, j is 1)
एक for
लूप के लिए, या तो काम करता है। ++i
अधिक सामान्य लगता है, शायद इसलिए कि K & R में इसका उपयोग किया जाता है ।
किसी भी मामले में, "पसंद करते हैं दिशानिर्देश का पालन ++i
से अधिक i++
" और आप गलत नहीं होगा।
की दक्षता के बारे में टिप्पणियों की एक जोड़ी है ++i
और i++
। किसी भी गैर-छात्र-परियोजना संकलक में, कोई प्रदर्शन अंतर नहीं होगा। आप इसे उत्पन्न कोड को देखकर सत्यापित कर सकते हैं, जो समान होगा।
दक्षता प्रश्न दिलचस्प है ... यहां एक उत्तर में मेरा प्रयास है: क्या सी में i ++ और ++ i के बीच एक प्रदर्शन अंतर है?
@OnFreund नोट्स के रूप में , यह C ++ ऑब्जेक्ट के लिए अलग है, क्योंकि operator++()
एक फ़ंक्शन है और संकलक मध्यवर्ती मान रखने के लिए एक अस्थायी ऑब्जेक्ट के निर्माण का अनुकूलन करने के लिए नहीं जान सकता है।
for(int i=0; i<10; i++){ print i; }
यह for(int i=0; i<10; ++i){ print i; }
मेरी समझ से अलग नहीं होगा, यह है कि कुछ भाषाएँ आपको अलग-अलग परिणाम देती हैं, जिनके आधार पर आप इसका उपयोग करते हैं।
i++
इसलिए मैं पसंद करता हूं क्योंकि यह "ऑपरेंड-ऑपरेटर" के रूप में है, एक ला एक असाइनमेंट "ऑपरेंड-ऑपरेटर-वैल्यू" है। दूसरे शब्दों में, लक्ष्य ऑपरेंड अभिव्यक्ति के बाईं ओर है, जैसे यह एक असाइनमेंट स्टेटमेंट में है।
i++
और print i
अलग बयानों में हैं, लेकिन क्योंकि i++;
और i<10
कर रहे हैं। @ जॉनीफ्लेश की टिप्पणी यह आधार नहीं है। मान लीजिए आपके पास for(int i=0; i++<10){ print i; }
और for(int i=0; ++i<10){ print i; }
। ये उस तरह से अलग तरीके से काम करेंगे जिस तरह @johnnyflash ने पहली टिप्पणी में वर्णित किया है।
i ++ को पोस्ट इंक्रीमेंट के रूप में जाना जाता है, जबकि ++ को प्री इंक्रीमेंट कहा जाता है ।
i++
i++
पोस्ट इन्क्रीमेंट है क्योंकि i
ऑपरेशन खत्म होने के बाद यह 1 से बढ़ जाता है।
निम्नलिखित उदाहरण देखें:
int i = 1, j;
j = i++;
यहाँ j = 1
लेकिन का मूल्य i = 2
। यहां मूल्य पहले i
सौंपा जाएगा j
फिर i
वेतन वृद्धि होगी।
++i
++i
पूर्व वेतन वृद्धि है क्योंकि यह i
ऑपरेशन से पहले 1 के मूल्य में वृद्धि करता है। इसका मतलब है के j = i;
बाद अमल करेंगे i++
।
निम्नलिखित उदाहरण देखें:
int i = 1, j;
j = ++i;
यहाँ j = 2
लेकिन का मूल्य i = 2
। यहां वेतन वृद्धि के बाद i
सौंपा जाएगा । इसी तरह से पहले निष्पादित किया जाएगा ।j
i
i
++i
j=i;
आपके प्रश्न के लिए जिसे लूप के इंक्रीमेंट ब्लॉक में उपयोग किया जाना चाहिए? जवाब है, आप किसी भी एक का उपयोग कर सकते हैं .. कोई फर्क नहीं पड़ता। यह आपके लूप के लिए निष्पादित करेगा नहीं। समय का।
for(i=0; i<5; i++)
printf("%d ",i);
तथा
for(i=0; i<5; ++i)
printf("%d ",i);
दोनों लूप एक ही आउटपुट का उत्पादन करेंगे। यानी 0 1 2 3 4
।
यह केवल वही मायने रखता है जहां आप इसका उपयोग कर रहे हैं।
for(i = 0; i<5;)
printf("%d ",++i);
इस मामले में आउटपुट होगा 1 2 3 4 5
।
कृपया "दक्षता" (गति, वास्तव में) के बारे में चिंता न करें, जिनमें से एक तेज है। हमारे पास इन दिनों ऐसे कंपाइलर हैं जो इन बातों का ध्यान रखते हैं। जो भी उपयोग करने के लिए समझ में आता है, जिसके आधार पर अधिक स्पष्ट रूप से आपके इरादे को दर्शाता है।
operator++(int)
(पोस्टफ़िक्स संस्करण) के भीतर कोड को बहुत अधिक अस्थायी बनाना पड़ता है जिसे वापस कर दिया जाएगा। क्या आप सुनिश्चित हैं कि कंपाइलर हमेशा इसे दूर कर सकते हैं?
++i
मूल्य बढ़ाता है, फिर उसे लौटाता है।
i++
मान लौटाता है, और फिर इसे बढ़ाता है।
यह एक सूक्ष्म अंतर है।
लूप के लिए, उपयोग करें ++i
, क्योंकि यह थोड़ा तेज़ है। i++
एक अतिरिक्त प्रतिलिपि बनाएगा जो बस फेंक दी जाती है।
i++
: इस परिदृश्य में पहले मान असाइन किया जाता है और उसके बाद वेतन वृद्धि होती है।
++i
: इस परिदृश्य में पहले वेतन वृद्धि की जाती है और फिर मान असाइन किया जाता है
नीचे इमेज विज़ुअलाइज़ेशन है और यहाँ एक अच्छा व्यवहारिक वीडियो भी है जो उसी को प्रदर्शित करता है।
इसका कारण थोड़ा तेज ++i
हो सकता i++
है, क्योंकि i++
इससे पहले कि मैं इसे बढ़ाता हूं, जबकि इसके मूल्य की स्थानीय प्रतिलिपि की आवश्यकता ++i
नहीं हो सकती है। कुछ मामलों में, कुछ कंपाइलर संभव होने पर इसे दूर कर देंगे ... लेकिन यह हमेशा संभव नहीं है, और सभी कंपाइलर ऐसा नहीं करते हैं।
मैं कंपाइलर ऑप्टिमाइज़ेशन पर बहुत अधिक भरोसा नहीं करने की कोशिश करता हूं, इसलिए मैं रयान फॉक्स की सलाह का पालन करूंगा: जब मैं दोनों का उपयोग कर सकता हूं, तो मैं उपयोग करता हूं ++i
।
i
जब आप कोई स्टेटमेंट लिखते हैं तो वैल्यू 1 से ज्यादा "लोकल कॉपी" नहीं होती है 1;
।
लूप में या तो उपयोग करने का प्रभावी परिणाम समान है। दूसरे शब्दों में, लूप दोनों उदाहरणों में एक ही सटीक काम करेगा।
दक्षता के संदर्भ में, i ++ over ++ i चुनने के साथ एक जुर्माना शामिल हो सकता है। भाषा की युक्ति के संदर्भ में, पोस्ट-इन्क्रीमेंट ऑपरेटर का उपयोग करके उस मान की एक अतिरिक्त प्रतिलिपि बनानी चाहिए, जिस पर ऑपरेटर कार्य कर रहा है। यह अतिरिक्त संचालन का एक स्रोत हो सकता है।
हालांकि, आपको पूर्ववर्ती तर्क के साथ दो मुख्य समस्याओं पर विचार करना चाहिए।
आधुनिक संकलक महान हैं। सभी अच्छे संकलक यह महसूस करने के लिए पर्याप्त स्मार्ट हैं कि यह फॉर-लूप में पूर्णांक वृद्धि देख रहा है, और यह दोनों विधियों को एक ही कुशल कोड के लिए अनुकूलित करेगा। यदि पूर्व-वेतन वृद्धि पर पोस्ट-इन्क्रीमेंट का उपयोग करना वास्तव में आपके प्रोग्राम को धीमी गति से चलने का समय देता है, तो आप एक भयानक संकलक का उपयोग कर रहे हैं ।
परिचालन समय-जटिलता के संदर्भ में, दो विधियां (भले ही एक प्रतिलिपि वास्तव में प्रदर्शन की जा रही हो) समतुल्य हैं। लूप के अंदर किए जाने वाले निर्देशों की संख्या में वृद्धि की कार्रवाई में संचालन की संख्या पर महत्वपूर्ण रूप से हावी होना चाहिए। इसलिए, महत्वपूर्ण आकार के किसी भी लूप में, वृद्धिशील विधि के दंड को लूप बॉडी के निष्पादन द्वारा बड़े पैमाने पर ओवरहैड किया जाएगा। दूसरे शब्दों में, आप वेतन वृद्धि के बजाय लूप में कोड के अनुकूलन के बारे में चिंता करना बेहतर समझते हैं।
मेरी राय में, पूरा मुद्दा बस एक शैली वरीयता के लिए उबलता है। यदि आपको लगता है कि पूर्व वेतन वृद्धि अधिक पठनीय है, तो इसका उपयोग करें। व्यक्तिगत रूप से, मैं पोस्ट-इन्क्रिमेंट को पसंद करता हूं, लेकिन यह शायद इसलिए है क्योंकि मुझे अनुकूलन के बारे में कुछ भी पता होने से पहले यह वही था जो मुझे सिखाया गया था।
यह समयपूर्व अनुकूलन का एक सर्वोत्कृष्ट उदाहरण है, और इस तरह के मुद्दों से हमें डिजाइन में गंभीर मुद्दों से ध्यान हटाने की क्षमता है। हालांकि, यह पूछना अभी भी एक अच्छा सवाल है, क्योंकि "सर्वोत्तम व्यवहार" में उपयोग या सहमति में कोई एकरूपता नहीं है।
वे दोनों संख्या बढ़ाते हैं। ++i
के बराबर है i = i + 1
।
i++
और ++i
बहुत समान हैं लेकिन बिल्कुल समान नहीं हैं। दोनों संख्या में वृद्धि करते हैं, लेकिन ++i
वर्तमान अभिव्यक्ति का मूल्यांकन करने से पहले संख्या में वृद्धि करते हैं, जबकिi++
अभिव्यक्ति के मूल्यांकन के बाद संख्या में वृद्धि होती है।
उदाहरण:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
++i
(उपसर्ग आपरेशन): प्राप्तियां और फिर मान नियत
(जैसे): int i = 5
, int b = ++i
इस मामले में, 6 7 और इतने पर करने के लिए पहले और उसके बाद वेतन वृद्धि ख को सौंपा गया है।
i++
(पोस्टफिक्स आपरेशन): निर्दिष्ट और उसके बाद मूल्य वृद्धि कर देता है
(उदाहरण के लिए): int i = 5
,int b = i++
इस मामले में, 5 से 6 और इतने पर करने के लिए पहले और उसके बाद वेतन वृद्धि ख को सौंपा गया है।
लूप के लिए इन्सेस्ट: i++
ज्यादातर इसलिए इस्तेमाल किया जाता है, क्योंकि आमतौर पर हम i
लूप के लिए इन्क्रीमेंट से पहले के शुरुआती मूल्य का उपयोग करते हैं । लेकिन आपके प्रोग्राम लॉजिक के आधार पर यह भिन्न हो सकता है।
मुझे लगता है कि आप अब शब्दार्थ में अंतर को समझते हैं (हालांकि ईमानदारी से मुझे आश्चर्य है कि लोग क्यों पूछते हैं कि 'ऑपरेटर एक्स का क्या मतलब है' पढ़ने के बजाय स्टैक ओवरफ्लो पर सवाल करते हैं, आप जानते हैं, एक पुस्तक या वेब ट्यूटोरियल या कुछ और।
लेकिन वैसे भी, जहां तक किसी को भी उपयोग करने के लिए, प्रदर्शन के प्रश्नों को अनदेखा करें, जो C ++ में भी महत्वपूर्ण नहीं हैं। यह वह सिद्धांत है जिसे आपको यह तय करते समय उपयोग करना चाहिए कि किसका उपयोग करना है:
आप कोड में क्या कहते हैं।
यदि आपको अपने बयान में मूल्य-पहले-वृद्धि की आवश्यकता नहीं है, तो ऑपरेटर के उस रूप का उपयोग न करें। यह एक छोटी सी बात है, लेकिन जब तक आप एक स्टाइल गाइड के साथ काम नहीं कर रहे हैं जो एक संस्करण को पूरी तरह से दूसरे पक्ष (उर्फ एक हड्डी की अध्यक्षता वाली शैली गाइड) के पक्ष में बैन करता है, तो आपको उस फॉर्म का उपयोग करना चाहिए जो सबसे सटीक रूप से व्यक्त करता है कि आप क्या करने की कोशिश कर रहे हैं।
QED, पूर्व वेतन वृद्धि संस्करण का उपयोग करें:
for (int i = 0; i != X; ++i) ...
अंतर को इस सरल C ++ कोड द्वारा समझा जा सकता है:
int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
मुख्य अंतर है
- i ++ पोस्ट ( वेतन वृद्धि के बाद ) और
++ मैं पूर्व ( वेतन वृद्धि से पहले )
i =1
लूप वेतन वृद्धि की तरह पोस्ट करें1,2,3,4,n
i =1
लूप वेतन वृद्धि की तरह अगर2,3,4,5,n
यह छोटा कोड पहले से ही पोस्ट किए गए उत्तरों की तुलना में भिन्न कोण से अंतर की कल्पना करने में मदद कर सकता है:
int i = 10, j = 10;
printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);
printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);
परिणाम है:
//Remember that the values are i = 10, and j = 10
i is 10
i++ is 10 //Assigns (print out), then increments
i is 11
j is 10
++j is 11 //Increments, then assigns (print out)
j is 11
पहले और बाद की स्थितियों पर ध्यान दें।
जिसके लिए उनमें से एक का उपयोग लूप के एक इन्क्रीप्शन ब्लॉक में किया जाना चाहिए, मुझे लगता है कि निर्णय लेने के लिए हम जो सबसे अच्छा कर सकते हैं वह एक अच्छा उदाहरण है:
int i, j;
for (i = 0; i <= 3; i++)
printf (" > iteration #%i", i);
printf ("\n");
for (j = 0; j <= 3; ++j)
printf (" > iteration #%i", j);
परिणाम है:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
मैं आपके बारे में नहीं जानता, लेकिन मुझे इसके उपयोग में कोई अंतर नहीं दिखता है, कम से कम लूप के लिए।
निम्नलिखित C कोड टुकड़ा पूर्व और बाद के वेतन वृद्धि और वेतन वृद्धि ऑपरेटरों के बीच अंतर को दर्शाता है:
int i;
int j;
वृद्धि ऑपरेटरों:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
प्री-क्रीमेंट का मतलब है एक ही लाइन पर इंक्रीमेंट। पोस्ट-इन्क्रीमेंट का अर्थ है, लाइन के क्रियान्वयन के बाद वेतन वृद्धि।
int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.
int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes
जब यह OR, और ऑपरेटरों के साथ आता है, तो यह अधिक दिलचस्प हो जाता है।
int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}
int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}
ऐरे में
System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12
jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13
mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13
for (int val: a) {
System.out.print(" " +val); //55, 13, 15, 20, 25
}
सी ++ पोस्ट / पॉइंटर वेरिएबल के प्री-इन्क्रीमेंट में
#include <iostream>
using namespace std;
int main() {
int x=10;
int* p = &x;
std::cout<<"address = "<<p<<"\n"; //prints address of x
std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
std::cout<<"address = "<<&x<<"\n"; //prints address of x
std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}
कुछ ही समय:
++i
और i++
यदि आप उन्हें किसी फ़ंक्शन में नहीं लिख रहे हैं तो वही काम करता है। यदि आप किसी चीज का उपयोग करते हैं function(i++)
या function(++i)
आप अंतर देख सकते हैं।
function(++i)
कहते हैं कि पहली वृद्धि 1 से होती है, उसके बाद इसे i
नए मान के साथ कार्य में लगाते हैं।
function(i++)
कहते हैं i
कि i
1 से वृद्धि के बाद पहले समारोह में डाल दिया ।
int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now
int j = ++i;
और int k = i++;
यहाँ तक कि जब कोई समारोह कॉल शामिल किया गया।
एकमात्र अंतर वैरिएबल की वृद्धि और ऑपरेटर के रिटर्न के मूल्य के बीच संचालन का क्रम है।
यह कोड और इसका आउटपुट अंतर बताता है:
#include<stdio.h>
int main(int argc, char* argv[])
{
unsigned int i=0, a;
a = i++;
printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
i=0;
a = ++i;
printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}
आउटपुट है:
i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1
इसलिए मूल रूप ++i
से वृद्धि होने के बाद मूल्य वापस करता है, जबकि ++i
मूल्य बढ़ने से पहले मूल्य वापस करता है। अंत में, दोनों मामलों में i
वसीयत का मूल्य बढ़ जाएगा।
एक और उदाहरण:
#include<stdio.h>
int main ()
int i=0;
int a = i++*2;
printf("i=0, i++*2=%d\n", a);
i=0;
a = ++i * 2;
printf("i=0, ++i*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
return 0;
}
आउटपुट:
i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2
मतभेद स्पष्ट हैं जब दिए गए मान एक और चर या जब वेतन वृद्धि संयोजन में अन्य कार्यों जहां आपरेशन पूर्वता लागू किया जाता है के साथ (किया जाता है करने के लिए असाइन किया गया है i++*2
से अलग है ++i*2
, लेकिन (i++)*2
और (++i)*2
एक ही मान देता है) कई मामलों में वे परस्पर विनिमय कर रहे। लूप सिंटैक्स के लिए एक शास्त्रीय उदाहरण है:
for(int i=0; i<10; i++)
का एक ही प्रभाव है
for(int i=0; i<10; ++i)
दो ऑपरेटरों के बीच कोई भ्रम न पालने के लिए मैंने यह नियम अपनाया:
असाइनमेंट के संबंध में ऑपरेशन के आदेश के साथ ++
चर के संबंध में ऑपरेटर की स्थिति को संबद्ध करेंi
++
दूसरे शब्दों में कहा:
++
इससे पहले i
कि वेतन वृद्धि असाइनमेंट से पहले किया जाना चाहिए ;++
i
वृद्धि के बाद वृद्धि असाइनमेंट के बाद किया जाना चाहिए :a = i ++ का अर्थ है कि एक समसामयिक i मान = a + i का अर्थ है कि इसमें एक वृद्धित आई मान है
a = i++;
इसका मतलब है कि जमा a
किया गया मूल्य i
वृद्धि के पहले का मूल्य होगा , लेकिन 'वेतन वृद्धि के बिना' का मतलब है कि i
वेतन वृद्धि नहीं है, जो पूरी तरह से गलत है - i
वेतन वृद्धि है, लेकिन वेतन वृद्धि से पहले अभिव्यक्ति का मूल्य है।
यहाँ अंतर को समझने के लिए उदाहरण है
int i=10;
printf("%d %d",i++,++i);
आउटपुट: 10 12/11 11
( printf
फ़ंक्शन के तर्कों के मूल्यांकन के क्रम पर निर्भर करता है , जो संकलक और आर्किटेक्चर में भिन्न होता है)
स्पष्टीकरण:
i++
-> i
मुद्रित किया जाता है, और फिर वेतन वृद्धि। (प्रिंट 10, लेकिन i
11 हो जाएंगे)
++i
-> i
मूल्य वृद्धि और मूल्य प्रिंट करता है। (प्रिंट्स 12, और मूल्य i
भी 12)
i++
और++i