2010-01-12 10 views
11

नीचे दिए गए strlen() फ़ंक्शन को केवल एक बार कॉल किया जाएगा (आगे तुलना के लिए संग्रहीत मूल्य के साथ); या यह हर बार तुलना की जाती है जब यह तुलना की जाती है?लूप के लिए इसमें कितनी बार स्ट्रेलन() कहा जाएगा?

for (i = 0; i < strlen(word); i++) 
{ /* do stuff */ } 

उत्तर

27

यह कार्यान्वयन-निर्भर है। आमतौर पर, इसे हर बार बुलाया जाता है, लेकिन, यदि संकलक देख सकता है कि word कभी नहीं बदलता है, और strlen एक शुद्ध कार्य (कोई साइड इफेक्ट्स) नहीं है, तो यह कॉल उठा सकता है।

देखें: http://underhanded.xcott.com/?page_id=15 इसका शोषण करने के एक प्रसिद्ध उदाहरण के लिए। :-)

+0

यह सही जवाब है ... वास्तव में, यह निर्भर करता है कि संकलक कितना चालाक है। – Noldorin

+0

उदाहरण में यह ''char *' पर किया गया था जिसका अर्थ है कि न तो सूचक और न ही डेटा की ओर इशारा किया गया था। क्या जीसीसी वास्तव में ऐसा कर रहा है? यह अविश्वसनीय रूप से खतरनाक लगता है। –

+0

@PP: मान लीजिए कि आपका 'शब्द' लूप के अंदर कहीं और नहीं पारित किया गया है (या केवल 'char const * 'लेने वाले फ़ंक्शन पर पास किया गया है), और आपका कोड सिंगल-थ्रेडेड माना जाता है, और इसमें कोई एलियासिंग शामिल नहीं है (या तो क्योंकि फ़ंक्शन यूनरी है, या क्योंकि पॉइंटर को 'प्रतिबंधित' घोषित किया गया है)। उस स्थिति में, मैं कहूंगा कि यह एक बहुत ही सुरक्षित धारणा है कि डेटा नहीं बदलेगा। –

8

यह पाश के हर यात्रा के लिए मूल्यांकन किया जाएगा (: यदि आवश्यक हो तोसंपादित करें)।

टैटू की तरह, अगर word लंबाई में बदलने वाला नहीं है, तो आप लूप से पहले strlen कॉल कर सकते हैं। लेकिन जैसा कि क्रिस ने कहा था, संकलक यह महसूस करने के लिए पर्याप्त हो सकता है कि word बदल नहीं सकता है, और डुप्लिकेट कॉल को ही हटा सकता है।

लेकिन अगर word लूप के दौरान लंबाई में बदल सकता है, तो निश्चित रूप से आपको लूप स्थिति में strlen कॉल रखना होगा।

+1

असल में, अधिकांश कंपाइलरों को इसे तब तक अनुकूलित करना चाहिए जब तक कि लूप बॉडी के भीतर 'शब्द' नहीं बदला जाता है या' अस्थिर 'के रूप में घोषित किया जाता है; हमेशा की तरह, आप यह देखने के लिए (डिस-) असेंबली की जांच कर सकते हैं कि क्या होता है ... – Christoph

+0

बह, यह पूर्ण उत्तर से बहुत दूर है। यदि संकलक आधा waqy सभ्य है, तो यह वास्तव में कॉल को अनुकूलित करना चाहिए ताकि यह केवल एक बार मूल्यांकन किया जा सके। – Noldorin

+0

यह सच है, एक संकलक प्रत्येक बार कॉल करने और कॉल करने से बचने के लिए पर्याप्त स्मार्ट हो सकता है। –

0

स्ट्रेल प्रदान की गई स्ट्रिंग की लंबाई जांचता है। जिसका मतलब है कि यदि लंबाई 10 है। आपका पुनरावृत्ति तब तक जारी रहेगा जब तक कि मैं नीचे 10 से नीचे हूं।

और उस स्थिति में। 10 बार।

Read more about loops

+0

-1 क्योंकि स्ट्रिंग को लूप के भीतर संशोधित किया जा सकता है और इस प्रकार 'strlen' को अनंत काल कहा जा सकता है (माना जाता है कि संकलक' strlen() 'के परिणाम को कैश नहीं कर रहा है)। –

+0

इसके अतिरिक्त उदाहरण में कोई गारंटी नहीं थी कि 'i' को संशोधित नहीं किया जा रहा था। –

+0

यह डाउन-वोट करने का एक बेवकूफ कारण है। यह मानते हुए कि वह स्ट्रिंग के साथ छेड़छाड़ नहीं करता है। यह एक बहुत ही बुनियादी व्याख्या थी कि यह पहली नजर में कैसा लगेगा और फिर एक संदर्भ कैसे काम करता है। –

6

मैं कभी कभी कोड है कि के रूप में ...

for (int i = 0, n = strlen(word); i < n; ++i) { /* do stuff */ } 

... ताकि strlen केवल एक बार कहा जाता है (प्रदर्शन में सुधार करने के लिए) हूँ।

0

इसे प्रत्येक पुनरावृत्ति के लिए बुलाया जाएगा। निम्नलिखित कोड केवल एक बार स्ट्रेलन फ़ंक्शन को कॉल करता है।

for (i = 0, j = strlen(word); i < j i++) 
{ /* do stuff */ } 
1

बार strlen(word) निष्पादित किया जाता है की संख्या पर निर्भर:

  1. तो word (डेटा स्थिर है) निरंतर रूप में घोषित किया जाता है
  2. या संकलक पता लगा सकते हैं कि word नहीं बदला है।

निम्न उदाहरण लें:

char word[256] = "Grow"; 

for (i = 0; i < strlen(word); ++i) 
{ 
    strcat(word, "*"); 
} 

इस उदाहरण में, चर word पाश के भीतर संशोधित किया गया है:
0) "आगे बढ़ें" - लंबाई == 4
1) "आगे बढ़ें * "- लंबाई == 5
2)" आगे बढ़ें ** "-, लंबाई == 6

हालांकि, संकलक strlen कॉल बाहर कारक बन सकते हैं तो यह एक बार कहा जाता है यदि varia ble word निरंतर रूप में घोषित किया जाता है:

void my_function(const char * word) 
{ 
    for (i = 0; i < strlen(word); ++i) 
    { 
    printf("%d) %s\n", i, word); 
    } 
    return; 
} 

समारोह घोषणा की है कि चर word निरंतर डेटा है (वास्तव में, निरंतर डेटा के लिए सूचक)। इस प्रकार लंबाई नहीं बदलेगी, इसलिए संकलक केवल strlen को कॉल कर सकता है।

संदेह में, आप हमेशा अनुकूलन स्वयं कर सकते हैं, जो इस मामले में अधिक पठनीय कोड पेश कर सकता है।

+3

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

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