2009-07-31 22 views
5

निम्नलिखित सी कोड ले लो के आदेश (। कश्मीर & आर पीजी 77):सी #: समारोह मूल्यांकन (सी बनाम)

push(pop() - pop()); /* WRONG */ 

पुस्तक का कहना है कि जब से - और / विनिमेय नहीं ऑपरेटरों, कर रहे हैं आदेश जिसमें 2 pop फ़ंक्शंस का मूल्यांकन किया जाता है (स्पष्ट रूप से, सही परिणाम प्राप्त करने के लिए) ... और इस प्रकार आपको पहले चर के परिणाम को पहले एक चर में रखना होगा और फिर अंकगणित के साथ आगे बढ़ना होगा, जैसे:

op2 = pop(); 
push(op2 - pop()); 

जाहिर है इस वजह से संकलक गारंटी नहीं दे सकते का क्रम कार्यों का मूल्यांकन किया जाता (... क्यों?)


मेरा प्रश्न, सी # इस एक ही बात करता है है? जैसा कि, सी # के साथ काम करते समय मुझे इस तरह की चीज के बारे में चिंता करने की ज़रूरत है? और उस मामले के लिए, अन्य उच्च स्तर की भाषाओं में से कोई भी?

+0

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

+0

एफडब्ल्यूआईडब्ल्यू, आप यहां सी # विनिर्देश के लिए अपना रास्ता खोज सकते हैं: http://msdn.microsoft.com/en-us /library/ms228593.aspx यह अत्यधिक लंबा नहीं है, और बहुत कम नहीं है। :) –

उत्तर

11

सी # में यह सही करने के लिए छोड़ दिया जाता है: http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx


पुन: सी ++ क्रम

जाहिर है इस वजह से संकलक गारंटी नहीं दे सकते का क्रम कार्यों का मूल्यांकन किया जाता (.. । क्यों?)

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

1

सभी मामलों में मूल्यांकन का आदेश सी # में अच्छी तरह से परिभाषित किया गया है, और बाएं से दाएं है। सी # भाषा spec (§7.3) से:

अभिव्यक्ति में ऑपरेटरों के मूल्यांकन का क्रम ऑपरेटरों की प्राथमिकता और सहयोगीता (§7.2.1) द्वारा निर्धारित किया जाता है। अभिव्यक्ति में संचालन का मूल्यांकन बाएं से दाएं से किया जाता है। उदाहरण के लिए, एफ (i) + जी (i ++) * एच (i) में, विधि एफ को पुराने मान का उपयोग करके बुलाया जाता है, फिर विधि जी को पुराने मान के साथ बुलाया जाता है, और अंततः, विधि एच को कॉल किया जाता है i के नए मूल्य के साथ। यह ऑपरेटर प्राथमिकता से अलग और असंबंधित है

सी ++ के मामले में, यह नहीं है कि ऑर्डर को परिभाषित नहीं किया जा सका; यह है कि ऑर्डर को अपरिभाषित करने की इजाजत देने के लिए संकलक को कोड को बेहतर अनुकूलित करने की अनुमति मिलती है।

0

मुझे विश्वास है कि सी # में तर्क सूची का मूल्यांकन बाएं से दाएं क्रम में किया जाता है।

2

Fabulous Adventures In Coding: Precedence vs Associativity vs Order से:

एक और तरीका है इस पर गौर करने के लिए, कि सी # में शासन नहीं तो सब कुछ बीच में लिखना रिकर्सिवली नियम "बाईं ओर का मूल्यांकन लागू करने के लिए" कोष्ठकों पहले क्या "है, बल्कि है फिर दाएं तरफ का मूल्यांकन करें, फिर ऑपरेशन करें "।

0

रंग मुझे आश्चर्य है, लेकिन जाहिरा तौर पर सी # "सही" बात करता है, और बाएं से दाएं मूल्यांकन करता है:

void Main() 
{ 
    Console.WriteLine(Pop() - Pop()); // Prints -1 
} 

// Define other methods and classes here 
bool switchVar = true; 
int Pop() 
{ 
    int ret; 
    if (switchVar) 
     ret = 1; 
    else 
     ret = 2; 
    switchVar = !switchVar; 

    return ret; 
} 
+3

जब आप इस मामले में सही होते हैं, तो इन प्रकार के सवालों के जवाब देने के लिए 'यह मेरे लिए काम करता है' परीक्षणों के जाल में न पड़ें - यह काफी संभव है कि एक सी संकलक एक ही परिणाम देगा, लेकिन आप यह मानने के लिए गलत होंगे कि इसका मतलब है ** ** परिणाम देने के लिए ** था। –

+0

ध्यान में रखते हुए वास्तव में केवल दो सी # कंपाइलर्स (माइक्रोसॉफ्ट के सीएससी, और मोनो) हैं, हालांकि यह सी/सी ++ कंपाइलर्स के सही pleathora की तुलना में इतना बड़ा सौदा नहीं है। –

+2

पहला नहीं: कम से कम तीन सी # कंपाइलर्स हैं जिन्हें मैं जानता हूं (dotGNU)। दूसरा नंबर: सी # कंपाइलर्स की संख्या बहुत सीमित है, और उनके लिए कुछ सच है, कि कुछ-सत्य-सत्य केवल एक परीक्षण है, सबूत नहीं। मैं माइकल बुर के साथ पूरी तरह से सहमत हूं, "मेरे लिए काम करता है" शून्य है, भले ही यह इस मामले में एक बड़ा सौदा न हो। –

2

नहीं है, सी # एक ही बात नहीं करता है। यह सी सीमा के समान मूल्यांकन सीमाओं का उपयोग नहीं करता है, जहां सीमाओं के बीच निष्पादन का आदेश अनिर्धारित है। अभिव्यक्ति का मूल्यांकन बाएं से दाएं, जैसा कि आप उम्मीद करेंगे।

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

5

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

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

+2

प्रदर्शन बनाम भविष्यवाणी (जो कंप्यूटर ऑपरेशन लागत से प्रोग्रामर के वेतन से प्रमुख लागत की शिफ्ट के साथ बहुत कुछ करने के लिए बहुत कुछ है) के बीच महत्व की शिफ्ट के साथ, किसी ने यह भी टिप्पणी की है कि जिन मामलों में यह एक सार्थक अंतर बना दिया गया था, उन्हें पहले से ही अनुमति दी गई थी क्योंकि संकलक आसानी से सबूत कर सकता था कि कोई व्यवहार मतभेद नहीं था। – AProgrammer

1

पुस्तक कहती है कि - और/कम्यूटिव ऑपरेटर नहीं हैं, जिस क्रम में 2 पॉप फ़ंक्शंस का मूल्यांकन किया जाता है, वह आवश्यक है (जाहिर है, सही परिणाम प्राप्त करने के लिए) ... और इस प्रकार आपको इसे रखना होगा पहले एक चर में पहले फ़ंक्शन का परिणाम और फिर अंकगणितीय के साथ आगे बढ़ें।

यह बिल्कुल सही नहीं है। के & आर ने कम्यूटेटिव ऑपरेटरों (done away with in ANSI C) के पुनर्गठन की अनुमति दी। चूंकि सूक्ष्मता कम्यूटिव नहीं है, इसलिए यह पुन: व्यवस्थित नहीं है ... कम से कम उस नियम के तहत। जो संकलक का मतलब कर सकते हैं कॉल किसी भी क्रम में उन कार्यों (जब तक pop() - pop() का परिणाम पूरी तरह से push() कॉल करने से पहले मूल्यांकन किया जाता है -

(अन) सौभाग्य से, सी भी नहीं define the order of evaluation (a fairly small scope के बाहर) करता है)

कौन सा - इस मामले में, एक ही समस्या में परिणाम - लेकिन एक अलग कारण के लिए।

संबंधित मुद्दे