কেন স্ট্রিং :: তুলনা একটি পূর্বাবস্থায় ফিরে?


102

কেন একটি ছোট টাইপের পরিবর্তে string::compareএকটি intপরিবর্তিত হয় shortবা char? আমার বোধগম্যতা হল এই পদ্ধতিটি কেবল -1, 0 বা 1 প্রদান করে।

দ্বিতীয় অংশ, যদি আমি একটি তুলনামূলক পদ্ধতিটি ডিজাইন করতে পারি যা টাইপের দুটি বস্তুর তুলনা করে Fooএবং আমি কেবল -1, 0 বা 1 ফিরে আসতে চাইতাম তবে ব্যবহার করা shortবা charসাধারণত একটি ভাল ধারণা হতে পারে?

সম্পাদনা: আমাকে সংশোধন করা হয়েছে, string::compare-1, 0, বা 1 ফিরে আসে না, এটি আসলে একটি মান> 0, <0 বা 0 প্রদান করে। আমাকে লাইনে রাখার জন্য ধন্যবাদ।

উত্তরটি মোটামুটি বলে মনে হচ্ছে, এর চেয়ে ছোট কোনও প্রকারের ফিরে আসার কোনও কারণ নেই intকারণ রিটার্ন মানগুলি "মূল্যায়ন" এবং সেই "মূল্যবোধগুলি" টাইপ ইন্ট (4 বাইট) এর চেয়ে ছোট হওয়ার কারণে কোনও উপকার পায় না। এছাড়াও, অনেক লোক উল্লেখ করেছিলেন যে বেশিরভাগ সিস্টেমে রেজিস্টারগুলি সম্ভবত intযাইহোক আকারের হতে চলেছে , যেহেতু এই রেজিস্টারগুলি আপনি একটি 1, 2 বা 4 বাইট মান দিচ্ছেন কিনা তা পূরণ করা হচ্ছে, কোনও ফেরত দেওয়ার কোনও আসল সুবিধা নেই ছোট মান।

সম্পাদনা 2: প্রকৃতপক্ষে দেখে মনে হচ্ছে অ্যালাইনমেন্ট, মাস্কিং ইত্যাদির মতো ছোট ডেটাটাইপগুলি ব্যবহার করার সময় অতিরিক্ত প্রসেসিং ওভারহেড হতে পারে একটি অ্যারের ক্ষেত্রে।

আজ কিছু শিখেছি, আবারো ধন্যবাদ!


আমি মনে করি যে আরও ভাল কিছু হতে পারে যদি এর জন্য আরও একটি নির্দিষ্ট ধরণের ব্যবহার করা যেতে পারে। একটি যা অ্যাডা 95 এর শৈলীতে কেবল -1, 0 এবং 1 রয়েছে।
শচীন কৈথ

23
string::compare()আপনার লিঙ্ক করা ডকুমেন্টেশনে পরিষ্কারভাবে বলা হয়েছে যে রিটার্নের মান হ'ল <0, 0, এবং> 0-
নোট-

6
ব্যবহার shortবা এর charপরিবর্তে কি সুবিধা হবে int? বেশিরভাগ আর্কিটেকচার কোনও ফাংশনের রিটার্ন ভ্যালু একটি রেজিস্টারে সংরক্ষণ করতে চলেছে এবং একটি intকোনও রেজিস্টারে পাশাপাশি একটি shortবা একটি হিসাবে ফিট করে char। এবং charসংখ্যার জন্য ব্যবহার করা সর্বদা একটি খারাপ ধারণা, বিশেষত যখন আপনাকে স্বাক্ষরিত মানগুলি সঠিকভাবে পরিচালিত হয় তার গ্যারান্টি দেওয়া দরকার।
কোডি গ্রে

7
ক্যাপ্টেন ওভলিয়াস, আপনার নাম এবং মন্তব্য ... ঠিক অমূল্য।
কোডি স্মিথ

2
ব্যবহার charকরা একটি খারাপ ধারণা হতে পারে, যেহেতু charস্বাক্ষরিত নয় এমন প্ল্যাটফর্মগুলিতে শূন্যের চেয়ে কম হলে যদি রিটার্ন মানটির কোড চেক করা ব্যর্থ হয় ।
সহস্রাব্দ

উত্তর:


113

প্রথমত, স্পেসিফিকেশনটি হ'ল এটি 0প্রয়োজনীয় -1বা নয়, এর চেয়ে কম বা সমান বা তার চেয়ে বেশি মান প্রদান করবে 1। দ্বিতীয়ত, রিটার্ন মানগুলি মূল্যবোধগুলি হয়, অবিচ্ছেদ্য প্রচারের সাপেক্ষে, তাই আর কিছু ছোট ফেরার কোনও মানে হয় না।

সি ++ তে (সি হিসাবে) প্রতিটি প্রকাশটি হয় একটি মূল্য বা লভ্যালু। .তিহাসিকভাবে, পদগুলি এই সত্যকে বোঝায় যে লভ্যালুগুলি একটি কার্যভারের বামদিকে প্রদর্শিত হয়, যেখানে মূল্যমানগুলি কেবল ডানদিকে প্রদর্শিত হতে পারে। আজ, অ-শ্রেণীর ধরণের জন্য একটি সহজ অনুমানকরণ হ'ল একটি মূল্যবানের স্মৃতিতে একটি ঠিকানা থাকে, মূল্যমান হয় না। সুতরাং, আপনি কোনও মূল্যের ঠিকানা নিতে পারবেন না, এবং সিভি-কোয়ালিফায়ার (যা "শর্ত" অ্যাক্সেস ") প্রয়োগ করবেন না। সি ++ পদে, কোনও মূল্যবোধের শ্রেণীর ধরণ নেই যা খাঁটি মান, কোনও বস্তু নয়। কোনও ফাংশনের রিটার্ন মান হ'ল একটি মূল্যায়ন, যদি না এর রেফারেন্স টাইপ থাকে। (নিবন্ধভুক্ত ফিটনেসবিহীন প্রকারগুলি প্রায়শই একটি রেজিস্টারে ফিরে আসবে, উদাহরণস্বরূপ, মেমরির পরিবর্তে))

শ্রেণীর ধরণের ক্ষেত্রে, আপনি কোনও মূল্যবোধের ভিত্তিতে সদস্য ফাংশনগুলিকে কল করতে পারেন এর কারণে সমস্যাগুলি আরও জটিল । এর অর্থ হল যে মূল্যগুলির অবশ্যই this পয়েন্টারের জন্য ঠিকানা থাকতে হবে এবং সিভি-যোগ্য হতে পারে, যেহেতু সিভি-যোগ্যতা ওভারলোড রেজোলিউশনে ভূমিকা রাখে। অবশেষে, সি ++ 11 মূল্যের উল্লেখগুলি সমর্থন করার জন্য কয়েকটি নতুন পার্থক্য প্রবর্তন করে; এগুলিও মূলত শ্রেণীর ধরণের ক্ষেত্রে প্রযোজ্য।

ইন্টিগ্রাল প্রচার intহ'ল সত্যকে বোঝায় যে যখন একটি চেয়ে ছোট সংখ্যক অবিচ্ছেদ্য প্রকারগুলি একটি অভিব্যক্তিতে মূল্য হিসাবে ব্যবহৃত হয়, বেশিরভাগ প্রসঙ্গে, সেগুলিতে উন্নীত হবে int। সুতরাং আমার কাছে যদি ভেরিয়েবল ঘোষিত short a, b;হয় তবে প্রকাশে a + bউভয়ই aএবং সংযোজন হওয়ার আগে bপ্রচারিত intহয়। একইভাবে, যদি আমি লিখি a < 0, তুলনাটি একটিতে aরূপান্তরিত মানের উপর করা হয় int। অনুশীলনে, খুব কম ক্ষেত্রেই এটির একটি পার্থক্য রয়েছে, কমপক্ষে 2 এর পরিপূরক মেশিনে যেখানে পূর্ণসংখ্যার গাণিতিক মোড়ানো থাকে (অর্থাত্ খুব কয়েকটি এক্সটিক্স ব্যতীত, আজ — আমি মনে করি ইউনিসিস মেইনফ্রেমগুলি কেবলমাত্র ব্যতিক্রম বাকী রয়েছে)। এখনও, এমনকি আরও সাধারণ মেশিনে:

short a = 1;
std::cout << sizeof( a ) << std::endl;
std::cout << sizeof( a + 0 ) << std::endl;

বিভিন্ন ফলাফল দেওয়া উচিত: প্রথমটির সমতুল্য sizeof( short ), দ্বিতীয়টিsizeof( int ) (অবিচ্ছেদ্য প্রচারের কারণে)।

এই দুটি ইস্যুটি আনুষ্ঠানিকভাবে অরথগোনাল; অবিচ্ছেদ্য প্রচারের সাথে মূল্য এবং লভ্যগুলির কোনও যোগসূত্র নেই। ব্যতীত ... অবিচ্ছেদ্য প্রচার কেবলমাত্র মূল্যায়নের ক্ষেত্রে প্রযোজ্য এবং আপনি যে কোনও ক্ষেত্রে মূল্যবোধ ব্যবহার করবেন সেগুলির বেশিরভাগ (তবে সমস্ত নয়) এর ফলে অবিচ্ছেদ্য প্রচারের ফলাফল হবে। এই কারণে, সত্যিই চেয়ে ছোট কিছু একটি সাংখ্যিক মান কোনো কারণ নেই int। চরিত্রের ধরণ হিসাবে এটি ফেরত না দেওয়ার একটি খুব ভাল কারণ রয়েছে। অতিরিক্ত লোড অপারেটরগুলি, যেমন <<প্রায়শই অক্ষরের ধরণের জন্য আলাদা আচরণ করে, তাই আপনি কেবল অক্ষরকে অক্ষর হিসাবে ফিরিয়ে দিতে চান। (আপনি পার্থক্যটি তুলনা করতে পারেন:

char f() { return 'a'; }
std::cout << f() << std::endl;      //  displays "a"
std::cout << f() + 0 << std::endl;  //  displays "97" on my machine

পার্থক্যটি হ'ল দ্বিতীয় ক্ষেত্রে, সংযোজনটি অবিচ্ছেদ্য প্রচার ঘটায়, যার ফলস্বরূপ একটি আলাদা ওভারলোড <<বেছে নেওয়া উচিত।


46
return values are rvalues, subject to integral promotionআপনার উত্তরে আপনি আরও ব্যাখ্যা করতে পারলে ভাল লাগবে ।
অ্যালভিন ওয়াং

"রিটার্ন মান rvalues হয় ... তাই কিছু ছোট ফেরার কোন বিন্দু" এটা পছন্দ
Masoud

1
@ অ্যালভিনওয়ং: চরিত্রের পরিবর্তে সি বর্ণের আক্ষরিক অন্তর্ কেন রয়েছে তার উত্তরগুলি দেখুন ? আরও কিছু পটভূমি তথ্যের জন্য।
জেসি শুভ

আপনার সম্পাদনা যুক্ত হওয়ার চমত্কার ব্যাখ্যার পরে আমি আবারও এটি +1 করতে পারতাম।
কোডি গ্রে

তা হলে কী হত signed char? এটি কি স্বাক্ষরিত একই আচরণ করবে char, বা এটি অন্যরকম হবে?
user541686

41

এটি ইচ্ছাকৃত যে এটি -1, 0 বা 1 ফিরে আসে না।

এটি অনুমতি দেয় (দ্রষ্টব্য এটি স্ট্রিংয়ের জন্য নয়, তবে এটি স্ট্রিংগুলির ক্ষেত্রেও সমানভাবে প্রযোজ্য)

int compare(int *a, int *b)
{
   return *a - *b;
}

যা তুলনায় অনেক কম জটিল:

int compare(int *a, int *b)
{
   if (*a == *b) return 0;
   if (*a > *b) return 1;
   return -1;
}

যদি আপনাকে -1, 0 বা 1 ফিরতে হয় তবে আপনাকে যা করতে হবে [বা সেই লাইনগুলি সহ কিছু] করতে হবে।

এবং এটি আরও জটিল ধরণের জন্যও কাজ করে:

class Date
{
    int year;
    int month;
    int day;
}

int compare(const Date &a, const Date &b)
{
   if (a.year != b.year) return a.year - b.year;
   if (a.month != b.month) return a.month - b.month;
   return a.day - b.day;
}

স্ট্রিং ক্ষেত্রে, আমরা এটি করতে পারি:

int compare(const std::string& a, const std::string& b)
{
   int len = min(a.length(), b.length());

   for(int i = 0; i < len; i++)
   {
      if (a[i] != b[i]) return a[i] - b[i];
   }
   // We only get here if the string is equal all the way to one of them
   // ends. If the length isn't equal, "longest" wins. 
   return a.length() - b.length();
}

8
আপনার প্রথম compareফাংশনটিতে ওভারফ্লোতে সমস্যা রয়েছে যা (ভাগ্যক্রমে) এটির চেয়ে কম হয় char*এবং যদি এটির charচেয়ে ছোট হয় তবে সমানভাবে প্রয়োগ হয় না int। উদাহরণস্বরূপ, যদি *aহয় MAX_INTএবং *bহয় -1তখন *a - *bইউবি হয় তবে বাস্তবায়ন যদি তার আচরণটি সংজ্ঞায়িত করতে পছন্দ করে তবে ফলাফলটি অবশ্যই অবশ্যই নেতিবাচক is
স্টিভ জেসোপ

1
আপনার শেষ উদাহরণের সাথে সমস্যা: length()একটি প্রদান করে size_t, যা এর চেয়ে বড় হতে পারে int...
এফ'এক্স

হ্যাঁ, যদি আপনার স্ট্রিং 2 জিবি-র বেশি দীর্ঘ হয় তবে সমস্যা হতে পারে। ফিফোতে জিনিসগুলি একবারে সঞ্চয় করার জন্য টেস্ট-কেস হিসাবে আমি 1 জিবি দীর্ঘ স্ট্রিং করেছি। তবে নিশ্চিত, বেসপু 64 হিসাবে এমপিইজি এনকোডযুক্ত স্ট্রিংয়ের সাথে কারও কারও সাথে ডিল করা বা এরকম কিছু হতে পারে ...
ম্যাট পিটারসন

@ ম্যাটস পিটারসন এটি আরও একটি মৌলিক সমস্যা, কারণ প্রশ্নটি হল "কেন এটি কোনও
এফ'এক্স

ওয়েল, আমি নিশ্চিত যে এটি হিস্টরিয়াল - আমার অর্থ historicalতিহাসিক কারণগুলি - এবং সম্ভবত যাতে এটি স্ট্রিম্প / মেমপ্যাম্প এবং অন্যান্য তুলনা প্রকারের ক্রিয়াকলাপগুলির সাথে সামঞ্জস্যপূর্ণ।
ম্যাটস পিটারসন

25

int সাধারণত হয় (বেশিরভাগ আধুনিক হার্ডওয়্যার এর অর্থ) সিস্টেম বাস এবং / অথবা সিপিইউ নিবন্ধভুক্ত একই আকারের একটি পূর্ণসংখ্যা হয়, যাকে মেশিন শব্দ বলা হয়। সুতরাং ইনট সাধারণত ছোট প্রকারের চেয়ে দ্রুত গতিতে প্রবাহিত হয় কারণ এটি প্রান্তিককরণ, মাস্কিং এবং অন্যান্য ক্রিয়াকলাপগুলির প্রয়োজন হয় না।

ছোট ধরণেরগুলি প্রধানত অ্যারে এবং স্ট্রাক্টের জন্য র‍্যাম ব্যবহারের অপ্টিমাইজেশনের অনুমতি দেওয়ার জন্য বিদ্যমান। বেশিরভাগ ক্ষেত্রে তারা আরও ভাল র‍্যাম ব্যবহারের জন্য কয়েকটি সিপিইউ চক্র (অ্যালিগমেন্ট অপারেশন আকারে) বাণিজ্য করে।

যদি না আপনার সেন্টেরেন সাইজের স্বাক্ষরিত বা স্বাক্ষরযুক্ত সংখ্যার (চার, সংক্ষিপ্ত…) হিসাবে আপনার রিটার্নের মান প্রয়োগ করার প্রয়োজন না হয় তবে আপনি ইন্টি ব্যবহার করা ভাল, তাই স্ট্যান্ডার্ড লাইব্রেরি এটি করে।


জিনিসগুলির হার্ডওয়্যার-দিকটি এমনভাবে বোঝানোর দুর্দান্ত উপায় sense
ওগ্রে গীতসংহিতা 33

10

এটি একটি সি-ইসএম।

সি- compareটাইপ ফাংশন প্রয়োজন হলে , তারা সর্বদা একটি ফিরে আসে int। সি ++ সবেমাত্র এগিয়ে নিয়ে গেছে (দুর্ভাগ্যক্রমে)।

যাইহোক, একটি প্রত্যাবর্তন intসম্ভবত বাস্তবতম সম্ভবত দ্রুত পদ্ধতি, কারণ এটি সাধারণত ব্যবহৃত সিস্টেমের রেজিস্টারগুলির আকার। (ইচ্ছাকৃতভাবে অস্পষ্ট।)


1
প্রকৃতপক্ষে shortএবং charপারফরম্যান্স জরিমানা আরোপ করতে পারে, উদাহরণস্বরূপ এগুলির 255+7একটি আলাদা মূল্য রয়েছে charএবং intতাই সঠিক বাস্তবায়ন অযৌক্তিকভাবে কেবল charসেখানে সংরক্ষণ করতে পারে না যেখানে কোনও intতার শব্দার্থতাকে হস্তান্তর না করে যত্ন নিতে পারে। সংকলকগণ অগত্যা এটি চাপিয়ে দেওয়া অদক্ষতা অপ্টিমাইজ করবে না।
জ্যাক এইডলি

10

পদ্ধতিটি প্রকৃতপক্ষে সেটে কোনও পূর্ণসংখ্যা ফেরত দেয় না { -1, 0, 1 }; এটি আসলে যে কোনও হতে পারে অবিচ্ছেদ্য মান ।

কেন? আমি যে মূল কারণটি ভাবতে পারি তা intহ'ল এটি আর্কিটেকচারের জন্য "প্রাকৃতিক আকার" মান বলে মনে করা হয়; এই আকারের মানগুলির ক্রিয়াকলাপগুলি সাধারণত ছোট বা বৃহত্তর মানগুলির ক্রিয়াকলাপের চেয়ে কমপক্ষে দ্রুত (এবং অনেক ক্ষেত্রে দ্রুত) হয়। সুতরাং এটি বাস্তবায়নের ক্ষেত্রে পর্যাপ্ত ঝাঁকুনি যা দ্রুত হয় তা ব্যবহারের অনুমতি দেওয়ার একটি ক্ষেত্রে।


4

আমি যদি এমন একটি তুলনা পদ্ধতি ডিজাইন করতে পারি যা ফু টাইপের দুটি বস্তুর সাথে তুলনা করে এবং আমি কেবল -1, 0 বা 1 ফিরে আসতে চাইতাম, শর্ট বা চর ব্যবহার করা সাধারণত একটি ভাল ধারণা হবে?

এটা ঠিক ধারণা হবে। একটি ভাল উপায় হ'ল একটি বিল ফিরিয়ে আনা (কেবল সমান হলে তুলনা করতে চাই), বা এনাম (আরও তথ্যের জন্য):

enum class MyResult
{
  EQUAL,
  LESS,
  GREATER
};

MyResult AreEqual( const Foo &foo1, const Foo & foo2 )
{
  // calculate and return result
}

3
"এটা ঠিক ধারণা হবে"। আপনার কি এর পক্ষে যুক্তি আছে?
jrok

4

মনে করুন কিছু লোক সি থেকে সি ++ এ কোড পরিবর্তন করছে। তারা প্রতিস্থাপন strcmpকরার সিদ্ধান্ত নিয়েছে string::compare

যেহেতু strcmpরিটার্ন int, তাই উপহার হিসাবে string::compareফিরে আসা সহজ int


2

সম্ভবত এটি আরও বেশি কাজ করার জন্য এটিরও strcmpএই মানগুলি রয়েছে । আপনি যদি পোর্ট কোড করতে চান তবে প্রতিস্থাপনগুলি যতটা সম্ভব সম্ভব কাছাকাছি হওয়া আরও স্বজ্ঞাত হতে পারে।

এছাড়াও, রিটার্ন মানটি কেবল -1, 0বা 1তবে নয় <0, 0বা >0

এছাড়াও, যেমনটি উল্লিখিত ছিল যেহেতু প্রত্যাবর্তনটি অবিচ্ছেদ্য প্রচারের সাপেক্ষে এটি আরও ছোট করে তোলা মানে না make


-1

কারণ একটি বুলিয়ান রিটার্ন মানটি কেবল দুটি সম্ভাব্য মান (সত্য, মিথ্যা) হতে পারে এবং একটি তুলনা ফাংশন তিনটি সম্ভাব্য মান (এর চেয়ে কম, সমান, এর চেয়েও বেশি) প্রদান করতে পারে।

হালনাগাদ

একটি স্বাক্ষরিত সংক্ষিপ্ত ফিরিয়ে দেওয়া সম্ভব হলেও আপনি যদি সত্যিই নিজের তুলনা ফাংশনটি বাস্তবায়িত করতে চান তবে আপনি দুটি বুলিয়ান সহ একটি স্তনবৃন্ত বা স্ট্রাক্ট মান ফিরিয়ে দিতে পারেন।


7
প্রশ্নের কোথাও কোথাও এটি বুলিয়ান প্রকারটি ফেরত দেওয়ার বিষয়ে কিছু বলে না। আসলে, তিনি বিশেষভাবে প্রস্তাব shortএবং charবিকল্প হিসাবে int
কোডি গ্রে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.