2010-04-16 12 views
6

एक किताब मैं वहाँ पढ़ रहा हूँ में कोड का एक टुकड़ा है:चार * लूप के लिए स्थिति कैसे हो सकती है?

string x; 
size_t h=0; 
for(const char* s=x.c_str();*s;++s) 
    h=(h*17)^*s; 

इस कोड के बारे में, मैं दो प्रश्न हैं:

  1. कैसे *s एक शर्त हो सकता है? इसका क्या मतलब है?

  2. "h=(h*17)^*s" का अर्थ क्या है?

मदद के लिए धन्यवाद!

+2

एक हैशिंग एल्गोरिदम की तरह दिखता है। –

उत्तर

16
  1. कैसे * एक शर्त हो सकता है? इसका क्या मतलब है?

इसका मतलब है ", जबकि मूल्य s द्वारा की ओर इशारा किया शून्य नहीं है।" सी तारों को निरस्त कर दिया जाता है, इसलिए c_str() द्वारा लौटाई गई स्ट्रिंग में अंतिम वर्ण शून्य वर्ण (\0 होगा, जो सभी बिट्स शून्य द्वारा दर्शाया गया है)।

  1. "एच = (एच * 17)^* एस" क्या मतलब है?

यह रों 17 द्वारा h तो xor यह मान के साथ s द्वारा की ओर इशारा किया गुणा।

+2

दिए गए कोड में एक सूक्ष्म बग हो सकता है। शून्य चरित्र स्ट्रिंग :: स्ट्रिंग्स में एक वैध वर्ण है। दिए गए फ़ंक्शन को स्ट्रिंग को पूरी तरह से संसाधित नहीं किया जाएगा यदि यह इसके इनपुट के बारे में सच है। – stonemetal

3
  • *s स्ट्रिंग समाप्ति वर्ण '\ 0' का पता लगाता है
  • (h*17)^*s यह क्या कहते हैं: ज 17 और चरित्र द्वारा बताया की सामग्री के साथ XOR एड से गुणा। एक साधारण हैशिंग funciton लगता है।
+0

सी और सी ++ –

+0

दोनों के बाद से हमारे पास सी में 'स्ट्रिंग' कब है? – IVlad

+0

@http: //stackoverflow.com/users/197788/ken-bloom क्षमा करें, मैंने टिप्पणी से पहले ही संपादित किया है;) – baol

1
  1. *s वह वर्ण है जो s वर्तमान में इंगित करता है, इसलिए यह एक चरित्र है। for लूप तब तक चलता है जब तक यह \0 बन जाता है, जिसका अर्थ है कि स्ट्रिंग समाप्त होने तक।
  2. hh * 17xored का मान (AScii मान) वर्ण *s के साथ असाइन किया गया है।

Here पॉइंटर्स के बारे में एक अच्छा ट्यूटोरियल है।

1

1) हालत की जाँच में *s कि क्या *s!=NUL

2) h=(h*17)^*s 17 से गुणा h का तात्पर्य और साथ मूल्य द्वारा की ओर इशारा किया exclusive-OR कार्रवाई करने।

1

सी और सी ++, true और false गैर-शून्य, और शून्य के समान हैं।तो if (1){ के तहत कोड हमेशा निष्पादित होगा, जैसा कि if (-1237830){ के तहत कोड होगा, लेकिन if (0){ हमेशा false है।

इसी प्रकार, यदि सूचक का मान हमेशा 0 है, तो स्थिति false जैसा ही है, यानी आप लूप से बाहर निकलेंगे।

3

सी (या सी ++) में किसी भी मूल्य को "बूलियन" के रूप में उपयोग किया जा सकता है। 0 का एक संख्यात्मक मान, या एक पूर्ण सूचक, का अर्थ है "झूठा"। कुछ और मतलब "सत्य" है।

यहां, *s "वर्तमान में वर्णित वर्ण मान s" है। लूप बंद हो जाता है अगर वह वर्ण 0 है (ASCII एन्कोडिंग 48 के साथ "0" अंक नहीं, लेकिन ASCII एन्कोडिंग 0 के साथ बाइट)। यह परंपरागत रूप से "एंड-ऑफ-स्ट्रिंग" मार्कर है, इसलिए स्ट्रिंग के अंत तक पहुंचने पर लूप रुक जाता है।

"^" बिटवाई एक्सओआर ऑपरेटर है। बाएं "*" एक सादा गुणा है, जबकि अन्य "*" पॉइंटर ड्रेफरेंस ऑपरेटर है (यानी वह चीज जो सूचक s लेती है और उस सूचक को इंगित करती है जिस पर यह सूचक इंगित करता है)। "=" असाइनमेंट है। संक्षेप में, h का मान 17 से गुणा किया गया है, फिर चरित्र के साथ XORed s द्वारा इंगित किया गया है, और परिणाम h का नया मान बन जाता है।

3

के रूप में अन्य उत्तर समझा दिया है, बुनियादी जवाब यह है कि किसी भी अभिव्यक्ति है कि 0 का मूल्यांकन सी या C++ एक 'असत्य' शर्त के रूप में व्याख्या हो जाता है, और जब s सूचक की अशक्त समाप्ति चरित्र तक पहुँच जाता है *s 0 मूल्यांकन करेंगे स्ट्रिंग ('\ 0')।

आप *s != 0 अभिव्यक्ति का समतुल्य रूप से उपयोग कर सकते हैं, और कुछ डेवलपर तर्क दे सकते हैं कि इसका उपयोग किया जाना चाहिए, यह राय देकर कि 'पूर्ण' अभिव्यक्ति अधिक स्पष्ट है। चाहे आप उस राय से सहमत हों या नहीं, आपको terse विकल्प के उपयोग को समझने में सक्षम होना चाहिए, क्योंकि इसका उपयोग आमतौर पर सी/सी ++ कोड में किया जाता है। आप इन अभिव्यक्तियों में बहुत कुछ आ जाएंगे, भले ही आप अधिक स्पष्ट तुलना का उपयोग करना पसंद करते हैं।

मानक से अधिक कठोर स्पष्टीकरण (किसी कारण से मैं इसे चर्चा में लाने के लिए मजबूर महसूस करता हूं, भले ही यह वास्तव में कुछ भी नहीं बदलता या स्पष्ट नहीं करता है। असल में, यह शायद कुछ लोगों के लिए अनावश्यक रूप से चीजों को हल करेगा - यदि आपको इस स्तर की सामान्य स्तर पर पहुंचने की परवाह नहीं है, तो आपको अभी बैक बटन पर क्लिक करके बिल्कुल कुछ भी याद नहीं होगा ...):

सी में, *s अभिव्यक्ति मानक कॉल 'अभिव्यक्ति में है -2 'for कथन का, और यह विशेष for कथन उदाहरण for कथन की मानक परिभाषा का लाभ उठा रहा है। for बयान किसी भी यात्रा के बयान के शब्दों के बीच एक 'यात्रा बयान' के रूप में वर्गीकृत किया गया है, और (6.8.5/4 "पुनरावृत्ति बयान") कर रहे हैं:

एक यात्रा बयान एक बयान के पाश शरीर कहा जाता है का कारण बनता है बार-बार निष्पादित किया जब तक नियंत्रित अभिव्यक्ति 0.

के बराबर तुलना 'अभिव्यक्ति -2' for बयान का हिस्सा के बाद से नियंत्रित अभिव्यक्ति है, इसका मतलब है कि for पाश बार-बार निष्पादित करेंगे जब तक *s के बराबर तुलना 0।

सी ++ मानक चीजों को थोड़ा अलग तरीके से परिभाषित करता है (लेकिन उसी परिणाम के साथ)। सी ++ में, for बयान while बयान के संदर्भ में परिभाषित किया गया है, और while बयान की हालत हिस्सा यात्रा (6.5.1/1 ", जबकि बयान") को नियंत्रित करता है:

का मूल्य तक हालत false

सी ++ मानक में इससे पहले हो जाता है, निम्नलिखित वर्णन करता है कि भाव bool (4.12 "बूलियन रूपांतरण") में बदल रही हैं:

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

मानक में समान शब्द (दोनों भाषाओं में) सभी चयन या पुनरावृत्ति विवरणों की नियंत्रण अभिव्यक्ति/स्थिति पर लागू होता है। यह सारी भाषा-लॉयरेसी इस तथ्य को उबालती है कि यदि अभिव्यक्ति 0 का मूल्यांकन करती है तो यह झूठी मूल्यांकन के समान है (शब्द की अंग्रेजी भावना में, क्योंकि सी में अंतर्निहित false कीवर्ड नहीं है)।

और यह सरल अवधारणा का लंबा, भ्रमित स्पष्टीकरण है।

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