2010-01-22 11 views
9

लूप दक्षता पर शुरुआती प्रश्न। मैंने सी ++ (मेरी पहली भाषा) में प्रोग्रामिंग शुरू कर दी है और Bjarne Stroustrup द्वारा 'सिद्धांतों और अभ्यास का उपयोग सी ++' का उपयोग कर रहे हैं। मैं पहले अध्यायों के माध्यम से अपना रास्ता बना रहा हूं और अभी लूप की अवधारणा के साथ पेश किया गया है।लूप दक्षता - सी ++

लूप के बारे में पहला अभ्यास मुझे निम्न से पूछता है: चरित्र 'बी' चार ('ए' + 1) है, 'सी' चार ('ए' + 2) आदि है। एक लूप का उपयोग करें उनकी संगत पूर्णांक मूल्यों के साथ पात्रों में से एक मेज लिखने :

int number = 64; //integer value for @ sign, character before A 
char letter = number;//converts integer to char value 
int i = 0; 

while (i<=25){ 
    cout << ++letter << "\t" << ++number << endl; 
    ++i; 
    } 
:

एक 97, 98 बी, ..., जेड 122

हालांकि, मैं अपरकेस का इस्तेमाल किया, मैं निम्नलिखित बनाया

क्या मेरा लक्ष्य केवल 'मैं' लूप में मौजूद होना चाहिए या यह बस नहीं है प्रकारों के बीच कनवर्ट करते समय संभव नहीं है? मैं चरित्र के मूल्य को इसके पूर्णांक समकक्ष (यानी वर्तमान विधि के विपरीत) में परिवर्तित करने के अलावा उपरोक्त किसी भी अन्य तरीके से नहीं सोच सकता है या बस रूपांतरण नहीं कर रहा हूं और अक्षर संग्रह '@' है।

+0

धन्यवाद, मैं कुछ पन्नों आगे फ़्लिप और यह पूछता है मुझे लूप के लिए इसका उपयोग करके पुनर्निर्माण करने के लिए =)। – SlackerByNature

+1

आह, स्वामी विधियां स्पष्ट हो जाती हैं –

उत्तर

9

आपको पहले स्पष्टता का लक्ष्य रखना चाहिए और आप इसके बजाय माइक्रो-ऑप्टिमाइज़ करने का प्रयास करें। बेहतर होगा कि तुम फिर से लिखने सकता है कि एक के रूप में पाश के लिए:

const int offsetToA = 65; 
const int numberOfCharacters = 26; 
for(int i = 0; i < numberOfCharacters; ++i) { 
    const int characterValue = i + offsetToA; 
    cout << static_cast<char>(characterValue ) << characterValue << endl; 
} 

और आप विभिन्न प्रकार के बीच में बदल सकते हैं - कि कास्टिंग (कोड में static_cast निर्माण ऊपर) कहा जाता है।

+6

स्पष्टता के विषय पर; संख्यात्मक स्थिरांक शायद ही कभी एक अच्छा विचार है। मैं 'ऑफसेट टीओए' मान '' '' (या '' ए'' 'असाइन करने का प्रस्ताव करता हूं, जिसे स्पष्ट रूप से (सही)' int' में परिवर्तित किया जाता है। यह निश्चित रूप से भी आवश्यक है कि मुद्रित पहले वर्ण की गणना 'ऑफसेट टीओए + 0' के रूप में की जाती है। –

2

आपके द्वारा किए जा रहे तरीके के बारे में विशेष रूप से अक्षम नहीं है, लेकिन यह निश्चित रूप से वर्णों और स्याही के बीच परिवर्तित करना संभव है (एक char एक पूर्णांक प्रकार है)। इसका मतलब यह होगा कि आपको केवल 3 (i, letter + number) के बजाय 1 काउंटर स्टोर करने की आवश्यकता है, जिसमें आपके पास

भी है, एक 'फॉर' लूप को समाप्त करने के लिए एक निश्चित शुरुआत से लूपिंग के लिए शायद अधिक मूर्खतापूर्ण है (हालांकि इसके संभव तो आप इस अभी तक मुलाकात नहीं की है)

2

एक बुरी तरह से यह करने के लिए नहीं है यही कारण है, लेकिन आप इस तरह से केवल एक पाश चर के साथ यह कर सकते हैं: आप भी इस्तेमाल कर सकते हैं

char letter = 65; 

while(letter <= 65+25){ 
    printf("%c\t%d\n", letter, letter); 
    ++letter; 
} 
22

जेके से इसे जारी रखते हुए लूप में खुद को पत्र (अक्षर < = 'z')। मैं लूप के लिए भी इस्तेमाल करता हूं लेकिन यह सिर्फ मुझे है।

for(char letter = 'a'; letter <= 'z'; ++letter) 
    std::cout << letter << "\t" << static_cast<int>(letter) << std::endl; 
+0

यह सही है: आप वास्तव में _letters_ पर फिर से सक्रिय करते हैं! प्रोग्रामिंग के लिए +1 जितना संभव हो सके _intention_ के लिए +1। – xtofl

+0

लेकिन क्या सी ++ गारंटी देता है कि 'ए' + 1 == 'बी''? विवरण के लिए इस प्रश्न का मेरा जवाब भी देखें। –

+2

@ आलोक: अनुभव गारंटी देता है कि 'ए' + 1 == बी। जैसे ही मैं एक ऐसे माहौल में काम करता हूं जहां मैं कोड लिखूंगा जो इसके साथ सौदा करता है;) – Patrick

0

तीन अलग-अलग चरों में वृद्धि शायद थोड़ा उलझन में है।

for (int i = 0; i != 26; ++i) 
{ 
    int chr = 'a' + i; 
    std::cout << static_cast<char>(chr) << ":\t" << chr << std::endl; 
} 

ध्यान दें कि एक for पाश का उपयोग कर, की स्थापना के परीक्षण और एक ही स्थान पर पाश चर incrementing के सभी तर्क रहता है: यहाँ एक संभावना है।

0

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

मुझे नहीं लगता कि आप इस प्रश्न को सही तरीके से समझ चुके हैं। आप कोड लिख रहे हैं, जानते हुए कि 'A' 65 है। व्यायाम का पूरा बिंदु 'A' के मान को 'Z' पर अपने सिस्टम पर प्रिंट करना है, बिना यह जानने के कि उनके पास क्या मूल्य है।

अब, c के लिए एक पूर्णांक मान प्राप्त करने के लिए, आप यह कर सकते हैं: static_cast<int>(c)। मेरा मानना ​​है कि आप यही पूछ रहे हैं।

मैंने कोई कोड नहीं लिखा है क्योंकि ऐसा करने के लिए आपके लिए और अधिक मजेदार होना चाहिए। विशेषज्ञों के लिए

प्रश्न: सी में, मुझे पता है कि 'a' ... 'z' निरंतर मूल्यों की आवश्यकता नहीं है ('A' के लिए एक ही ... 'Z')। सी ++ के लिए भी यही सच है? मैं ऐसा सोचूंगा, लेकिन फिर ऐसा लगता है कि स्ट्रॉस्ट्रप की पुस्तक यह मानती है।

+0

मैं आपके बिंदु को समझ सकता हूं लेकिन यह वास्तव में उतना ही बुनियादी है जितना मैंने लिखा था, static_cast (सी) पेश नहीं किया गया है, पाठक ऐसी संभावनाओं से कभी अवगत नहीं है। उन्होंने एक लूप के माध्यम से संख्याओं और उनके वर्गों की एक सूची बनाने के पहले उदाहरण दिए। यह लूप की सामग्री को न केवल लूप के विचार को पेश करने के बारे में अधिक है। यदि इसका कोई औचित्य हो। – SlackerByNature

+0

आलोक: नहीं, मुझे विश्वास नहीं है कि सी ++ गारंटी देता है कि या तो। स्रोत और निष्पादन वर्ण सेट 2.2 में परिभाषित किए गए हैं, जो बताता है कि दशमलव अंक लगातार हैं लेकिन अक्षरों का उल्लेख नहीं करते हैं। लेकिन प्रश्नकर्ता कहता है कि यह पाठ में है जो मुझे पुस्तक में प्रश्न से कॉपी करने के लिए प्रतीत होता है। तो मुझे लगता है कि सवाल के प्रयोजनों के लिए, बजेर्ने मानते हैं कि लोअरकेस अक्षरों को लगातार जारी किया जाता है। जैसा कि slackerbyname कहते हैं, यह ईडीसीबीआईसी को संभालने के बारे में कोई सवाल नहीं है, न ही आपके कोड पर पोर्टिंग बाधाओं को पेश करने के बारे में और कैसे ... –

+0

"किसी चरित्र सी के लिए पूर्णांक मान प्राप्त करने के लिए, आप कर सकते हैं:' static_cast (c) ' "। या 'int i = c;', जो मैं अपेक्षा करता हूं। –

2

आप अपने पाश की दक्षता के बारे में चिंतित हैं, तो मैं यह कोशिश करने के लिए आप से आग्रह करता हूं होगा:

इस कोड को संकलित और इस तरह के दृश्य स्टूडियो के रूप में, एक IDE के तहत चल रहा है, और शुरुआत में एक को तोड़ने बिंदु निर्धारित हो जाओ । जब आप वहां जाते हैं, तो डिस्प्लेब्स व्यू (निर्देश दृश्य) पर स्विच करें और F11 (सिंगल-स्टेप) कुंजी को मारना शुरू करें, और मानसिक गिनती रखें कि आप कितनी बार इसे मार रहे हैं।

आप देखेंगे कि यह लूप में प्रवेश करता है, i की तुलना 25 के विरुद्ध करता है, और फिर cout लाइन के लिए कोड करना शुरू करता है। इसमें letter बढ़ाना शामिल है, और फिर << कोउट के लिए दिनचर्या में जा रहा है। यह वहां कई चीजें करता है, संभवतः सबराउटिन आदि में गहराई से जा रहा है, और आखिरकार एक वस्तु वापस लौटकर वापस आ जाता है। फिर यह "\t" को तर्क के रूप में धक्का देता है और उसे उस ऑब्जेक्ट में भेजता है, और वापस जाता है और इससे पहले की गई सभी चीज़ें करता है। फिर यह number लेता है, इसे बढ़ाता है, और cout::<< दिनचर्या को पास करता है जो एक पूर्णांक स्वीकार करता है, इसे एक स्ट्रिंग में परिवर्तित करने के लिए फ़ंक्शन को कॉल करता है (जिसमें लूप शामिल होता है), फिर वह लूप से पहले की गई सभी चीजें करता है जो स्ट्रिंग में स्ट्रिंग करता है आउटपुट बफर और वापसी।

थक गए? आप अभी तक नहीं कर रहे हैं endl को आउटपुट होना चाहिए, और जब ऐसा होता है, न केवल यह "\n" बफर में डालता है, लेकिन यह सिस्टम रूटीन को उस बफर को फ़ाइल या कंसोल पर फ़्लश करने के लिए कहता है जहां आप I/O भेज रहे हैं। आप शायद उसमें एफ 11 नहीं कर सकते हैं, लेकिन बाकी आश्वासन दिया है कि यह बहुत सारे चक्र लेता है और आई/ओ पूरा होने तक वापस नहीं आता है।

अब तक, आपकी एफ 11-गिनती कई हज़ार, अधिक या उससे कम के आसपास होनी चाहिए।

अंत में, आप बाहर आते हैं और ++i कथन प्राप्त करते हैं, जिसमें 1 या 2 निर्देश होते हैं, और अगले पुनरावृत्ति को शुरू करने के लिए लूप के शीर्ष पर वापस कूदते हैं।

अब, क्या आप अभी भी लूप की दक्षता के बारे में चिंतित हैं?


इस बिंदु को बनाने का एक आसान तरीका है, और यह केवल निर्देशक के रूप में है। अपने पूरे कोड के चारों ओर एक अनंत लूप लपेटें ताकि यह हमेशा के लिए चलता है। यह चल रहा है, आईडीई में "रोकें" बटन दबाएं, और कॉल स्टैक को देखें। (This is called a "stackshot".) यदि आप इसे कई बार करते हैं तो आपको एक अच्छा विचार मिलता है कि यह समय व्यतीत करता है। यहाँ एक उदाहरण है:

NTDLL! 7c90e514() 
KERNEL32! 7c81cbfe() 
KERNEL32! 7c81cc75() 
KERNEL32! 7c81cc89() 
MSVCRTD! 1021bed3() 
MSVCRTD! 1021bd59() 
MSVCRTD! 10218833() 
MSVCRTD! 1023a500() 
std::_Fputc() line 42 + 18 bytes 
std::basic_filebuf<char,std::char_traits<char> >::overflow() line 108 + 25 bytes 
std::basic_streambuf<char,std::char_traits<char> >::sputc() line 85 + 94 bytes 
std::ostreambuf_iterator<char,std::char_traits<char> >::operator=() line 304 + 24 bytes 
std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Putc() line 633 + 32 bytes 
std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Iput() line 615 + 25 bytes 
std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::do_put() line 481 + 71 bytes 
std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::put() line 444 + 44 bytes 
std::basic_ostream<char,std::char_traits<char> >::operator<<() line 115 + 114 bytes 
main() line 43 + 96 bytes 
mainCRTStartup() line 338 + 17 bytes 

मैं इस समय का एक गुच्छा किया है, और नहीं एक बार जब यह बाहरी i<=25 पाश के लिए कोड में बंद हो गए। तो यह लूप अनुकूलित करना किसी के महान रूपक की तरह है: "वजन कम करने के लिए बाल कटवाने"।

1

चूंकि किसी और ने इसका उल्लेख नहीं किया है: पुनरावृत्ति की निश्चित मात्रा होने के बाद, यह do..while के साथ पोस्ट-कंडीशन पुनरावृत्ति के लिए भी एक उम्मीदवार है।

char letter = 'a'; 
do { 
    std::cout << letter << "\t" << static_cast<int>(letter) << std::endl; 
} while (++letter <= 'z'); 

हालांकि, के रूप में दिखाया गया है Patrick's answerfor मुहावरा अक्सर कम (इस मामले में लाइनों की संख्या में) है। मदद के लिए

0

धन्यवाद .. सब मैं नीचे लिखा

int main() 
{ 
char letter = 96; 
int number = letter; 
int i = 0; 

while(i <26) 
{ 
cout <<++letter <<":" <<++numbers <<" "; 
++i; 
} 

महान ... और बहुत सरल काम करता है अब समझने के लिए किया गया था।

1

आप int करने के लिए चार को बढ़ावा देने के कर सकते हैं ...

//characters and their corresponding integer values 
#include"../../std_lib_facilities.h" 

int main() 
{ 
    char a = 'a'; 
    while(a<='z'){ 
     cout<<a<<'\t'<<a*1<<'\n'; //a*1 => char operand promoted to integer! 
     ++a; 
    } 

    cout<<endl; 
} 
0

मैं इस कोशिश की और ठीक काम किया है: स्पष्टीकरण लोगों के लिए

char a = 'a'; 
int i = a; //represent char a as an int 
while (a <= 'z') { 
cout << a << '\t' << i << '\n'; 
++a; 
++i; 
} 
संबंधित मुद्दे