2012-04-16 17 views
10

प्रश्न यह है कि कोड क्या करता है, यह कार्य क्या करता है इसका वर्णन करना है।खराब लिखित कोड को समझना, दूसरे वर्ष सीएस पेपर

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

int g(int * y, unsigned size, int z) { 
    int tmp = y[0]; 
    // what type is unsigned size? Int I presume. Why would you add an int to an array of ints? 
    int * b = y + size; 
    y[0] = z; 
    // I have the most difficulty understanding the following. 
    while (1) if (*(--b)==z){y[0] = tmp; return b - y;}; 
    // are the following 3 lines ever even reached? 
    y[0] = tmp; 
    if (tmp == z) return 0; 
    else return -1; 
} 
+7

प्रश्न क्या है? –

+0

"किस प्रकार का हस्ताक्षर आकार है?" क्यों, 'हस्ताक्षरित', या, परिवार के नाम के साथ, 'हस्ताक्षरित int'। –

+18

इस प्रश्न को बंद करने से पूरी तरह से असहमत होना है। इसे 'होमवर्क 'चिह्नित किया गया है, यह स्पष्ट है, और ओपी के पास कोड के बारे में विशिष्ट प्रश्न हैं जो स्पष्ट रूप से निर्धारित किए गए हैं और पूरी तरह उत्तरदायी हैं। –

उत्तर

10
// what type is unsigned size? 

यह एक unsigned intsize कहा जाता है। आप इसे सामान्य पॉइंटर अंकगणित के रूप में एक सूचक में जोड़ते हैं - इस पॉइंटर को सरणी के बहुत अंत तक अग्रिम करें।

while (1) if (*(--b)==z){y[0] = tmp; return b - y;}; 

ठीक है, हम

  • while(1) = जबकि (सही), या 'हमेशा के पाश'
  • *(--b) पूर्व घटती ख हो गया और सरणी
  • की है कि सूचकांक से मूल्य पढ़ा है
  • यदि हमें z मिला है, तो पहले तत्व को उस मूल्य के साथ बदलें जिसे हम पढ़ते हैं और b-y लौटाते हैं - सरणी इंडेक्स के लिए पॉइंटर अंकगणितीय हम
पर हैं

यानी हम z के अंतिम उदाहरण को खोजने के लिए सरणी के माध्यम से पीछे की तरफ स्कैन कर रहे हैं और जिस सूचकांक को हमने पाया है उसे वापस कर रहे हैं। हम हमेशा क्योंकि हम अगर z सरणी में नहीं है पहला तत्व है, यानी वहाँ के रूप में डाल दिया सरणी में z मिलेगा तो हम लौट 0.

// are the following 3 lines ever even reached? 

नहीं, मैं ऐसा नहीं सोचता।

+2

कोड के साथ कोई समस्या है, हालांकि: यदि आकार == 0' है, तो लूप स्मृति स्थान से पीछे की ओर स्कैनिंग शुरू कर देगा _before_ 'y' का पहला तत्व। यह अच्छा नहीं हो सकता है। विशेष रूप से, इस मामले में कोई गारंटी नहीं है कि लूप सामान्य रूप से समाप्त हो जाएगा। लूप को तब भी समाप्त कर दिया जाएगा जब उसे कुछ यादृच्छिक स्मृति स्थान मिल जाए जो उसमें संग्रहीत 'z' का मान होता है या जब यह अवैध स्मृति पता को अस्वीकार करने का प्रयास करता है तो यह क्रैश हो जाएगा। –

+0

@ टेड हाँ, सच - 'आकार' के लिए कोई सीमा सत्यापन नहीं है। अच्छी जगह! – Rup

7

किस प्रकार अहस्ताक्षरित आकार

unsignedunsigned int के लिए कम है।

आप इनट्स की सरणी में एक int क्यों जोड़ देंगे?

पॉइंटर्स और सरणी एक ही चीज़ नहीं हैं। आपके द्वारा दिखाया गया कोड पॉइंटर्स का उपयोग कर रहा है, सरणी नहीं। int * b = y + size; लाइन के बाद, b एक सूचक है जो प्रविष्टियों को इंगित करता है जहां से y इंगित कर रहा है। उदाहरण के लिए, यदि size2, b तीसरे प्रविष्टि को इंगित करेंगे। ASCII कला:

+---------+ 
| entry 0 |<--- `y` points here 
| entry 1 | 
| entry 2 |<--- `b` points here if `size` is `2` 
| entry 3 | 
| entry 4 | 
+---------+ 

मैं सबसे कठिनाई निम्नलिखित को समझने की है।

while (1) if (*(--b)==z){y[0] = tmp; return b - y;};

पाश प्रविष्टियों में स्मृति y द्वारा की ओर इशारा किया एक size द्वारा की पहचान से पहले प्रवेश के साथ शुरू में लग रहा है। प्रवेश z को == है, तो यह tmp को y[0] सेट करता है और (सूचकांक, जिस पर प्रवेश मिला था रिटर्न सूचक अंकगणित का उपयोग करके, b - y जहां b ओर इशारा करते हुए और y की शुरुआत कर रहा है के बीच प्रविष्टियों की संख्या देता है। के बाद से --b decrements सूचक, पाश स्मृति के माध्यम से पिछड़े काम करता है।

निम्नलिखित 3 लाइनों कभी भी पहुँच रहे हैं?

सं return समारोह से बाहर हो जाएंगे जब पहली मिलान प्रवेश पाया जाता है, w जो शुरुआत में हो सकता है (y[0] को z पर सेट किया गया है)। चूंकि टेड हॉफ टिप्पणियों में बताते हैं, हालांकि, लूप शुरू हो जाएगा और शुरुआत से पहले जारी रहेगा (जहां y इंगित कर रहा है) यदि size0 प्रविष्टि पर है, जो अंत में प्रोग्राम को मेमोरी एक्सेस उल्लंघन के साथ विफल होने का कारण बनता है।

+0

धन्यवाद, यह बहुत उपयोगी है। इसके अलावा रुप ने बताया कि वाई [0] शुरुआत में ज़ेड पर सेट है, इसलिए जेड हमेशा पाएगा। –

+0

@ माइकगल्लाघर: दोह, उस बिट को याद किया। फिक्स्ड। –

+0

@ माइकगल्लाघर - 'z' नहीं मिलेगा यदि आकार == 0'। –

5

यह कोड पहली बात यह साबित करती है कि लेखक अक्षम है। लेकिन मैं असाइनमेंट के उस हिस्से को इकट्ठा करता हूं: अक्षम लोगों द्वारा लिखा कोड समझना।

शुरुआत के लिए:

  • unsigned एक वैध सी ++ प्रकार, unsigned int के लिए एक संकुचन है। यह आमतौर पर सबसे अच्छा टाला जाता है, जब तक कि आप थोड़ा सा काम नहीं कर लेते।

  • आपके कोड में कोई सरणी नहीं है; आप सूचक में एक पूर्णांक जोड़ रहे हैं। और उत्सुकता से पर्याप्त, [] सरणी अनुक्रमण नहीं है, लेकिन
    परिभाषित किया गया है कि a[b] बिल्कुल *(a+b) के बराबर है। (कम से कम प्रकारों में निर्माण के लिए।) आप को समझाने के लिए सी के बारे में एक पुस्तक खोजना चाहेंगे; सी ++ में, हम आम तौर पर std::vector का उपयोग करते हैं, ठीक से पॉइंटर अंकगणित के बारे में इस भ्रम से बचने के लिए।

भाग के लिए के रूप में आप समझने में परेशानी होती: शुरुआत के लिए, चलो चलो लिखने यह एक समझदार तरीके से:

while (true) { 
    -- b; 
    if (*b == z) { 
     y[0] = tmp; 
     return b - y; 
    } 
} 

केवल एक चीज है जो एक मुद्दा कारण चाहिए वापसी बयान है के बारे में : यह सूचक घटाव है; इस मामले में, y एक सरणी का पहला तत्व है (शेष कोड से निर्णय), b - y b द्वारा इंगित तत्व की अनुक्रमणिका की गणना करता है।

पॉइंटर्स का उपयोग शुद्ध obfuscation होगा, सिवाय इसके कि idiom सी में सर्वव्यापी है, और सी ++ में इटरेटर के साथ चलाया जाता है।

और आप सही हैं कि लूप के बाद कोड कभी निष्पादित नहीं किया जा सकता है; लूप को छोड़ने का एकमात्र तरीका return के माध्यम से है।

लेखन पाश होगी इसका एक अधिक स्वच्छ रास्ता:

int i = size; 
while (i != 0 && y[i - 1] != z) { 
    -- i; 
} 
y[0] = tmp; 
return i; 
+1

कोड का आपका अंतिम भाग काफी सही नहीं लगता है। एक के लिए, ब्रेसिज़ संतुलित नहीं हैं। यह मानते हुए कि इंडेंटिंग इच्छित ब्रिंगिंग को दर्शाती है, यह ओपी के कोड के बराबर नहीं है (विशेष रूप से जब 'आकार == 0')। –

+0

+1 सिर्फ "... चलिए इसे एक तरह से लिखते हैं ..." ;-) –

+0

@ टेडहोप मैं बंद ब्रेस भूल गया; मैं इसे ठीक कर दूंगा। मामले के लिए जब 'आकार == 0', मूल कोड उस मामले में व्यवहार को अपरिभाषित करता था, इसलिए मुझे नहीं लगता कि मुझे समान होने की आवश्यकता है :-)। –

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