এই ফাংশনটি কেন একটি স্ট্রিংয়ের সঠিক দৈর্ঘ্য দেয়? (চার পয়েন্টার বাড়ানো)


12

এটি এমন একটি ফাংশন যা একটি স্ট্রিংয়ে অক্ষরের সংখ্যা গণনা করে:

int str_len(const char* s) {
    int i = 0;
    while(*(s++)) {
        i++;
    }
    return i;
}

কেন এটি সঠিক দৈর্ঘ্য দেয়?

ধরা যাক আমি এই ফাংশনটিকে একটি সাধারণ স্ট্রিং দিয়ে কল করি "a"। তারপরে ওয়েল sলুপে বর্ধিত হয়, সুতরাং এর মান sএবং iউভয় 0 হয়।

উত্তর:


10

এর মান s++হ'ল sইনক্রিমেন্টের পূর্বে মূল মূল্য হ'ল পরবর্তী ক্রম বিন্দুর আগে একটি অনির্দিষ্ট সময়ে বৃদ্ধি হয়।

সুতরাং *s++এবং *(s++)সমতুল্য: এরা উভয়েরই মূল মূল্যকে অবজ্ঞা করে s। আর একটি সমতুল্য অভিব্যক্তি হ'ল *(0, s++)মূর্খতার জন্য নয়, এটি এইরকম:0[s++]

উল্লেখ্য তবে আপনার ফাংশন টাইপ ব্যবহার করা উচিত size_tজন্য iএবং তার রিটার্ন টাইপ:

size_t str_len(const char *s) {
    size_t i = 0;
    while (*s++) {
        i++;
    }
    /* s points after the null terminator */
    return i;
}

এখানে লুপ প্রতি একক বৃদ্ধি সহ একটি সম্ভাব্য আরও কার্যকর সংস্করণ:

size_t str_len(const char *s) {
    const char *s0 = s;
    while (*s++) {
        /* nothing */
    }
    return s - 1 - s0;
}

যারা দ্বিতীয় অনুচ্ছেদে অদ্ভুত অভিব্যক্তিগুলি সম্পর্কে অবাক হন:

  • 0, s++কমা অপারেটরের একটি উদাহরণ ,যা এর বাম অংশটি মূল্যায়ন করে, তার ডান অংশটি যা এর মান গঠন করে। সুতরাং (0, s++)সমতুল্য (s++)

  • 0[s++]সমতূল্য (s++)[0]এবং *(0 + s++)বা *(s++ + 0)যা প্রক্রিয়া সহজ *(s++)। পয়েন্টার এবং সূচক এক্সপ্রেশনগুলিতে []প্রকাশের স্থানান্তর খুব সাধারণ বা বিশেষভাবে কার্যকর নয় তবে এটি সি স্ট্যান্ডার্ডের সাথে সঙ্গতিপূর্ণ।


নিশ্চিত আশা কমা অপারেটর পরিষ্কার ছিল। , s++খারাপ জিনিসগুলি দূরে সরিয়ে ফেলুন:)
ডেভিড সি র্যাঙ্কিন

6

ধরা যাক আমি এই ফাংশনটিকে একটি সাধারণ স্ট্রিং "এ" বলি। তারপরে ওদিকে লুপে বৃদ্ধি করা হয় সুতরাং s এর মান 0 হয় আমিও 0 হয়।

যে উদাহরণে, sপয়েন্ট 'a'মধ্যে "a"। তারপরে এটি বর্ধিত iহয় এবং বর্ধিতও হয়। এখন sনাল টার্মিনেটরটি নির্দেশ করুন, এবং iহয় 1। লুপের মাধ্যমে পরবর্তী রানগুলিতে *(s++)হ'ল '\0'(যা 0) তাই লুপটি শেষ হয় এবং i(এর 1) বর্তমান মান ফিরে আসে।

সাধারণত, লুপটি স্ট্রিংয়ের প্রতিটি চরিত্রের জন্য একবার চালায় এবং তারপরে নাল টার্মিনেটরে এসে থামে, সুতরাং এটি অক্ষরগুলি গণনা করে।


S বন্ধনীগুলিতে থাকার কারণে, আমি ভেবেছিলাম যে এটি প্রথমে বর্ধিত হবে (সুতরাং এখন এটি '/ 0' এ নির্দেশ করে)। সুতরাং লুপটি মিথ্যা এবং আমি কখনই বর্ধিত হয় না।
লোর

2
@lor কী, তা স্মরণ postincrement অপারেটার: এটা যাই হোক না কেন মূল্যায়ণ sঅনুষ্ঠিত সামনে বৃদ্ধিশীল। আপনি যা বর্ণনা করছেন তা হ'ল আচরণ ++s(যা প্রকৃতপক্ষে একের অধীনে গণনা করা হবে এবং খালি স্ট্রিং পাস হলে ইউবিকে অনুরোধ করবে)।
টবি স্পিড

2

এটি নিখুঁত জ্ঞান করে:

int str_len(const char* s) {
    int i = 0;
    while(*(s++)) { //<-- increments the pointer to char till the end of the string
                    //till it finds '\0', that is, if s = "a" then s is 'a'
                    // followed by '\0' so it increments one time
        i++; //counts the number of times the pointer moves forward
    }
    return i;
}

"তবে sবন্ধনীগুলিতে রয়েছে That's তাই আমি ভেবেছিলাম আগে এটি বাড়ানো হবে"

ঠিক এই কারণেই পয়েন্টারটি বর্ধিত হয় এবং চরিত্রটি নয়, আসুন আপনাকে বলে দিন যে আপনার (*s)++ক্ষেত্রে এই চরিত্রটি বাড়ানো হবে এবং পয়েন্টারটি নয়। ডিফেরেন্সিংয়ের অর্থ আপনি এখন পয়েন্টার দ্বারা রেফার করা মানটি নিয়ে কাজ করছেন, পয়েন্টারটি নিজেই নয়।

যেহেতু উভয় অপারেটরের একই বৈশিষ্ট্য রয়েছে তবে ডান থেকে বামে সাহচর্য আপনি *s++পয়েন্টারটি বাড়ানোর জন্য কোনও বন্ধনী ছাড়াই কেবল ব্যবহার করতে পারেন ।


কিন্তু এস বন্ধনী মধ্যে আছে। এজন্য আমি ভেবেছিলাম আগে এটি বাড়ানো হবে। (যদি আমাদের "a" s এর মতো সরল স্ট্রিং থাকে তবে এখন "/ 0" এ নির্দেশ করবে)। শর্তটি এখন (0) থাকাকালীন সময় লুপটি কখনই প্রবেশ করে না।
লোর

2

পোস্ট ইনক্রিমেন্ট অপারেটর অপারেন্ডের মান 1 বৃদ্ধি করে তবে এক্সপ্রেশনের মানটি ইনক্রিমেন্ট অপারেশনের আগে অপারেন্ডের মূল মান।

যুক্তি প্রেরণ ধরে str_len()হয় "a"। এর মধ্যে str_len()পয়েন্টারটি sস্ট্রিংয়ের প্রথম অক্ষরের দিকে নির্দেশ করছে "a"। ইন whileলুপ:

while(*(s++)) {
.....
.....

যদিও sবৃদ্ধি করা হবে কিন্তু এর মান sমধ্যে অভিব্যক্তি চরিত্র এটা বৃদ্ধি করার আগে প্রতি নির্দেশ করা হয়, যা প্রথম অক্ষর পয়েন্টার হয় পয়েন্টার হতে হবে 'a'। পয়েন্টারটি যখন অবৈধ sহয় তখন এটি চরিত্র দেয় 'a'। পরবর্তী পুনরাবৃত্তিতে sপয়েন্টারটি পরবর্তী অক্ষরের দিকে নির্দেশ করবে যা শূন্য চরিত্র \0। যখন sসম্মানিত করা হয়, এটি দেবে 0এবং লুপটি প্রস্থান করবে। নোট করুন, sএখন স্ট্রিংয়ের নাল চরিত্রের অতীতের একটি উপাদানকে নির্দেশ করবে "a"

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.