2011-08-30 13 views
6

सवाल निम्नलिखित कोड मुझे थोड़ी उलझन:सी संकेत

char * strcpy(char * p, const char * q) { 
while (*p++=*q++); 
//return 
} 

यह strcpy समारोह की एक छीन कार्यान्वयन है। इस कोड से, हम देखते हैं कि पॉइंटर पी और क्यू अवरुद्ध किए गए हैं, डीईआर कॉन्फ्रेंस किए गए हैं और क्यू को तब तक असाइन किया जाता है जब तक कि \ 0 char तक नहीं पहुंच जाता है। जो चीज मुझे भ्रमित करती है वह लूप के पहले पुनरावृत्ति है। जहां तक ​​मुझे पता है, सरणी का सूचक सूचक सरणी के पहले तत्व को इंगित करता है। इस कोड में, असाइनमेंट होने से पहले पॉइंटर को बढ़ाया जाता है (दाएं?), इसलिए मेरी समझ से पहले तत्व को कभी भी पी को असाइन नहीं किया जाना चाहिए (क्योंकि पोस्ट increment असाइनमेंट से पहले होता है), लेकिन यह करता है और मैं पीछे जादू को समझ नहीं पा रहा हूं। किसी भी तरह की व्याख्या करने के लिए पर्याप्त क्यों? :-)

धन्यवाद

+6

पोस्ट/प्री की आपकी परिभाषाएं पीछे की ओर प्रतीत होती हैं। पोस्ट = बाद, पूर्व = पहले। यहां वृद्धि के बाद से पता चलता है कि पहला चरित्र कॉपी किया जाएगा, तो पॉइंटर बढ़ाया जाएगा। – Marlon

+0

क्यों सी ++ टैग (और शीर्षक)? यह एक सी पुस्तकालय समारोह है। –

+1

मुझे पूरी तरह वैध सी ++ कोड की तरह दिखता है, @ पॉल। तो क्यों नहीं * सी ++ टैग? –

उत्तर

9

क्योंकि ++ चर के बाद, वे वृद्धि नहीं कर रहे हैं तक के बाद अभिव्यक्ति का मूल्यांकन किया जाता है। यही कारण है कि यह पोस्ट-वृद्धि ऑपरेटर है; पूर्व-वृद्धि प्रीफिक्स्ड (++ पी) है। * ++ पी दूसरे स्थान पर लिखता है, * पी ++ पहले लिखता है।

+1

ओह एसएच *** टी, मुझे वास्तव में सोने की जरूरत है: एस। धन्यवाद केविन: एस – Davita

1

अभिव्यक्ति (* q ++) के दाईं ओर का मूल्यांकन * पी ++ से पहले किया जाएगा, और दोनों ही असाइनमेंट के बाद ही बढ़ाए जाएंगे।

बाईं ओर दिए गए कथन को पढ़ें और पोस्ट-वृद्धि (++ क्यू के बजाय q ++) याद रखें लाइन में बाकी सब कुछ हल हो जाने के बाद होता है।

*q --> dereference q 
= --> assign the value 
*p --> to p 

दोनों वृद्धि।

इसे तब तक करें जब तक q q q का तत्व = 0 नहीं लेता है, जब यह शून्य टर्मिनेटर तक पहुंच जाता है।

2

p++ पॉइंटर p के बाद में वृद्धि कर रहा है। इसलिए p का वर्तमान मूल्य p से पहले पर निर्भरता ऑपरेटर द्वारा संचालित किया जाता है।

आपका तर्क सही इस प्रकार किया गया है होता अगर while पाश लिखा गया था:

while (*++p=*++q); 

इस मामले वेतन वृद्धि अपसंदर्भन से पहले क्या होगा में।

2

नहीं, असाइनमेंट के बाद वृद्धि होती है।

यदि यह *(++p) था, तो सूचक p बढ़ाया जाएगा और उसके बाद असाइन किया जाएगा।

1

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

यह दूसरी तरह के आसपास होता है। *p पर मान *q पर सेट है, तो दोनों पॉइंटर्स बढ़े हैं।

जब आप int foo = bar++ है के बाद foo स्थापित किया गया है वेतन वृद्धि होता है।यह पहली बार हो आप क्या करेंगे करवाने के लिए int foo = ++bar

+1

@ मार्लोन, आपने मेरी पोस्ट क्यों संपादित की? आपने अर्थ को उलटा कर दिया है, जो गलत है। * पी * क्यू पर सेट है, दूसरी तरफ नहीं जब तक कि मेरा पूरा मस्तिष्क भाग्य न हो और कुछ खो जाए। – Alex

1

q++ का मूल्य क्ष
++q का मूल्य q+1

1

while पाश की हालत के बाद वेतन वृद्धि प्रदर्शन कर रहा है है। इसके तुल्य:

while (true) { 
    char* old_p = p; 
    const char* old_q = q; 

    ++p; // or p++; 
    ++q; // or q++; 

    *old_p = *old_q; 
    if (*old_p == '\0') 
     break; 
} 
+0

बिल्कुल सही नहीं है, क्योंकि आपका समय (* पी) अगले चरित्र को देख रहा है, न कि सिर्फ एक कॉपी किया गया है। – Neil

+0

@ नील - आह, मूर्ख मुझे। पकड़ने के लिए धन्यवाद! – Dawson

2

भाव x++ और ++x दोनों एक परिणाम (मान) और एक पक्ष प्रभाव है।

x++ अभिव्यक्ति के परिणाम x का वर्तमान मान है। पक्ष प्रभाव कि x की सामग्री है द्वारा 1.

परिणाम अभिव्यक्ति ++x की बढ़ती है, x प्लस 1. के वर्तमान मूल्य पक्ष प्रभाव ऊपर के रूप में ही है।

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

x = 1; 
y = 2; 
z = ++x + y++; 

कोई गारंटी नहीं कि x की सामग्री को पहले अभिव्यक्ति y++ मूल्यांकन किया जाता है संशोधित किया जाएगा, या यहां तक ​​कि इससे पहले कि ++x + y++ का परिणाम (z को सौंपा गया है न = है और न ही + ऑपरेटरों परिचय दिया है अनुक्रम बिंदु)। अभिव्यक्ति++x 2 का मूल्यांकन करता है, लेकिन यह संभव है कि परिवर्तनीय x में z के बाद मान 2 शामिल नहीं हो सकता है।

यह याद रखना महत्वपूर्ण है कि x++ + x++ जैसे अभिव्यक्तियों का व्यवहार स्पष्ट रूप से भाषा मानक द्वारा अपरिभाषित है; भविष्यवाणी करने का कोई अच्छा (अच्छा) तरीका नहीं है कि अभिव्यक्ति का नतीजा क्या होगा, या मूल्यांकन के बाद x का मूल्य क्या होगा। इसलिए *p++ की तरह भाव *(p++) (यानी, आप अभिव्यक्ति p++ के परिणाम के * ऑपरेटर लागू कर रहे हैं) के रूप में पार्स कर रहे हैं

पोस्टफिक्स ऑपरेटरों, एकल ऑपरेटरों की तुलना में अधिक पूर्वता है। फिर, p++ अभिव्यक्ति का परिणाम p का वर्तमान मान है, इसलिए while (*p++=*q++); पहला तत्व नहीं छोड़ता है।

ध्यान दें कि ऑटोइनक्रिकमेंट/कमी ऑपरेटर के लिए ऑपरेशन lvalue होना चाहिए (अनिवार्य रूप से, एक अभिव्यक्ति जो स्मृति स्थान को संदर्भित करती है जैसे स्मृति को पढ़ या संशोधित किया जा सकता है)। अभिव्यक्ति का परिणाम x++ या ++x एक lvalue नहीं है, इसलिए आप ++x++ या (x++)++ या ++(++x) जैसी चीजें नहीं लिख सकते हैं।आप कुछ लिख सकते हैं जैसे ++(*p++) (p++ एक लाभा नहीं है, लेकिन *p++ है), हालांकि शायद आपको अपना कोड पढ़ने वाले किसी भी व्यक्ति द्वारा थप्पड़ मार दिया जाएगा।

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