यदि लूप स्थिति में उपयोग किया जाता है, तो क्या स्ट्रेलेन की गणना कई बार की जाएगी?


109

मुझे यकीन नहीं है कि यदि निम्न कोड अनावश्यक गणना का कारण बन सकता है, या यह संकलक-विशिष्ट है?

for (int i = 0; i < strlen(ss); ++i)
{
    // blabla
}

विल strlen()जब हर बार की गणना की जा iबढ़ जाती है?


14
मुझे लगता है कि एक परिष्कृत अनुकूलन के बिना यह अनुमान लगाया जा सकता है कि 'ss' लूप में कभी नहीं बदलता है, तो हाँ। संकलन करने के लिए सबसे अच्छा है, और देखने के लिए विधानसभा को देखें।
मर्कोवा

6
यह संकलक पर निर्भर करता है, अनुकूलन स्तर पर और ssलूप के अंदर आप (हो सकता है) क्या करते हैं ।
हिस्टोरो इलिव

4
यदि संकलक यह साबित कर सकता है कि ssकभी संशोधित नहीं हुआ है, तो यह गणना को लूप से बाहर निकाल सकता है।
डैनियल फिशर

10
@ माइक: "कंपाइल-टाइम विश्लेषण की आवश्यकता है कि वास्तव में स्ट्रैलेन क्या करता है" - स्ट्रलेन शायद एक आंतरिक है, इस मामले में ऑप्टिमाइज़र को पता है कि यह क्या करता है।
स्टीव जेसप

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

जवाबों:


138

हां, strlen()प्रत्येक पुनरावृत्ति पर मूल्यांकन किया जाएगा। यह संभव है कि आदर्श परिस्थितियों में, ऑप्टिमाइज़र यह कटौती करने में सक्षम हो सकता है कि मूल्य नहीं बदलेगा, लेकिन मैं व्यक्तिगत रूप से उस पर भरोसा नहीं करूंगा।

मैं कुछ करूँगा

for (int i = 0, n = strlen(ss); i < n; ++i)

या संभवतः

for (int i = 0; ss[i]; ++i)

जब तक स्ट्रिंग पुनरावृत्ति के दौरान लंबाई बदलने वाली नहीं है। यदि यह हो सकता है, तो आपको strlen()हर बार या तो कॉल करना होगा, या अधिक जटिल तर्क के माध्यम से संभालना होगा।


14
यदि आप जानते हैं कि आप स्ट्रिंग में हेरफेर नहीं कर रहे हैं, तो दूसरा बहुत बेहतर है क्योंकि यह अनिवार्य रूप से लूप है जो किसी भी तरह से किया जाएगा strlen
मिली

26
@alk: यदि स्ट्रिंग छोटा हो सकता है, तो ये दोनों गलत हैं।
माइक सेमोर

3
@alk: यदि आप स्ट्रिंग बदल रहे हैं, तो एक लूप के लिए संभवतः प्रत्येक वर्ण पर पुनरावृति करने का सबसे अच्छा तरीका नहीं है। मुझे लगता है कि इंडेक्स काउंटर को प्रबंधित करने के लिए लूप अधिक प्रत्यक्ष और आसान है।
मिली

2
आदर्श परिस्थितियों में लिनक्स के तहत जीसीसी के साथ संकलन शामिल है, जहां संकलक को कई कॉलों को खत्म करने की अनुमति strlenके रूप में चिह्नित किया __attribute__((pure))गया है। जीसीसी गुण
डेविड रोड्रिगेज -

6
दूसरा संस्करण आदर्श और सबसे मुहावरेदार रूप है। यह आपको केवल दो बार के बजाय केवल एक बार स्ट्रिंग के ऊपर से गुजरने की अनुमति देता है, जिसमें लंबे तारों के लिए बेहतर प्रदर्शन (विशेष रूप से कैश सुसंगतता) होगा।
आर .. गिटहब स्टॉप हेल्पिंग ICE

14

हां, हर बार जब आप लूप का उपयोग करते हैं। फिर यह हर बार स्ट्रिंग की लंबाई की गणना करेगा। तो इसका उपयोग इस तरह से करें:

char str[30];
for ( int i = 0; str[i] != '\0'; i++)
{
//Something;
}

उपर्युक्त कोड में str[i]केवल स्ट्रिंग में iएक बार में एक चक्र शुरू होने पर एक विशेष वर्ण को सत्यापित करता है, इस प्रकार यह कम मेमोरी लेगा और अधिक कुशल होगा।

अधिक जानकारी के लिए इस लिंक को देखें।

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

char str[];
for ( int i = 0; i < strlen(str); i++)
{
//Something;
}

3
मैं "[यह] अधिक कुशल है" से सहमत हो सकता हूं, लेकिन कम मेमोरी का उपयोग कर सकता हूं? केवल मेमोरी उपयोग अंतर जिसे मैं सोच सकता हूं कि कॉल के दौरान कॉल स्टैक में होगा strlen, और यदि आप उस तंग को चला रहे हैं, तो आपको शायद कुछ अन्य फ़ंक्शन कॉल के साथ ही
समाप्त करने के

@ MichaelKjörling यदि आप "स्ट्रलेन" का उपयोग करते हैं, तो एक लूप में इसे हर बार लूप के चलने पर पूरे स्ट्रिंग को स्कैन करना पड़ता है, जबकि उपरोक्त कोड में "str [ix]", यह केवल एक तत्व को प्रत्येक चक्र के दौरान स्कैन करता है। लूप जिसका स्थान "ix" द्वारा दर्शाया गया है। इस प्रकार यह "स्ट्रैलेन" की तुलना में कम मेमोरी लेता है।
कोडेक्सटर

1
मुझे यकीन नहीं है कि वास्तव में बहुत कुछ समझ में आता है। स्ट्रलेन का एक बहुत ही भला कार्यान्वयन कुछ ऐसा होगा int strlen(char *s) { int len = 0; while(s[len] != '\0') len++; return len; }जो आपके जवाब में कोड में बहुत कुछ कर रहा है। मैं यह तर्क नहीं दे रहा हूं कि दो बार की बजाय एक बार स्ट्रिंग पर पुनरावृत्ति करना अधिक समय लेने योग्य है , लेकिन मैं एक या दूसरे को अधिक या कम मेमोरी का उपयोग करके नहीं देखता हूं। या आप स्ट्रिंग लंबाई को धारण करने के लिए उपयोग किए जाने वाले चर का उल्लेख कर रहे हैं?
एक CVn

@ MichaelKjörling कृपया उपरोक्त संपादित कोड और लिंक देखें। और मेमोरी के लिए- हर बार जब लूप रन करता है तो हर एक वैल्यू जो इटेरेट्स मेमोरी में स्टोर होती है और 'स्ट्रैलेन' के मामले में क्योंकि यह पूरे स्ट्रिंग को बार-बार गिनता है और इसे स्टोर करने के लिए अधिक मेमोरी की आवश्यकता होती है। और इसलिए भी कि जावा के विपरीत, C ++ में कोई "कचरा संग्राहक" नहीं है। फिर मैं गलत भी हो सकता हूं। सी ++ में "कचरा कलेक्टर" की अनुपस्थिति के बारे में लिंक देखें ।
कोडेक्सटर

1
@ aashis2s कूड़े के संग्रहकर्ता की कमी केवल एक भूमिका निभाती है जब ढेर पर वस्तुओं का निर्माण होता है। स्टैक पर मौजूद वस्तुएँ स्कोप और समाप्त होते ही नष्ट हो जाती हैं।
इक्के

9

एक अच्छा संकलक हर बार इसकी गणना नहीं कर सकता है, लेकिन मुझे नहीं लगता कि आप सुनिश्चित हो सकते हैं, कि हर संकलक ऐसा करता है।

इसके अलावा, संकलक को जानना होगा, वह strlen(ss)नहीं बदलता है। यह केवल सच है अगर लूप ssमें नहीं बदला जाता forहै।

उदाहरण के लिए, यदि आप पर केवल पढ़ने के लिए समारोह का उपयोग ssमें forपाश लेकिन नहीं घोषित करते ss-parameter के रूप में const, संकलक भी है कि पता नहीं कर सकते हैं ssपाश में बदल गया है और गणना करने के लिए है नहीं है strlen(ss)कि हर चरण में।


3
+1: न केवल लूप ssमें बदला जाना चाहिए for; लूप नामक किसी फ़ंक्शन द्वारा इसे एक्सेस नहीं किया जा सकता है और इसे बदला जाना चाहिए (या तो क्योंकि यह एक तर्क के रूप में पारित हो जाता है, या क्योंकि यह एक वैश्विक चर या फ़ाइल-स्कोप वैरिएबल है)। कॉन्स्ट-क्वालिफिकेशन भी एक कारक हो सकता है।
जोनाथन लेफ़लर

4
मुझे लगता है कि यह बहुत कम संभावना है कि संकलक यह जान सके कि 'ss' बदलता नहीं है। '
Ss

जोनाथन सही है, कंपाइलर के लिए एक स्थानीय कास्ट स्ट्रिंग एकमात्र तरीका हो सकता है, यह सुनिश्चित करने के लिए कि 'ss' को बदलने का कोई तरीका नहीं है।
मर्कोवा

2
@ मर्कोवा: वास्तव में, यह उन चीजों में से एक है जो restrictC99 के लिए है।
स्टीव जेसप जूल

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

4

यदि ssप्रकार का है const char *और आप constलूप के भीतर नेस को नहीं निकाल strlenरहे हैं, तो कंपाइलर केवल एक बार कॉल कर सकता है , यदि अनुकूलन चालू हो। लेकिन यह निश्चित रूप से व्यवहार नहीं है जिसे गिना जा सकता है।

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

for( auto i = strlen(s); i > 0; --i ) {
  // do whatever
  // remember value of s[strlen(s)] is the terminating NULL character
}

1
यह strlenबिल्कुल गलत है । जब तक आप अंत तक हिट नहीं करते हैं।
आर .. गिटहब स्टॉप हेल्पिंग आईसीई

i > 0? क्या यह i >= 0यहाँ नहीं होना चाहिए ? व्यक्तिगत रूप से, मैं भी शुरू करूँगा strlen(s) - 1यदि स्ट्रिंग पर पीछे की ओर चलना, तो समाप्ति\0 को कोई विशेष विचार करने की आवश्यकता नहीं है।
बजे एक CVn

2
@ माइकलकॉर्लिंग i >= 0केवल तभी काम करता है जब आप इसके लिए इनिशियलाइज़ करते हैं strlen(s) - 1, लेकिन तब यदि आपके पास शून्य लंबाई पर एक स्ट्रिंग है तो प्रारंभिक मूल्य अंडरफ्लो होता है
प्रेटोरियन

@ प्रेटोरियन, शून्य लंबाई स्ट्रिंग पर अच्छा बिंदु। मैंने उस मामले पर विचार नहीं किया जब मैंने अपनी टिप्पणी लिखी थी। क्या C ++ i > 0प्रारंभिक लूप प्रविष्टि पर अभिव्यक्ति का मूल्यांकन करता है ? यदि ऐसा नहीं होता है, तो आप सही हैं, शून्य लंबाई का मामला निश्चित रूप से लूप को तोड़ देगा। यदि ऐसा होता है, तो आप "बस" एक हस्ताक्षरित i== -1 <0 प्राप्त करते हैं ताकि सशर्त होने पर कोई लूप प्रविष्टि न हो i >= 0
एक CVn

@ माइकलकॉर्जलिंग हां, पहली बार लूप निष्पादित करने से पहले बाहर निकलने की स्थिति का मूल्यांकन किया जाता है। strlenवापसी प्रकार अहस्ताक्षरित है, इसलिए (strlen(s)-1) >= 0शून्य लंबाई के तारों के लिए सही का मूल्यांकन करता है।
प्रेटोरियन

3

औपचारिक रूप से हां, strlen()हर पुनरावृत्ति के लिए बुलाए जाने की उम्मीद है।

वैसे भी मैं कुछ चतुर कंपाइलर ऑप्टिमाइज़ेशन की मौजूदगी की संभावना को नकारना नहीं चाहता, जो पहले वाले के बाद स्ट्रगल () के लिए किसी भी लगातार कॉल को ऑप्टिमाइज़ करेगा।


3

इसमें संपूर्ण रूप से समर्पित कोड forलूप के हर पुनरावृत्ति पर निष्पादित किया जाएगा । strlen(ss)कॉल के परिणाम को याद करने के लिए कंपाइलर को यह जानना होगा कि कम से कम

  1. समारोह strlenसाइड इफेक्ट फ्री था
  2. द्वारा इंगित की गई स्मृति ssलूप की अवधि के लिए परिवर्तित नहीं होती है

कंपाइलर इन चीजों में से किसी को भी नहीं जानता है और इसलिए पहली कॉल के परिणाम को सुरक्षित रूप से याद नहीं कर सकता है


वैसे यह उन चीजों को जान सकता है जो स्थैतिक विश्लेषण के साथ हैं, लेकिन मुझे लगता है कि आपकी बात यह है कि इस तरह का विश्लेषण वर्तमान में किसी भी C ++ कंपाइलर में लागू नहीं किया गया है, हाँ?
GManNickG

@GManNickG यह निश्चित रूप से # 1 साबित कर सकता है लेकिन # 2 कठिन है। एक एकल धागे के लिए हाँ यह निश्चित रूप से साबित हो सकता है लेकिन बहु-सूत्रित वातावरण के लिए नहीं।
जेरेडपायर

1
शायद मैं जिद्दी हो रहा हूं, लेकिन मुझे लगता है कि नंबर दो बहुपरत वातावरण में भी संभव है, लेकिन निश्चित रूप से एक बेतहाशा मजबूत आक्रमण प्रणाली के बिना नहीं। बस यहाँ हालांकि musing; निश्चित रूप से किसी भी वर्तमान सी ++ संकलक के दायरे से परे।
GManNickG

@GManNickG मुझे नहीं लगता कि यह C / C ++ में संभव है। मैं बहुत आसानी से की पता छिपाया जा सकता था ssएक में size_tया इसे विभाजित कई लोगों के बीच byteमूल्यों। मेरा कुटिल धागा तो बस उस पते में बाइट्स लिख सकता है और संकलक को यह समझने का तरीका पता होगा कि यह किससे संबंधित है ss
जेयरपावर

1
@JaredPar: माफ़ करना धमाकेदार, आप दावा कर int a = 0; do_something(); printf("%d",a);सकते हैं कि अनुकूलित नहीं किया जा सकता है, इस आधार पर जो do_something()आपकी असंबद्ध अंतरंग बात कर सकता है, या स्टैक को वापस क्रॉल कर सकता है और aजानबूझकर संशोधित कर सकता है। वास्तव में, जीसी 4.5 इसे do_something(); printf("%d",0);-O3 के साथ ऑप्टिमाइज़ करता है
स्टीव जेसोप

2

हाँ । जब मैं बढ़ता हूं तो स्ट्रैलेन की गणना हर बार की जाएगी।

यदि आप एस एस परिवर्तन नहीं किया साथ पाश में साधन यह तर्क को प्रभावित नहीं करेगा अन्यथा यह प्रभावित करेगा।

यह निम्नलिखित कोड का उपयोग करने के लिए सुरक्षित है।

int length = strlen(ss);

for ( int i = 0; i < length ; ++ i )
{
 // blabla
}

2

हां, strlen(ss)प्रत्येक पुनरावृत्ति पर लंबाई की गणना करेगा। यदि आप ssकिसी तरह से बढ़ा रहे हैं और भी बढ़ा रहे हैं i; अनंत लूप होगा।


2

हां, हर बार लूप के मूल्यांकन के बाद strlen()फ़ंक्शन को कहा जाता है।

यदि आप दक्षता में सुधार करना चाहते हैं, तो स्थानीय चर में सब कुछ बचाने के लिए हमेशा याद रखें ... इसमें समय लगेगा लेकिन यह बहुत उपयोगी है।

आप नीचे दिए गए कोड का उपयोग कर सकते हैं:

String str="ss";
int l = strlen(str);

for ( int i = 0; i < l ; i++ )
{
    // blablabla
}


2

आजकल आम नहीं है, लेकिन 20 साल पहले 16 बिट प्लेटफार्मों पर, मैं इसकी सिफारिश करूंगा:

for ( char* p = str; *p; p++ ) { /* ... */ }

यदि आपका कंपाइलर ऑप्टिमाइज़ेशन में बहुत स्मार्ट नहीं है, तो भी उपरोक्त कोड का परिणाम अच्छा असेंबली कोड हो सकता है।


1

हाँ। परीक्षण यह नहीं जानता कि ss लूप के अंदर परिवर्तित नहीं होता है। यदि आप जानते हैं कि यह नहीं बदलेगा तो मैं लिखूंगा:

int stringLength = strlen (ss); 
for ( int i = 0; i < stringLength; ++ i ) 
{
  // blabla 
} 

1

Arrgh, यह आदर्श परिस्थितियों में भी होगा, अरे!

आज के अनुसार (जनवरी 2018), और जीसीसी 7.3 और क्लैंग 5.0, यदि आप संकलित करते हैं:

#include <string.h>

void bar(char c);

void foo(const char* __restrict__ ss) 
{
    for (int i = 0; i < strlen(ss); ++i) 
    {
        bar(*ss);
    }
}    

तो हमारे पास:

  • ss एक निरंतर सूचक है।
  • ss चिह्नित है __restrict__
  • लूप बॉडी किसी भी तरह से ss(अच्छी तरह से, जब तक कि यह उल्लंघन न हो __restrict__) द्वारा बताई गई मेमोरी को नहीं छू सकती ।

और फिर भी , दोनों संकलक strlen() उस लूप के प्रत्येक एकल पुनरावृत्ति को निष्पादित करते हैं । गजब का।

इसका मतलब @Praetorian और @JaredPar का गठबंधन / इच्छाधारी सोच भी नहीं है।


0

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


0

हाँ।

strlen()जब iवृद्धि होती है और अनुकूलित नहीं किया जाता है तो हर बार गणना की जाती है।

नीचे दिए गए कोड से पता चलता है कि संकलक को अनुकूलन क्यों नहीं करना चाहिए strlen()

for ( int i = 0; i < strlen(ss); ++i )
{
   // Change ss string.
   ss[i] = 'a'; // Compiler should not optimize strlen().
}

मुझे लगता है कि उस विशेष संशोधन से कभी भी ss की लंबाई बदल नहीं जाती, बस उसकी सामग्री, इसलिए (वास्तव में, वास्तव में चतुर) संकलक अभी भी अनुकूलित कर सकता है strlen
डैरेन कुक

0

हम इसे आसानी से परख सकते हैं:

char nums[] = "0123456789";
size_t end;
int i;
for( i=0, end=strlen(nums); i<strlen(nums); i++ ) {
    putchar( nums[i] );
    num[--end] = 0;
}

लूप को फिर से शुरू करने से पहले प्रत्येक पुनरावृत्ति के बाद लूप स्थिति का मूल्यांकन किया जाता है।

उस प्रकार के बारे में भी सावधान रहें जो आप स्ट्रिंग्स की लंबाई को संभालने के लिए उपयोग करते हैं। यह होना चाहिए size_tजिसे unsigned intstdio के रूप में परिभाषित किया गया है । तुलना करना और इसे intडालना कुछ गंभीर भेद्यता समस्या का कारण हो सकता है।


0

ठीक है, मैंने देखा कि कोई कह रहा है कि यह किसी भी "चतुर" आधुनिक संकलक द्वारा डिफ़ॉल्ट रूप से अनुकूलित है। वैसे अनुकूलन के बिना परिणामों को देखो। मैंने कोशिश की:
न्यूनतम सी कोड:

#include <stdio.h>
#include <string.h>

int main()
{
 char *s="aaaa";

 for (int i=0; i<strlen(s);i++)
  printf ("a");
 return 0;
}

मेरा कंपाइलर: g ++ (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3
असेंबली कोड बनाने के लिए कमांड: g ++ -S -mm = Intel test.cpp

Gotten assembly code at the output:
    ...
    L3:
mov DWORD PTR [esp], 97
call    putchar
add DWORD PTR [esp+40], 1
    .L2:
     THIS LOOP IS HERE
    **<b>mov    ebx, DWORD PTR [esp+40]
mov eax, DWORD PTR [esp+44]
mov DWORD PTR [esp+28], -1
mov edx, eax
mov eax, 0
mov ecx, DWORD PTR [esp+28]
mov edi, edx
repnz scasb</b>**
     AS YOU CAN SEE it's done every time
mov eax, ecx
not eax
sub eax, 1
cmp ebx, eax
setb    al
test    al, al
jne .L3
mov eax, 0
     .....

मैं किसी भी संकलक पर भरोसा करने के लिए तैयार restrictहोऊंगा जब तक कि स्ट्रिंग के पते को अयोग्य घोषित नहीं किया जाता। हालांकि कुछ ऐसे मामले हैं जहाँ इस तरह का अनुकूलन वैध restrictहोगा, किसी भी उचित उपाय के द्वारा इस तरह के मामलों को मज़बूती से पहचानने के लिए आवश्यक प्रयास , लगभग निश्चित रूप से लाभ से अधिक होगा। यदि स्ट्रिंग के पते में एक const restrictक्वालीफायर था, हालांकि, यह कुछ और देखने के बिना अनुकूलन को सही ठहराने के लिए पर्याप्त और अपने आप में पर्याप्त होगा।
सुपरकैट

0

प्रेटोरियन के जवाब पर विस्तार से मैं निम्नलिखित की सिफारिश करता हूं:

for( auto i = strlen(s)-1; i > 0; --i ) {foo(s[i-1];}
  • autoक्योंकि आप इस बात की परवाह नहीं करना चाहते हैं कि किस प्रकार के स्ट्रेंथ रिटर्न हैं। एक C ++ 11 संकलक (उदाहरण के लिए gcc -std=c++0x, पूरी तरह से C ++ 11 नहीं बल्कि ऑटो प्रकार का काम) आपके लिए ऐसा करेगा।
  • i = strlen(s)क्योंकि आप तुलना करना चाहते हैं 0(नीचे देखें)
  • i > 0 क्योंकि 0 से तुलना करना (थोड़ा) तेज है जो किसी अन्य संख्या की तुलना में है।

नुकसान यह है कि आपको i-1स्ट्रिंग वर्णों तक पहुंचने के लिए उपयोग करना होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.