क्यों x + = y जैसे शॉर्टकट अच्छे अभ्यास माने जाते हैं?


305

मुझे नहीं पता कि ये वास्तव में क्या कहे जाते हैं, लेकिन मैं उन्हें हर समय देखता हूं। अजगर का कार्यान्वयन कुछ इस तरह है:

x += 5शॉर्टहैंड नोटेशन के रूप में x = x + 5

लेकिन यह अच्छा अभ्यास क्यों माना जाता है? मैंने इसे लगभग हर पुस्तक या प्रोग्रामिंग ट्यूटोरियल में चलाया है, जिसे मैंने पायथन, सी, आर इत्यादि के लिए पढ़ा है। मुझे लगता है कि यह सुविधाजनक है, जिसमें अंतरिक्ष सहित तीन कीस्ट्रोक्स की बचत है। लेकिन वे हमेशा मुझे यात्रा करने लगते हैं जब मैं कोड पढ़ रहा होता हूं, और कम से कम मेरे दिमाग में, इसे कम पठनीय बनाते हैं , अधिक नहीं।

क्या मुझे कुछ स्पष्ट और स्पष्ट कारण याद आ रहे हैं, जिनका उपयोग सभी जगह किया जाता है?


@EricLippert: क्या C # इसे उसी तरह से हैंडल करता है जैसे कि शीर्ष उत्तर में वर्णित है? क्या वास्तव में यह कहना अधिक कुशल सीएलआर-वार x += 5है x = x + 5? या क्या यह वास्तव में सिर्फ सिंथेटिक चीनी है जैसा कि आप सुझाव देते हैं?
मांस

24
@ पत्थर: स्रोत कोड में एक अतिरिक्त जोड़ के रूप में व्यक्त करने वाले छोटे विवरणों के परिणामस्वरूप निष्पादन योग्य कोड की दक्षता पर प्रभाव पड़ता है 1970 में मामला हो सकता है; यह निश्चित रूप से अब नहीं है। ऑप्टिमाइज़िंग कंपाइलर अच्छे हैं, और आपके पास यहां या वहां नैनोसेकंड की तुलना में बड़ी चिंताएं हैं। यह विचार कि + = ऑपरेटर "बीस साल पहले" विकसित किया गया था, स्पष्ट रूप से गलत है; देर डेनिस रिची ने 1969 में बेल लैब्स में 1973 के माध्यम से सी विकसित की।
एरिक लिपर्ट

1
देखें blogs.msdn.com/b/ericlippert/archive/2011/03/29/... (भी भाग दो देखें)
SLaks

5
अधिकांश कार्यात्मक प्रोग्रामर इस बुरे अभ्यास पर विचार करेंगे।
पीट किर्कम

जवाबों:


598

यह आशुलिपि नहीं है।

+=प्रतीक 1970 के दशक में सी भाषा में दिखाई दिया, और - "स्मार्ट कोडांतरक" का एक स्पष्ट रूप से अलग मशीन शिक्षा और को संबोधित मोड के अनुरूप सी विचार के साथ:

" i=i+1", "i+=1"और" ++i" जैसी चीजें , हालांकि एक सार स्तर पर एक ही प्रभाव पैदा करती हैं, प्रोसेसर के काम करने के एक अलग तरीके से निम्न स्तर पर मेल खाती हैं।

विशेष रूप से उन तीन अभिव्यक्तियों को मानते हुए, iचर एक सीपीयू रजिस्टर में संग्रहीत मेमोरी एड्रेस में रहता है (इसे नाम दें D- इसे "इंट्रूडर टू इंट" के रूप में सोचें) और प्रोसेसर का ALU एक पैरामीटर लेता है और एक में परिणाम देता है "संचायक" (इसे ए कहते हैं - इसे इंट के रूप में सोचें)।

इन बाधाओं (उस अवधि से सभी माइक्रोप्रोसेसरों में बहुत आम) के साथ, अनुवाद की संभावना सबसे अधिक होगी

;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1;  //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)

;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value

;++i;
INC (D); //Just "tick" a memory located counter

इसे करने का पहला तरीका असत्य है, लेकिन निरंतर ( ADD A, Bया ADD A, (D+x)) के बजाय चरों के साथ काम करते समय यह अधिक सामान्य है और अधिक जटिल अभिव्यक्तियों का अनुवाद करते समय (वे सभी एक स्टैक में कम प्राथमिकता वाले ऑपरेशन में उबलते हैं, उच्च प्राथमिकता कहते हैं, पॉप और तब तक दोहराएं जब तक कि सभी तर्क समाप्त नहीं हो गए)।

दूसरा "राज्य मशीन" का अधिक विशिष्ट है: हम अब "एक अभिव्यक्ति का मूल्यांकन" नहीं कर रहे हैं, लेकिन "एक मान का संचालन कर रहे हैं": हम अभी भी एएलयू का उपयोग करते हैं, लेकिन पैरामीटर को बदलने के लिए अनुमत परिणाम होने के आसपास बढ़ते मूल्यों से बचें। इस तरह के निर्देश का उपयोग नहीं किया जा सकता है जहां अधिक जटिल अभिव्यक्ति की आवश्यकता होती है: i = 3*i + i-2जगह में संचालित नहीं किया जा सकता है, क्योंकि iअधिक बार आवश्यक है।

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

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

x += 5 माध्यम

  • X द्वारा पहचाने गए स्थान का पता लगाएं
  • इसमें 5 जोड़ दें

लेकिन x = x + 5इसका मतलब है:

  • X + 5 का मूल्यांकन करें
    • X द्वारा पहचाने गए स्थान का पता लगाएं
    • एक्स को एक संचायक में कॉपी करें
    • संचायक में 5 जोड़ें
  • परिणाम को x में संग्रहीत करें
    • X द्वारा पहचाने गए स्थान का पता लगाएं
    • संचायक को इसकी प्रतिलिपि दें

बेशक, अनुकूलन कर सकते हैं

  • यदि "खोज एक्स" का कोई साइड इफेक्ट नहीं है, तो दो "खोज" एक बार किया जा सकता है (और एक्स एक पॉइंटर रजिस्टर में संग्रहीत पता बन जाता है)
  • यदि &xसंचायक के बजाय ADD को लागू किया जाता है, तो दो प्रतियों को निकाला जा सकता है

इस प्रकार x += 5एक के संयोग से अनुकूलित कोड बनाना ।

लेकिन यह केवल तभी किया जा सकता है जब "फाइंडिंग एक्स" का कोई साइड इफेक्ट न हो, अन्यथा

*(x()) = *(x()) + 5;

तथा

*(x()) += 5;

शब्दशः भिन्न हैं, क्योंकि x()साइड इफेक्ट्स (स्वीकार x()करना एक फ़ंक्शन है जो चारों ओर अजीब चीजें कर रहा है और वापस आ रहा है int*) दो बार या एक बार उत्पादित किया जाएगा।

के बीच समानता है x = x + yऔर x += yइसलिए विशेष मामले के कारण है जहां +=और =प्रत्यक्ष एल-मूल्य पर लागू होते हैं।

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


किसके लिए अधिक विवरण पसंद है ...

हर सीपीयू में एक ALU (अंकगणित-तार्किक इकाई) होती है, जो कि बहुत सार में, एक कॉम्बीनेटरियल नेटवर्क है जिसके इनपुट और आउटपुट को रजिस्टरों के लिए "प्लग" किया जाता है और / या मेमोरी को निर्देश के opcode पर निर्भर करता है।

बाइनरी ऑपरेशंस को आमतौर पर "कहीं" लिए गए इनपुट के साथ "एक संचायक रजिस्टर के संशोधक" के रूप में लागू किया जाता है, जहां कहीं भी हो सकता है - निर्देश प्रवाह के अंदर ही (प्रकट प्रतियोगी के लिए विशिष्ट: ADD A 5) - एक अन्य रजिस्ट्री के अंदर (अभिव्यक्ति की गणना के लिए विशिष्ट) टेंपरेरी: जैसे ADD AB) - मेमोरी के अंदर, एक रजिस्टर द्वारा दिए गए पते पर (जैसे कि विशिष्ट डेटा प्राप्त करने का उदाहरण: ADD A (H)) - H, इस मामले में, एक डेरेफ़रिंग पॉइंटर की तरह काम करते हैं।

इस छद्मकोश के साथ, x += 5है

ADD (X) 5

जबकि x = x+5है

MOVE A (X)
ADD A 5
MOVE (X) A

यही है, x + 5 एक अस्थायी देता है जिसे बाद में सौंपा गया है। x += 5एक्स पर सीधे काम करता है।

वास्तविक कार्यान्वयन प्रोसेसर के वास्तविक अनुदेश सेट पर निर्भर करता है: यदि कोई ADD (.) cओपकोड नहीं है , तो पहला कोड दूसरा बन जाता है: कोई रास्ता नहीं।

यदि ऐसा कोई ओपकोड है, और ऑप्टिमाइज़ेशन सक्षम है, तो दूसरी अभिव्यक्ति, रिवर्स मूव्स को समाप्त करने और रजिस्टरों के ओपकोड को समायोजित करने के बाद, पहली बन जाती है।


90
+1 केवल यह समझाने के लिए कि पुराने जमाने में यह अलग (और अधिक कुशल) मशीन कोड पर मैप करता था।
Péter Török

11
@KeithThompson यह सच है लेकिन कोई इस बात से इनकार नहीं कर सकता कि असेंबली का सी भाषा (और बाद में सभी सी शैली भाषाओं) के डिजाइन पर बहुत बड़ा प्रभाव था
MattDavey

51
एर्म, "+ =" "इंक" में मैप नहीं करता (यह "एड" में मैप करता है), "++" मैप्स से "इंक"।
ब्रेंडन

11
"20 साल पहले" से, मुझे लगता है कि आपका मतलब "30 साल पहले" था। और BTW, COBOL ने C को एक और 20 साल से हरा दिया: ADD 5 TO X.
जोएलफैन

10
सिद्धांत रूप में महान; तथ्यों में गलत। X86 ASM INC केवल 1 जोड़ता है, इसलिए यह यहां चर्चा किए गए "ऐड और असाइन" ऑपरेटर को प्रभावित नहीं करता है (यह "++" और "-" हालांकि के लिए एक शानदार जवाब होगा)।
मार्क ब्रैकेट

281

आप इसके बारे में कैसे सोचते हैं, इस पर निर्भर करते हुए, यह वास्तव में समझना आसान है क्योंकि यह अधिक सीधा है। उदाहरण के लिए:

x = x + 5 "एक्स ले लो, इसमें पांच जोड़ो," की मानसिक प्रक्रिया को आमंत्रित करता है, और फिर उस नए मान को वापस एक्स पर असाइन करता है।

x += 5 "5 से x बढ़ाएँ" के रूप में सोचा जा सकता है

तो, यह सिर्फ शॉर्टहैंड नहीं है, यह वास्तव में कार्यक्षमता को बहुत अधिक सीधे वर्णन करता है। जब कोड के gobs के माध्यम से पढ़ते हैं, तो इसे समझना बहुत आसान है।


32
+1, मैं पूरी तरह सहमत हूं। मैं एक बच्चे के रूप में प्रोग्रामिंग में शामिल हो गया, जब मेरा दिमाग आसानी से निंदनीय था, और फिर x = x + 5भी मुझे परेशान किया। जब मैंने बाद की उम्र में गणित में प्रवेश किया, तो इसने मुझे और भी परेशान किया। का उपयोग करना x += 5काफी अधिक वर्णनात्मक है और एक अभिव्यक्ति के रूप में बहुत अधिक समझ में आता है।
बहुपत्नी

44
वहाँ भी मामला है जहाँ चर का एक लंबा नाम है: reallyreallyreallylongvariablename = reallyreallyreallylongvariablename + 1... ओह, नहीं !!! टाइपो

9
@ मैट फेनविक: इसका एक लंबा परिवर्तनशील नाम नहीं है; यह किसी प्रकार की अभिव्यक्ति हो सकती है। उन लोगों को सत्यापित करने के लिए और भी कठिन होने की संभावना है, और यह सुनिश्चित करने के लिए पाठक को बहुत ध्यान देना होगा कि वे समान हैं।
डेविड थोरले

32
X = X + 5 एक हैक की तरह है जब आपका लक्ष्य 5 से एक्स को बढ़ाना है
जेफ़ओ

1
@Polynomial मुझे लगता है कि मैं एक बच्चे के रूप में भी x = x + 5 की अवधारणा में आया हूं। 9 साल पुराना है अगर मुझे सही से याद है - और यह मेरे लिए सही समझ में आता है और यह अभी भी मेरे लिए सही समझ में आता है और इसे x + = 5. के लिए पसंद करता है। पहला बहुत अधिक क्रिया है और मैं अवधारणा को और अधिक स्पष्ट रूप से कल्पना कर सकता हूं - यह विचार कि मैं x को पूर्व का मान मान रहा हूं (जो कुछ भी है) और फिर जोड़ रहा है 5. मुझे लगता है कि विभिन्न दिमाग अलग-अलग तरीकों से काम करते हैं।
क्रिस हैरिसन

48

कम से कम पायथन में , x += yऔर x = x + yपूरी तरह से अलग चीजें कर सकते हैं।

उदाहरण के लिए, यदि हम करते हैं

a = []
b = a

तो a += [3]में परिणाम होगा a == b == [3], जबकि a = a + [3]में परिणाम होगा a == [3]और b == []। यही है, +=वस्तु को जगह में संशोधित करता है (ठीक है, यह कर सकता है, आप अपनी __iadd__पसंद के अनुसार बहुत अधिक कुछ करने के लिए विधि को परिभाषित कर सकते हैं ), जबकि =एक नई वस्तु बनाता है और चर को बांधता है।

NumPy के साथ संख्यात्मक कार्य करते समय यह बहुत महत्वपूर्ण है , जैसा कि आप अक्सर किसी सरणी के विभिन्न भागों में कई संदर्भों के साथ समाप्त करते हैं, और यह सुनिश्चित करना महत्वपूर्ण है कि आप अनजाने में किसी ऐसे सरणी के भाग को संशोधित न करें जिसके अन्य संदर्भ हैं; या अनावश्यक रूप से सरणियों की नकल (जो बहुत महंगी हो सकती है)।


4
+1 के लिए __iadd__: ऐसी भाषाएं हैं, जहां आप एक उत्परिवर्ती डेटास्ट्रक्चर के लिए एक अपरिवर्तनीय संदर्भ बना सकते हैं, जहां operator +=परिभाषित किया गया है, उदाहरण के लिए scala: val sb = StringBuffer(); lb += "mutable structure"बनाम var s = ""; s += "mutable variable"। इसके अलावा डेटास्ट्रक्चर की सामग्री को संशोधित करता है जबकि बाद वाला परिवर्तनशील बिंदु को नया बनाता है।
उड़ान भेड़

43

इसे एक मुहावरा कहा जाता है । प्रोग्रामिंग मुहावरे उपयोगी हैं क्योंकि वे एक विशेष प्रोग्रामिंग निर्माण लिखने का एक सुसंगत तरीका है।

जब भी कोई लिखता x += yहै कि आप जानते हैं कि कुछ और जटिल ऑपरेशन के xद्वारा वृद्धि की जा रही है y(एक सर्वोत्तम अभ्यास के रूप में, आमतौर पर मैं अधिक जटिल संचालन और इन सिंटैक्स शॉर्टहैंड को नहीं मिलाता)। यह 1 से वृद्धि करते समय सबसे अधिक समझ में आता है।


13
x ++ और ++ x थोड़ा भिन्न है x + = 1 और एक दूसरे के लिए।
गैरी विल्बोबी

1
@ गैरी: ++xऔर x+=1सी और जावा के बराबर हैं (शायद सी # भी) हालांकि जरूरी नहीं कि सी ++ में ऐसा हो क्योंकि जटिल ऑपरेटर शब्दार्थ हैं। कुंजी यह है कि वे दोनों xएक बार मूल्यांकन करते हैं , एक-एक करके चर को बढ़ाते हैं, और एक परिणाम होता है जो मूल्यांकन के बाद चर की सामग्री है।
डोनाल्ड फेलो

3
@ डॉनल फेलो: पूर्वता अलग है, इसलिए ++x + 3ऐसा नहीं है x += 1 + 3। कोष्ठक करें x += 1और यह समान है। अपने आप से बयान के रूप में, वे समान हैं।
डेविड थॉर्नले

1
@DavidThornley: यह कहना मुश्किल है कि "वे समान हैं" जब वे दोनों अपरिभाषित व्यवहार करते हैं :)
को ऑर्बिट में लाइटनेस दौड़

1
अभिव्यक्तियों में से कोई भी ++x + 3, x += 1 + 3या (x += 1) + 3अपरिभाषित व्यवहार नहीं है (परिणामी मान "फिट बैठता है")।
जॉन हस्कल

42

@ पब्बी की बात को थोड़ा स्पष्ट करने के लिए, विचार करें someObj.foo.bar.func(x, y, z).baz += 5

+=ऑपरेटर के बिना , जाने के दो तरीके हैं:

  1. someObj.foo.bar.func(x, y, z).baz = someObj.foo.bar.func(x, y, z).baz + 5। यह केवल भयानक अतिरेक और लंबा नहीं है, यह भी धीमी है। इसलिए एक करना होगा
  2. एक अस्थायी चर का उपयोग करें tmp := someObj.foo.bar.func(x, y, z); tmp.baz = tmp.bar + 5:। यह ठीक है, लेकिन यह एक साधारण चीज के लिए बहुत शोर है। यह वास्तव में रनटाइम पर क्या होता है, के करीब है, लेकिन यह लिखने के लिए थकाऊ है और बस उपयोग +=करने से कंपाइलर / दुभाषिया को काम शिफ्ट हो जाएगा।

+=ऐसे और अन्य ऑपरेटरों का लाभ निर्विवाद है, जबकि उनका उपयोग करना केवल समय की बात है।


एक बार जब आप ऑब्जेक्ट श्रृंखला में 3 स्तर गहरे हो जाते हैं, तो आप 1 जैसे छोटे अनुकूलन के बारे में देखभाल करना बंद कर सकते हैं, और 2. जैसे शोर कोड। इसके बजाय, अपने डिज़ाइन पर एक बार और विचार करें।
डोरस

4
@ कोरस: मैंने जो अभिव्यक्ति चुनी, वह "जटिल अभिव्यक्ति" के लिए एक मनमाना प्रतिनिधि है। अपने सिर में किसी चीज़ से इसे बदलने के लिए बेझिझक, जिसके बारे में आप नाइटपिक नहीं करेंगे;)
back2dos

9
+1: यह इस अनुकूलन का सिद्धांत कारण है - यह हमेशा सही होता है, भले ही बाएं हाथ की अभिव्यक्ति कितनी जटिल हो।
S.Lott

9
एक टाइपो को वहां रखना एक अच्छा उदाहरण है कि क्या हो सकता है।
डेविड थोरले

21

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

साथ में

RidiculouslyComplexName += 1;

चूंकि इसमें केवल एक चर नाम शामिल है, आप सुनिश्चित हैं कि कथन क्या करता है।

साथ में RidiculouslyComplexName = RidiculosulyComplexName + 1;

हमेशा संदेह होता है कि दोनों पक्ष बिल्कुल समान हैं। क्या आपने बग को देखा? सब्सक्राइबर्स और क्वालिफायर मौजूद होने पर यह और भी खराब हो जाता है।


5
यह उन भाषाओं में और भी बदतर हो जाता है जहाँ असाइनमेंट स्टेटमेंट स्पष्ट रूप से चर बना सकते हैं, खासकर अगर भाषा केस-सेंसिटिव हो।
सुपरकैट

14

जबकि + = अंकन मुहावरेदार और कम है, ये कारण नहीं हैं कि यह पढ़ना आसान क्यों है। कोड को पढ़ने का सबसे महत्वपूर्ण हिस्सा अर्थ के लिए सिंटैक्स की मैपिंग है, और इसलिए सिंटैक्स प्रोग्रामर की विचार प्रक्रियाओं से जितना अधिक मेल खाता है, उतना अधिक पठनीय होगा (यही कारण है कि बॉयलरप्लेट कोड खराब है: यह विचार का हिस्सा नहीं है। प्रक्रिया, लेकिन कोड फ़ंक्शन बनाने के लिए अभी भी आवश्यक है)। इस मामले में, विचार "5 से वेतन वृद्धि x है", "x x का मान 5 x 5 नहीं है"।

ऐसे अन्य मामले हैं जहां पठनीयता के लिए एक छोटा संकेतन बुरा है, उदाहरण के लिए जब आप एक टर्नरी ऑपरेटर का उपयोग करते हैं जहां एक ifबयान अधिक उपयुक्त होगा।


11

कुछ जानकारी के लिए कि ये ऑपरेटर 'सी-शैली' भाषाओं में क्यों शुरू कर रहे हैं, के एंड आर 1 संस्करण (1978), 34 साल पहले के कुछ अंश हैं :

सुगमता से अलग, असाइनमेंट ऑपरेटरों को यह फायदा है कि वे लोगों के सोचने के तरीके से बेहतर मेल खाते हैं। हम कहते हैं कि "2 से i जोड़ें" या "2 से बढ़ाएँ i", "नहीं मैं लेते हैं, 2 जोड़ते हैं, तो परिणाम वापस i में डालते हैं।" इस प्रकार i += 2। इसके अलावा, जैसे एक जटिल अभिव्यक्ति के लिए

yyval[yypv[p3+p4] + yypv[p1+p2]] += 2

असाइनमेंट ऑपरेटर कोड को समझने में आसान बनाता है, क्योंकि पाठक को श्रमसाध्य तरीके से यह जांचने की ज़रूरत नहीं है कि दो लंबे अभिव्यक्ति वास्तव में एक ही हैं, या आश्चर्य है कि वे क्यों नहीं हैं। और एक असाइनमेंट ऑपरेटर कंपाइलर को अधिक कुशल कोड बनाने में भी मदद कर सकता है।

मुझे लगता है कि इस मार्ग से यह स्पष्ट है कि ब्रायन कर्निघन और डेनिस रिची (के एंड आर) का मानना ​​था कि यौगिक असाइनमेंट ऑपरेटरों ने कोड पठनीयता के साथ मदद की।

जब से K & R ने लिखा है, और जब से लोगों को कोड लिखना चाहिए, तब से बहुत कुछ बदल गया है या विकसित हुआ है, तो यह एक लंबा समय है। लेकिन यह प्रोग्रामर.स्टैकएक्सचेंज सवाल पहली बार है जब मैं किसी को कंपाउंड असाइनमेंट की पठनीयता के बारे में शिकायत करने की याद दिला सकता हूं, इसलिए मुझे आश्चर्य होता है कि क्या कई प्रोग्रामर उन्हें एक समस्या मानते हैं? फिर से, जैसा कि मैंने लिखा है कि इस प्रश्न में 95 अपवर्जन हैं, इसलिए हो सकता है कि लोग कोड पढ़ते समय उन्हें परेशान करते हों।


9

पठनीयता के अलावा, वे वास्तव में अलग-अलग चीजें करते हैं: +=दो बार अपने बाएं ऑपरेंड का मूल्यांकन करने की आवश्यकता नहीं है।

उदाहरण के लिए, दो बार expr = expr + 5निकाले जाएंगे expr(यह मानते हुए कि exprयह अशुद्ध है)।


सभी लेकिन अजीब संकलक के लिए, इससे कोई फर्क नहीं पड़ता। अधिकांश कंपाइलर स्मार्ट हैं expr = expr + 5expr += 5
जिनके

7
@vsz यदि exprसाइड इफेक्ट्स नहीं है।
पबि

6
@vsz: C में, यदि exprसाइड इफेक्ट्स हैं, तो उन साइड इफेक्ट्स को दो बार लागू expr = expr + 5 करना चाहिए
कीथ थॉम्पसन

@ पबबी: यदि इसके साइड इफेक्ट हैं, तो "सुविधा" और "पठनीयता" के बारे में कोई मुद्दा नहीं है, जो मूल प्रश्न का बिंदु था।
१०:१४ बजे

2
बेहतर उन "साइड इफेक्ट्स" बयानों के बारे में सावधान रहें। पढ़ता है और करने के लिए लिखते हैं volatileदुष्प्रभाव होते हैं, और x=x+5और x+=5जब एक ही साइड इफेक्ट xहैvolatile
MSalters

6

स्पष्ट गुणों के अलावा जिसे अन्य लोगों ने बहुत अच्छी तरह से वर्णित किया है, जब आपके पास बहुत लंबे नाम हैं तो यह अधिक कॉम्पैक्ट है।

  MyVeryVeryVeryVeryVeryLongName += 1;

या

  MyVeryVeryVeryVeryVeryLongName =  MyVeryVeryVeryVeryVeryLongName + 1;

6

यह संक्षिप्त है।

यह टाइप करने के लिए बहुत छोटा है। इसमें कम ऑपरेटर शामिल हैं। इसमें सतह का क्षेत्रफल कम और भ्रम की स्थिति कम होती है।

यह एक अधिक विशिष्ट ऑपरेटर का उपयोग करता है।

यह एक आकस्मिक उदाहरण है, और मुझे यकीन नहीं है कि वास्तविक संकलक इसे लागू करते हैं। x + = y वास्तव में एक तर्क और एक ऑपरेटर का उपयोग करता है और जगह में x को संशोधित करता है। x = x + y में x = z का एक मध्यवर्ती प्रतिनिधित्व हो सकता है जहाँ z x + y है। बाद वाले दो ऑपरेटरों, जोड़ और असाइनमेंट और एक अस्थायी चर का उपयोग करते हैं। एकल ऑपरेटर यह स्पष्ट करता है कि मूल्य पक्ष y के अलावा और कुछ नहीं हो सकता है और इसकी व्याख्या करने की आवश्यकता नहीं है। और सैद्धांतिक रूप से कुछ फैंसी सीपीयू हो सकते हैं जिनके पास एक प्लस-बराबर ऑपरेटर है जो एक प्लस ऑपरेटर और श्रृंखला में एक असाइनमेंट ऑपरेटर की तुलना में तेजी से चलता है।


2
सैद्धांतिक रूप से विद्वतापूर्ण। ADDकई CPUs पर निर्देश वेरिएंट कि रजिस्टर या स्मृति दूसरा योज्य के रूप में अन्य रजिस्टर, स्मृति या स्थिरांक का उपयोग करने पर सीधे संचालित है। सभी संयोजन उपलब्ध नहीं हैं (उदाहरण के लिए मेमोरी में मेमोरी जोड़ें), लेकिन उपयोगी होने के लिए पर्याप्त हैं। किसी भी दर पर, एक सभ्य ऑप्टिमाइज़र के साथ कोई भी कंपाइलर उसी कोड को जनरेट x = x + yकरना चाहेगा जिसके लिए वह करेगा x += y
ब्लर एफएल

4. "मैं वंचित हूं"।
मार्क कैनल्स

5

यह एक अच्छा मुहावरा है। यह तेज है या नहीं यह भाषा पर निर्भर करता है। सी में, यह तेज़ है क्योंकि यह दाहिने हाथ की ओर से चर बढ़ाने के लिए एक निर्देश का अनुवाद करता है। पायथन, रूबी, सी, सी ++ और जावा सहित आधुनिक भाषाएं सभी सेशन = वाक्य रचना का समर्थन करती हैं। यह कॉम्पैक्ट है, और आपको इसकी जल्दी आदत है। चूँकि आप इसे अन्य लोगों के कोड (OPC) में पूरी तरह से देखेंगे, आप इसे इस्तेमाल करने के लिए भी इस्तेमाल कर सकते हैं। यहाँ कुछ अन्य भाषाओं में होता है।

पायथन में, टाइपिंग x += 5अभी भी पूर्णांक ऑब्जेक्ट 1 के निर्माण का कारण बनता है (हालांकि यह एक पूल से निकाला जा सकता है) और पूर्णांक ऑब्जेक्ट का अनाथ 5 युक्त।

जावा में, यह टैटिट कास्ट होने का कारण बनता है। टाइप करने का प्रयास करें

int x = 4;
x = x + 5.2  // This causes a compiler error
x += 5.2     // This is not an error; an implicit cast is done.

आधुनिक अनिवार्य भाषाएं। में (शुद्ध) कार्यात्मक भाषाओं x+=5के रूप में कम अर्थ है x=x+5; उदाहरण के लिए हास्केल में उत्तरार्द्ध को 5 से बढ़ने का कारण नहीं है x- इसके बजाय यह एक अनंत पुनरावृत्ति लूप को जन्म देता है। उसके लिए एक आशुलिपि कौन चाहता है?
लेफ्टनैबाउट

जरूरी नहीं कि यह आधुनिक
कंपाइलरों के

की गति +=इतनी भाषा निर्भर नहीं है क्योंकि यह प्रोसेसर पर निर्भर है। उदाहरण के लिए, X86 एक दो पता वास्तुकला है, यह केवल +=मूल रूप से समर्थन करता है। इस तरह के एक बयान a = b + c;को संकलित किया जाना चाहिए a = b; a += c;क्योंकि बस कोई निर्देश नहीं है जो कि जोड़ के परिणाम को किसी एक सम्मन के स्थान पर रख सकता है। इसके विपरीत पावर आर्किटेक्चर एक तीन एड्रेस आर्किटेक्चर है, जिसमें विशेष कमांड नहीं होते हैं +=। इस आर्किटेक्चर पर, स्टेटमेंट a += b;और a = a + b;हमेशा एक ही कोड को संकलित करते हैं।
cmaster

4

+=जब आप एक संचयकर्ता के रूप में एक चर का उपयोग कर रहे हैं, जैसे ऑपरेटर बहुत उपयोगी होते हैं , यानी कुल चल रहा है:

x += 2;
x += 5;
x -= 3;

की तुलना में पढ़ने के लिए बहुत आसान है:

x = x + 2;
x = x + 5;
x = x - 3;

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


मेरे लिए यह बिल्कुल विपरीत है - पहला संस्करण स्क्रीन पर गंदगी की तरह है और दूसरा स्वच्छ और पठनीय है।
मिखाइल वी

1
अलग-अलग लोगों के लिए अलग-अलग स्ट्रोक, @MikhailV, लेकिन यदि आप प्रोग्रामिंग में नए हैं तो आप कुछ समय बाद अपना विचार बदल सकते हैं।
कालेब

मैं प्रोग्रामिंग के लिए इतना नया नहीं हूं, मुझे लगता है कि आपको बस लंबे समय से + = नोटेशन की आदत है और इसलिए आप इसे पढ़ सकते हैं। जो शुरू में इसे कोई अच्छा दिखने वाला वाक्यविन्यास नहीं बनाता है, इसलिए रिक्त स्थान से घिरा एक + ऑपरेटर उद्देश्यपूर्ण रूप से क्लीनर होता है + और = दोस्तों जो सभी मुश्किल से अलग हैं। ऐसा नहीं है कि आपका उत्तर गलत है, लेकिन किसी को खुद की आदत बनाने पर बहुत अधिक भरोसा नहीं करना चाहिए कि "यह पढ़ना कितना आसान है"।
मिखाइल V

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

1

इस पर विचार करो

(some_object[index])->some_other_object[more] += 5

D0 आप वास्तव में लिखना चाहते हैं

(some_object[index])->some_other_object[more] = (some_object[index])->some_other_object[more] + 5

1

अन्य उत्तर अधिक सामान्य मामलों को लक्षित करते हैं, लेकिन एक और कारण है: कुछ प्रोग्रामिंग भाषाओं में, इसे ओवरलोड किया जा सकता है; उदा । स्काला


छोटा स्काला सबक:

var j = 5 #Creates a variable
j += 4    #Compiles

val i = 5 #Creates a constant
i += 4    #Doesn’t compile

यदि कोई वर्ग केवल +ऑपरेटर को परिभाषित करता है , x+=yतो वास्तव में इसका शॉर्टकट है x=x+y

यदि कोई वर्ग ओवरलोड करता है +=, तो वे नहीं हैं:

var a = ""
a += "This works. a now points to a new String."

val b = ""
b += "This doesn’t compile, as b cannot be reassigned."

val c = StringBuffer() #implements +=
c += "This works, as StringBuffer implements “+=(c: String)”."

साथ ही, ऑपरेटरों +और +=(+ एक, ++ एक, एक ++, एक + बा + = ख कर रहे हैं विभिन्न ऑपरेटरों के साथ-साथ और न केवल इन); दो अलग-अलग ऑपरेटरों हैं उन भाषाओं में जहां ऑपरेटर ओवरलोडिंग उपलब्ध है, यह दिलचस्प स्थिति पैदा कर सकता है। जैसा कि ऊपर वर्णित है - यदि आप +जोड़ने के लिए ऑपरेटर को अधिभारित करेंगे , +=तो ध्यान रखें कि आपको अधिक भार भी उठाना होगा।


"यदि एक वर्ग केवल + ऑपरेटर को परिभाषित करता है, तो x + = y वास्तव में x = x + y का शॉर्टकट है।" लेकिन निश्चित रूप से यह दूसरे तरीके से भी काम करता है? C ++ में, इसे पहले परिभाषित करना +=और फिर a+b"की एक प्रति बनाना a, bइसका उपयोग करना +=, इसकी प्रति वापस करना" के रूप में परिभाषित करना बहुत आम है a
13:11 बजे लेफ्टरनैबाउट

1

इसे एक बार और केवल एक बार कहें: x = x + 1मैं दो बार 'x' कहता हूं।

लेकिन कभी मत लिखो, 'ए = बी + = 1' या हमें 10 बिल्ली के बच्चे, 27 चूहे, एक कुत्ता और एक हम्सटर को मारना होगा।


आपको चर का मान कभी नहीं बदलना चाहिए, क्योंकि इससे कोड को सही साबित करना आसान हो जाता है - कार्यात्मक प्रोग्रामिंग देखें। हालांकि अगर आप करते हैं, तो बेहतर है कि केवल एक बार ही कुछ न कहें।


"एक चर के मूल्य को कभी नहीं बदलें" कार्यात्मक प्रतिमान ?
पीटर मोर्टेंसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.