यदि "i ++ == ++ i" हो तो C डेवलपर्स को कितना उत्सुक बनाता है? [बन्द है]


15

बस एक यादृच्छिक अवलोकन, ऐसा लगता है कि StackOverflow.com पर, "++ i == i ++" के बारे में प्रश्न हैं। हालांकि यह सवाल हर समय पूछा जाता है, मुझे लगता है कि मैंने पिछले 2 महीनों में इसे 6 या 7 बार पूछा है।

मुझे आश्चर्य है कि सी डेवलपर्स इसमें क्यों रुचि रखते हैं? C # और Java देवों के लिए भी यही अवधारणा / प्रश्न मौजूद है, लेकिन मुझे लगता है कि मैंने केवल एक C # संबंधित प्रश्न देखा।

यह इसलिए है क्योंकि बहुत सारे उदाहरणों का उपयोग करता है ++ i? क्या यह इसलिए है क्योंकि कुछ लोकप्रिय पुस्तक या ट्यूटोरियल है? क्या यह इसलिए है क्योंकि सी डेवलपर्स सिर्फ 'दक्षता' / 'प्रदर्शन' के लिए एक ही पंक्ति में जितना संभव हो उतना रटना पसंद करते हैं और इसलिए ++ ऑपरेटर का उपयोग करके अधिक बार 'अजीब' निर्माण का सामना करते हैं?


23
(मेरे लिए C # dev के रूप में, i ++ और ++ i बराबर हैं। मुझे पता है कि वे नहीं हैं, लेकिन अगर मैं ऐसा कोड लिखूं जो इस अंतर पर निर्भर करता है कि मैं इसे अधिक पठनीय बनाना चाहूंगा और संकलक और JITter से देखभाल करने की अपेक्षा करूंगा। इसके बारे में, लेकिन एक सी # देव के रूप में मैं क्योंकि मैं पहले से ही अपेक्षाकृत अक्षम कर रहा हूँ वैसे भी एक या दो घड़ी चक्र को बचाने के लिए) की कोशिश कर रहा नहीं कर रहा हूँ
माइकल Stum

1
नवोदित प्रोग्रामर के रूप में हम अंकगणित, तर्क के साथ खेलना पसंद करते हैं और उत्सुक हैं कि चीजें कैसे काम करती हैं। मुझे लगता है कि एक बड़ा कारण है कि हम इस तरह के सवालों से प्यार करते हैं। यह एक पथप्रदर्शक विशेषता नहीं हो सकता है लेकिन यह सुनिश्चित करना दिलचस्प है! इस कारण से हम पहले स्थान पर प्रोग्रामर नहीं बने?
चानी

2
क्या आप शाब्दिक रूप से अभिव्यक्ति का उल्लेख कर रहे हैं ++i == i++, या आम तौर पर बीच के अंतर के बारे में ++iऔर i++?
कीथ थॉम्पसन

जवाबों:


30

मुझे संदेह है कि इसका कम से कम हिस्सा थोड़ा सरल है: अब भी, हम स्कूल वर्ष की शुरुआत के आसपास इस तरह के बहुत सारे प्रश्न देखते हैं, और वे धीरे-धीरे पूरे वर्ष बंद कर देते हैं।

इस तरह, मुझे लगता है कि यह अनुमान लगाना उचित है कि उनमें से कुछ केवल उन कक्षाओं का परिणाम हैं जिनमें शिक्षक कम से कम इसके बारे में बात करते हैं, लेकिन अपनी बात () को बहुत अच्छी तरह से नहीं समझाते हैं (जैसा कि अक्सर नहीं क्योंकि वह वास्तव में उन्हें खुद नहीं समझता)। विशेष रूप से उन लोगों के आधार पर जो इन सवालों को पूछते हैं, कुछ वास्तविक कोडिंग पर आधारित हैं।


14
क्या यह सितंबर के विपरीत नहीं है ? शाश्वत सितंबर तब था जब एओएल ने अपने ग्राहकों को यूज़नेट एक्सेस की पेशकश करना शुरू कर दिया, जिससे यह सितंबर जैसा लगने लगा (वह महीना जब स्कूल शुरू करने वाले नए छात्रों ने परंपरागत रूप से नए साल के रूप में बोर्डों पर बमबारी की)।
मुलवल्कर

यह एक दिलचस्प सिद्धांत है, लेकिन शायद यह हमेशा शिक्षकों की गलती नहीं है अगर कोई व्यक्ति सामग्री को नहीं समझता था: शायद छात्र थे (1) कक्षा के दौरान पर्याप्त ध्यान नहीं दे रहे थे और (2) स्टैकओवरफ्लो पर जवाब देने के लिए बहुत आलसी थे। फिर से वही सवाल पूछ रहा हूं।
जियोर्जियो

12

क्योंकि सी प्रोग्रामर संचालन के आदेश को समझने के लिए हैं। C # डेवलपर्स जरूरी नहीं कि बिटवाइज ऑपरेटर्स ((।, ~, ~) या उपसर्ग ऑपरेटरों का उपयोग करें क्योंकि हम सामान्य रूप से अन्य सामान के बारे में अधिक चिंतित हैं। हालाँकि, जो हम C # devs का एहसास नहीं करते हैं, वह यह है कि हमें पता होना चाहिए कि हम दैनिक आधार पर जो ऑपरेटरों का उपयोग करते हैं, उन्हें कैसे ठीक से उपयोग किया जाए। हम में से ज्यादातर सिर्फ उन जगहों से बचते हैं जहाँ यह एक समस्या हो सकती है।

अपने सिर के ऊपर से, इस स्निपेट का आउटपुट क्या है?

    double x = 5.5;
    Console.WriteLine(x++);
    x = 5.5;
    Console.WriteLine(++x);

मैं कहूंगा कि सी # देवों की एक अच्छी संख्या में पता नहीं है कि कंसोल का आउटपुट क्या है।


3
+1। पूर्व और बाद के फिक्स वेतन वृद्धि / गिरावट ऑपरेटरों के बीच अंतर जानना इस तरह की स्थितियों के लिए इसके लायक है।
मौलरस

4
मुझे लगता है कि मैं इस बिंदु को देख रहा हूं और मुझे या तो आउटपुट पता नहीं होगा (मेरा मानना ​​है कि यह 5.5 और 6.5 है, लेकिन मुझे यकीन नहीं है), और मेरे लिए यह कोई फर्क नहीं पड़ेगा क्योंकि मैं इसे x ++ को रिफ्लेक्टर करूंगा; Console.WriteLine (x); हाथोंहाथ। मैं पूरी तरह से अनजान नहीं हूँ, लेकिन मुझे लगता है कि यह शून्य प्रयोज्य के साथ एक बड़ी कोड गंध है।
माइकल Stum

9
प्रश्न के उत्तर का संचालन के क्रम या उपसर्ग और पश्च उपसंहार के बीच के अंतर से कोई लेना-देना नहीं है। यह परिभाषित और अपरिभाषित व्यवहार की बात है।
डेविड थॉर्नले

2
मैंने आज इसका सामना किया। कुछ इस तरह if (myList[i++] == item)। चतुर। मुझे यह एक IndexOutOfRange अपवाद के स्रोत की तलाश में मिला ... वास्तव में, बहुत "चतुर"।
rmac

7
मुझे लगता है कि यह ५.५ और ६.५ है, लेकिन मैंने पहले कभी ++फ्लोट पर उपयोग नहीं किया है, और मुझे कहना होगा कि यह बहुत उपयुक्त नहीं लगता है। क्या लोग ऐसा करते हैं? (मैं पसंद करता हूँ += 1)
बार्ट वैन ह्युकेलोम

8

मुझे लगता है कि यह स्पष्ट है। सी # में, के लिए int i, i++ == ++iहमेशा गलत है, जबकि ++i == i++हमेशा सच है, मज़बूती से, और जो कोई भी इच्छुक है, वह इसे आसानी से सी # के नियमों को सीखकर पता लगा सकता है (या वास्तव में सिर्फ इसे चलाकर)।

सी और सी ++ में, दूसरी ओर, यह अपरिभाषित के करीब है क्योंकि यह संकलक, निष्पादन पर्यावरण, प्लेटफॉर्म, आदि पर निर्भर करता है, इसलिए यह जवाब देने के लिए बहुत कठिन सवाल है, इसलिए बहुत से लोग इसे पूछते हैं।


+1 - लेकिन यह वास्तव में जवाब देने के लिए एक कठिन सवाल नहीं है। "अपरिभाषित" एक शब्द है। सभी "यह निर्भर करता है ..." सामान सामान है जिसके बारे में ज्यादातर लोग चिंता नहीं करते हैं। यहां तक ​​कि अगर आप केवल एक विशेष मंच के लिए लिख रहे हैं, तो आपको समग्र रूप से भाषा के लिए सामान्य मुहावरों का उपयोग करना चाहिए, और पूर्व-वेतन वृद्धि और पश्च-वृद्धि ऑपरेटरों के अधिकांश उपयोग कुछ सामान्य मुहावरों का हिस्सा हैं।
स्टीव

+1: यह वास्तव में पूछे गए प्रश्न का उत्तर देता है (अर्थात, आप लाइनों के बीच नहीं पढ़ रहे हैं)।
थॉमस ईडिंग

7

यह एक लोकप्रिय प्रश्न है क्योंकि यह एक ट्रिक प्रश्न है। यह अपरिभाषित है

ऊपर दिया गया लिंक Bjarnes Stroustrup के होमपेज पर एक FAQ पर जाता है, जो इस प्रश्न को विशेष रूप से संबोधित करता है, और बताता है कि यह निर्माण अपरिभाषित क्यों है। यह क्या कहता है:

मूल रूप से, C और C ++ में, यदि आप एक चर को दो बार अभिव्यक्ति में पढ़ते हैं जहां आप इसे लिखते हैं, तो परिणाम अपरिभाषित होता है।

मूल्यांकन के आदेश के अपरिभाषित होने पर बेहतर प्रदर्शन करने वाले कोड का उत्पादन करने का दावा किया जाता है।


5

सबसे अधिक संभावना है क्योंकि सी में, यह वास्तव में मायने रखता है यदि आप लिखते हैं i++या ++iजब आप सूचक अंकगणित कर रहे हैं। वहाँ, iएक ऑपरेशन से पहले या बाद में बढ़ाना महत्वपूर्ण हो सकता है। मैं आपको एक उदाहरण देता हूं लेकिन पिछली बार जब मैंने लिखा था कि सी 10 साल पहले था ...

C # में, मैं कभी ऐसी स्थिति में नहीं आया हूँ जिसके लिए मुझे सोचने की आवश्यकता होगी i++या ++iक्योंकि AFAIK, फॉर / लूप्स के लिए, यह वास्तव में मायने नहीं रखता है।


3
C # में अंतर को समझना अभी भी महत्वपूर्ण है - सिर्फ इसलिए कि आप उन्हें केवल / प्रत्येक लूप में उपयोग करने के लिए प्रतीत करते हैं इसका मतलब यह नहीं है कि आप उन्हें खोजने के लिए एकमात्र स्थान
STW

पूरी तरह से सच है कि।
म्लादेन प्रजादिक

3
यह सवाल के लिए प्रासंगिक नहीं है। यह सवाल किसी i++और के बीच के अंतर के बारे में नहीं है ++i, बल्कि उन्हें एक ही अभिव्यक्ति में संयोजित करने का है।
डेविड थॉर्नले

@ डेविड सवाल यह है कि सी प्रोग्रामर इसे लेकर उत्सुक क्यों हैं। उत्तर (यह C में मायने रखता है, C # में इतना नहीं है) पूरी तरह से प्रासंगिक है। "
फ्लोरियन F

2

कुछ साल पहले मैंने पढ़ा था कि इन ऑपरेटरों को खतरनाक माना जाता था इसलिए मैंने इस पर अधिक जानकारी खोदने की कोशिश की। अगर उस समय स्टैकओवरफ्लो हुआ होता, तो मैं वहां पूछ लेता।

अब यह इसलिए है क्योंकि कुछ ट्विस्टेड लोग लूप लिखते हैं जैसे कि

while( [something] )
{
  a[++j] = ++j;
}

अब भी, मैं इस बारे में निश्चित नहीं हूं कि क्या होगा / होना चाहिए, लेकिन यह मेरे लिए बहुत स्पष्ट है कि एक ही लाइन पर एकाधिक ++ [var] परेशानी पूछ रहा है।


2
वेतन वृद्धि का अपरिभाषित व्यवहार C
tzenes

7
जैसे असाइनमेंट x = ++j;सी में अच्छी तरह से परिभाषित हैं। उपरोक्त अनिश्चित है क्योंकि jएक हस्तक्षेप अनुक्रम बिंदुओं के बिना दो बार संशोधित किया गया है।
मैथ्यू फ्लशेन

2

दो कारण।

++ i का सही क्रियान्वयन i वृद्ध करना है और फिर इसे वापस करना है। I ++ का सही कार्यान्वयन वर्तमान मूल्य, वेतन वृद्धि i, और सहेजे गए मान को वापस करना है। यह जानना कि इन्हें पर्यायवाची के रूप में लागू नहीं किया गया है।

प्रश्न तब बनता है जब संकलक अभिव्यक्ति का मूल्यांकन करते समय उन्हें लागू करता है, जैसे कि समानता।

यदि समानता परीक्षण पहले किया जाता है, तो पूर्व और बाद के वेतन वृद्धि ऑपरेटरों, आपको अलग-अलग तर्क लिखना होगा, अगर बाएं हाथ की तरफ (lhs) और दाहिने हाथ की तरफ (rhs) का मूल्यांकन पहले किया जाता है, तो समानता।

यह सभी कार्यों के क्रम के बारे में है, और यह बदले में कोड एक को प्रभावित करता है। और, बहुत आश्चर्य की बात नहीं, सभी भाषाओं में सहमति नहीं है।

बुनियादी परीक्षण सूची यह डेवलपर्स को यह देखने के लिए परीक्षण करने की अनुमति देती है कि क्या उनकी धारणाएं सही हैं, साथ ही साथ वास्तविक कार्यान्वयन भाषा विनिर्देश से मेल खाता है।

पॉइंटर्स, लूप्स या रिटर्निंग वैल्यूज़ के साथ काम करने पर यह सभी प्रकार का प्रभाव डाल सकता है।


5
इस पर बुनियादी परीक्षण भ्रामक होगा, क्योंकि यह अपरिभाषित व्यवहार है। यदि यह इस समय की अपेक्षा ठीक काम करता है, तो अगली बार इसकी कोई गारंटी नहीं है।
डेविड थॉर्नले

आपने गलत प्रश्न का उत्तर दिया है। आपको जवाब देना चाहिए कि सी प्रोग्रामर इसके बारे में क्यों उत्सुक हैं।
ह्यूगो

आपका दूसरा पैरा वैसे भी गलत है (C ++ 11 से पहले, कम से कम): व्यवहार का उपयोग मूल्य++i का उपयोग करना हैi+1 और किसी समय में, शायद उससे पहले या बाद में, लेकिन अगले अनुक्रम बिंदु से पहले, वेतन वृद्धिi
एमएम

@MattMcNabb - क्या आप मुझे इसके लिए किसी विनिर्देशन की ओर संकेत कर सकते हैं, मैं यह जानने के लिए उत्सुक हूं कि क्या कार्यान्वयन में चीजें बदल गई हैं। उन दिनों में जहां सी ने पीडीपी असेंबली में अच्छी तरह से मैप किया, ++ ने आईएनसी निर्देश को इंजेक्ट किया, जबकि प्रत्यय संस्करण को वेतन वृद्धि के बाद एक निर्देश का उपयोग करने के लिए एक रजिस्टर में मूल्य की प्रतिलिपि बनाना था। आपके द्वारा वर्णित परिवर्तन के लिए क्या आवश्यकता है?
वॉल्ट स्टोनबर्नर

2

मुझे लगता है कि यह एक संस्कृति की बात है।

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

किसी अन्य भाषा में कुछ प्रोग्रामिंग करने वाले व्यक्ति के लिए - किसी ऐसे व्यक्ति ने जो इस विचार को उठाया है कि प्रोग्रामिंग भाषाओं को सटीक माना जाता है, और यह माना जाता है कि कंप्यूटर वे करते हैं जो उन्हें करने के लिए कहा जाता है ... ठीक है, यह एक झटका है पता चलता है कि सी जानबूझकर कुछ चीजों के बारे में अस्पष्ट है।


सी इस तरह से है क्योंकि यह तब भी अस्तित्व में था जब सी # परिभाषित किया गया था, जिसमें सबसे अजीब एम्बेडेड या मेनफ्रेम प्लेटफॉर्म शामिल हैं, जिनके मुकाबले आप सोच सकते हैं। दूसरी ओर, C # ... x86, और 360 पर चलता है? शायद एआरएम भी? और कुछ नहीं। इसलिए C # बहुत अधिक परिभाषित कर सकता है।
डेडएमजी जूल

++ इसके अलावा, सी पहले एक पीडीपी -11 पर नहीं बनाया गया था? जहां ऑटो-इंक्रीमेंट के निर्देश थे? सी "मशीन के करीब" होना चाहता था ताकि यह निर्देश सेट का उपयोगी उपयोग कर सके।
माइक डनलैवी

@MikeDunlavey: नहीं, C ++और --ऑपरेटर PDP-11 पर आधारित नहीं थे, जो तब मौजूद नहीं था जब उन ऑपरेटरों को C की पूर्ववर्ती भाषा में पेश किया गया था। देखें cm.bell-labs.com/who/dmr/ist.html , और "ऑटो-इन्क्रीमेंट" की खोज करें।
कीथ थॉम्पसन

1

शायद यह सिर्फ इतना है कि सी डेवलपर्स सामान्य रूप से ++ वेतन वृद्धि का उपयोग करते हैं - यह देखते हुए कि कैसे सी के पास कोई "फ़र्क" नहीं है या सरणियों के माध्यम से पुनरावृति करने के लिए इसी तरह का बयान है। ओह, और निश्चित रूप से सूचक अंकगणितीय, जैसा कि पहले उल्लेख किया गया है!


1
अच्छी बात है, यह भूल गए कि फॉरच एक अपेक्षाकृत आधुनिक अवधारणा है।
माइकल स्टम

-1

दोनों भागों के बीच का अंतर: पोस्ट और प्रीइंक्रिमेंट काम कर रहे हैं जिस तरह से इन दोनों कोड को हर भाषा में काम करना चाहिए। यह भाषाई दोष नहीं होगा !!!

++i

यह प्री इन्क्रीमेंट है। कोड का यह टुकड़ा सबसे पहले उस मूल्य को बढ़ाएगा, iजहां वह उस मूल्य को भेजता है जहां उसका उपयोग किया जाता है।

i++

यह पद वृद्धि है। कोड का यह टुकड़ा उस लाइन iके मूल्य को बढ़ाने से पहले लौटाएगा iजहां इसका उपयोग किया जाता है।

एक और छोटे उदाहरण में:

int main(void)
{
  int i = 0; 
  int result; 
  result = 10 + ++i; 
  printf("%d \n", result); // = 11 

  int j = 0; 
  result = 10 + j++; 
  printf("%d \n", result);// = 10
  return 0;
}

यह कोड कोडपैड पर परिणाम के साथ संकलन है।

यह ओवरलोडिंग ऑपरेटर के आंतरिक कार्यान्वयन के साथ करना है।

++i सीधे मूल्य बढ़ता है (और इसलिए थोड़ा तेज है)

i++पहले एक प्रतिलिपि बनाता है जो उस स्थान पर वापस आ जाती है जहां जरूरत होती है और बाद में iचर का मूल मूल्य एक से बढ़ जाता है।

मुझे उम्मीद है कि यह अब स्पष्ट है।


फिर भी यह वास्तविक प्रश्न को स्वीकार नहीं करता है: सी डेवलपर्स दूसरों से अधिक इस बारे में क्यों पूछते हैं। ओपी संचालकों को समझता है।
मार्टिज़न पीटरर्स

साथ ही यह उत्तर तथ्यात्मक रूप से गलत है। ++iतेजी से नहीं है, और i++एक प्रतिलिपि नहीं बनाता है। इसके अलावा, ++iC ++ की तुलना में C में थोड़ा अलग व्यवहार करता है, अन्य भाषाओं के बीच अकेले रहने दें।
एमएम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.