লুপের জন্য '1' বাড়িয়ে যখন! = এর পরিবর্তে> (<) ব্যবহার করার কোনও প্রযুক্তিগত কারণ আছে?


198

আমি প্রায় কখনও এর forমতো লুপ দেখতে পাই না :

for (int i = 0; 5 != i; ++i)
{}

লুপে 1 বৃদ্ধি করে যখন ব্যবহার করার >বা <তার পরিবর্তে কোনও প্রযুক্তিগত কারণ আছে ? বা এই একটি কনভেনশন আরও?!=for


104
এটি এটিকে আরও পঠনযোগ্য করে তোলে, এছাড়াও, যদি আপনি কখনও (উদাহরণস্বরূপ) এ পরিবর্তন i++করেন তবে i+=2এটি খুব দীর্ঘ সময়ের জন্য (বা সম্ভবত চিরকালের জন্য) চলবে। এখন, যেহেতু আপনি সাধারণত <সেই ক্ষেত্রে ব্যবহার করেন যেখানে আপনি পুনরাবৃত্তিকে 1 এর বেশি করে বাড়িয়েছেন , আপনি <সেই ক্ষেত্রে যেখানে আপনি এটি 1 দ্বারা বাড়িয়েছেন তার জন্যও ব্যবহার করতে পারেন (ধারাবাহিকতার জন্য)।
বারাক মনোস

112
5 != iমন্দ
স্লাভা

27
আপনি যা করছেন সে সম্পর্কে আপনার সর্বদা সচেতন হওয়া উচিত তবে আপনি যেভাবেই ভুল করবেন। <ব্যবহার করে কেউ এই কোডটিতে একটি বাগ প্রবর্তনের সম্ভাবনা হ্রাস করে।
আরট

40
@ ওলেট্যাঞ্জ যদি আপনি ভাসমান পয়েন্ট সংখ্যা ব্যবহার করে পুনরাবৃত্তি করেন তবে আপনি ইতিমধ্যে খারাপ হয়ে
ক্যাপ্টেন কোডম্যান

29
@ স্লাভা ... মন্দ নয় not আপনি দৃশ্যত কখনো একটি সহজ দ্বারা সি বিট চলেছি মধ্যে পার্থক্য উপার্জন টাইপো if ( i == 5 ) ...এবং if ( i = 5 )। খুব আলাদা জিনিস। অপারেশনগুলিকে বিপরীত করা সমস্যাটি প্রতিরোধ করে: যেহেতু আক্ষরিক হয় না lvals, তাদের এপাইন করা যায় না এবং সংকলক টাইপোর উপরে ছুটে যায়। @ জিঙ্গাম: ভাল ডিফেন্সিভ প্রোগ্রামিং!
নিকোলাস কেরি

উত্তর:


303
while (time != 6:30pm) {
    Work();
}

সন্ধ্যা :31:৩০ টা ... ধুর, এখন আমার বাসায় যাওয়ার পরবর্তী সুযোগ আগামীকাল! :)

এটি দেখানোর জন্য যে শক্তিশালী বিধিনিষেধ ঝুঁকি হ্রাস করে এবং সম্ভবত এটি বোঝার জন্য আরও স্বজ্ঞাত।


25
কখনও কখনও, "ঝুঁকি প্রশমিত করতে" চেষ্টা করার পরে বাগটি লুকিয়ে রাখা শেষ হয়। যদি লুপটির নকশাটি অপরিবর্তিত থেকে সন্ধ্যা :30:৩০ অবসন্ন হওয়া উচিত, তবে ব্যাগটি <লুকিয়ে রাখবে তবে !=ব্যবহারটি এটি স্পষ্ট করে দেবে যে কোনও সমস্যা আছে।
অ্যাড্রিয়ান ম্যাকার্থি

27
@ অ্যাড্রিয়ানম্যাকার্থী: অগত্যা নয়; এটি কেবল একটি দ্বিতীয় বাগ প্রবর্তন করতে পারে, নির্ণয়কে আরও শক্ত করে তোলে ।
অরবিটে

4
@ অ্যাড্রিয়ানম্যাকার্থী: এটাই আমার বক্তব্য; আপনি এর কয়েকটি উদাহরণ থাকতে পারেন যা আপনি এখনও দেখেন নি;)
অরবিট-এ

6
আমার মনে হয় ইডিট্রেটরা হ'ল অ্যাড্রিয়ানএমসি কার্ডি পয়েন্টের একটি নিখুঁত উদাহরণ। তাদের জন্য প্রস্তাবিত তুলনাটি <= এর পরিবর্তে!
তাইকাহান

5
আমি ঠিক এই ত্রুটিটি দেখেছি (এবং এটি 3 মাসের ডিবাগিংয়ের কারণ ঘটেছে) - তবে এই উত্তরটি পুরোপুরি মিস করে। প্রদত্ত উদাহরণে শেষ শর্তটি মিস করা অসম্ভব । আপনি এমনকি বলতে পারেন যে সচেতনভাবে বেছে নেওয়া! = ওভার <হ'ল এই সত্যটির একটি দৃ a় দৃ as় বক্তব্য। এমন ঝুঁকি নিরসন করা যা নিশ্চিতভাবেই বিদ্যমান না আমার কাছে কোড গন্ধ। (এই কথাটি বলে, আপনি সমানভাবে তর্ক করতে পারেন যে <
মুশকিল is

95

কোন প্রযুক্তিগত কারণ আছে। তবে ঝুঁকি, রক্ষণাবেক্ষণযোগ্যতা এবং কোডের আরও ভাল বোঝার প্রশমন রয়েছে।

<বা >এর চেয়ে শক্তিশালী বিধিনিষেধ রয়েছে!= বেশিরভাগ ক্ষেত্রেই একই উদ্দেশ্যটি (আমি এমনকি সমস্ত ব্যবহারিক ক্ষেত্রে বলতে পারি)।

এখানে সদৃশ প্রশ্ন আছে ; এবং একটি আকর্ষণীয় উত্তর


6
কিছু প্রকার রয়েছে, যেমন পুনরাবৃত্তিকারীরা <বা> সমর্থন করে না তবে সমর্থন করে == এবং! =।
সাইমন বি

1
এটা দিয়ে লুপ জন্য একটি আছে int- এ । কোনও পুনরুক্তিকারী নেই।
এলী

7
"তবে ঝুঁকি, রক্ষণাবেক্ষণযোগ্যতা এবং কোড সম্পর্কে আরও ভাল বোঝার প্রশমন রয়েছে" " যার সবগুলিই সঠিকভাবে প্রযুক্তিগত কারণগুলি। :-)
টিজে ক্রোডার

@ টিজে ক্রাউডার আপনি যখন মেশিনগুলি ফলস্বরূপ কী করবে তা নিয়ে কথা বলতে চাইলে এটির কারণ কী?
ব্রিলিয়ানড

1
@ ড্যানশেপার্ড আমি সাধারণত ঝুঁকি এবং রক্ষণাবেক্ষণ প্রশমনকে ব্যবসায়িক কারণ হিসাবে বিবেচনা করব এবং কোডের আরও ভাল বোঝা সামাজিক কারণ হিসাবে বিবেচনা করব (যদিও এই কারণগুলিতে এই ক্ষেত্রে সমস্ত প্রযুক্তিগত ক্ষেত্রে প্রয়োগ করা হচ্ছে)। "ঝুঁকি হ্রাস" বিবেচনাগুলি কোনওভাবেই প্রযুক্তিগত বিষয়গুলিতে সীমাবদ্ধ নয় এবং "কোডের আরও ভাল বোঝার" বিবেচনাগুলি যদি আপনি নিজেকে বিভিন্ন গোষ্ঠীর সাথে কাজ করতে দেখেন তবে পরিবর্তন হতে পারে (এতে জড়িত মেশিনগুলি একেবারে পরিবর্তিত না হলেও) )।
ব্রিল্যান্ড

85

হ্যাঁ একটি কারণ আছে। আপনি যদি এর মতো লুপের জন্য একটি (প্লেইন পুরাতন সূচক ভিত্তিক) লিখেন

for (int i = a; i < b; ++i){}

তারপরে এটি কোনও মান aএবং b(যেমন শূন্য পুনরাবৃত্তির জন্য প্রত্যাশিত হিসাবে কাজ করে a > bযদি আপনি ব্যবহার করে থাকেন তবে অসীমের পরিবর্তে zeroi == b; ) ।

অন্যদিকে, পুনরাবৃত্তিকারীদের জন্য আপনি লিখতে চান

for (auto it = begin; it != end; ++it) 

কারণ যে কোনও পুনরাবৃত্তিকে একটি কার্যকর করা উচিত operator!=, তবে প্রতিটি পুনরুক্তির জন্য এটি সরবরাহ করা সম্ভবoperator<

লুপগুলির জন্যও পরিসীমা ভিত্তিক

for (auto e : v)

কেবল অভিনব চিনি নয়, তবে তারা ভুল কোড লেখার সম্ভাবনা হ্রাস করতে পারে।


4
চমৎকার উদাহরণ। আমি !=পরিবর্তে একটি ক্ষেত্রে আগ্রহী হতে হবে <। আমি ব্যক্তিগতভাবে কখনই ব্যবহার করি না যা আমি ভাবি।
এলী

@ এলিয়াসিন আমি খুব ভাল একটি খুঁজে পাইনি এবং আমি কোনও খারাপ পোস্টও করতে চাইনি: কল্পনা করুন আপনার কোনও ধরণের বৃত্তাকার ধারক রয়েছে, যেখানে আপনি কনটেইনার এন এর আকার + x মোডুলো দ্বারা বৃদ্ধি করেছেন এবং আপনি যখন লুপটি থামাতে চান একটি নির্দিষ্ট সূচী পৌঁছে .... ভাল একটি সত্যিই খারাপ উদাহরণ। সম্ভবত আমি আরও ভাল একটি
পেয়ে যাব

<! এর পরিবর্তে <! এর পরিবর্তে একই লুপটি এই প্রসঙ্গে <(বা>) এর সুবিধা কী তা তা পরিষ্কার করে দেয়। for (int i=a; i != b; i++) {}
পল স্মিথ

10
!=পুনরাবৃত্তকারীদের পাশাপাশি কিছু ব্যবহার করা বেশ বিপজ্জনক, কারণ কখনও কখনও পুনরাবৃত্তির তুলনায় তুলনামূলক কম হতে পারে (উদাহরণস্বরূপ এটি একটি পয়েন্টার) তবে তুলনা অর্থহীন (এটি একটি লিঙ্কযুক্ত তালিকা)।
ঝ্যান লিংস

1
গুরুত্ব সহকারে, সাদা স্থান ব্যবহার করতে শিখুন।
মাইলস রাউট

70

আপনার মতো কিছু থাকতে পারে

for(int i = 0; i<5; ++i){
    ...
    if(...) i++;
    ...
}

যদি আপনার লুপ ভেরিয়েবলটি অভ্যন্তরীণ কোড দ্বারা লিখিত হয়, তবে i!=5সেই লুপটি না ভাঙতে পারে। এটি অসমতার জন্য পরীক্ষা করা নিরাপদ।

পঠনযোগ্যতা সম্পর্কে সম্পাদনা করুন । অসমতার ফর্মটি প্রায়শই ব্যবহৃত হয়। অতএব, এটি পড়ার জন্য খুব দ্রুত কারণ এটি বোঝার জন্য বিশেষ কিছু নেই (কাজটি সাধারণ হওয়ার কারণে মস্তিষ্কের বোঝা হ্রাস হয়)। তাই পাঠকদের পক্ষে এই অভ্যাসটি ব্যবহার করা দুর্দান্ত।


6
এই ধরণের অভ্যন্তরীণ "যদি (শর্ত) থাকে তবে আমি ++" হ'ল প্রথম জিনিসটি যা আমি ভেবেছিলাম।
ওয়ার্নার সিডি

3
এটি সর্বোচ্চ ভোট প্রাপ্ত উত্তর বলে প্রত্যাশায় এসেছিল; আমি অবাক হয়েছি এটি সন্ধান করতে আমাকে এ পর্যন্ত স্ক্রোল করতে হয়েছিল। "আচ্ছা, আপনার সবচেয়ে শক্তিশালী শর্তটি ব্যবহার করা উচিত" এর চেয়ে নবীন প্রোগ্রামারকে বোঝানোর দিকে এটি আরও অনেক কিছু করে। অন্যান্য উত্তরগুলি, যদি তারা শীর্ষে থাকে তবে ওপির প্রস্তাবিত কোডটিতে কী ভুল হতে পারে তার একটি সুস্পষ্ট এবং সুস্পষ্ট ব্যাখ্যা হিসাবে এটিকে অন্তর্ভুক্ত করা উচিত।
মাউথ

1
@ মুখোমুখি আমি সম্পূর্ণরূপে একমত, তবে আমার পিওভি বেশ স্বার্থগত;)
জোহান ডি

3
@ মুখ যখন আমি অপ্রত্যাশিত উত্পাদনের আচরণটি আমার বাগগুলি প্রকাশ করে, তখন আমি এটি পছন্দ করি না? :-)
deworde

3
@ মাউস লুক, আমাদের যা করতে হবে তা হ'ল কখনই কোনও ভুল হয় না এবং সবকিছু ঠিক হয়ে যায়। Simples।
ডিফোর্ড

48

এবং সর্বশেষে তবে সর্বনিম্ন নয়, একে ডিফেন্সিভ প্রোগ্রামিং বলা হয় , যার অর্থ প্রোগ্রামটি প্রভাবিত করে বর্তমান এবং ভবিষ্যতের ত্রুটিগুলি এড়াতে সর্বদা সবচেয়ে শক্তিশালী কেস গ্রহণ করা।

একমাত্র ক্ষেত্রে যেখানে প্রতিরক্ষামূলক প্রোগ্রামিংয়ের প্রয়োজন হয় না, সেখানে রাজ্যগুলি প্রাক-শর্তাবলীর মাধ্যমে প্রমাণিত হয়েছে (তবে তারপরে এটি প্রমাণিত হয় যে এটি সমস্ত প্রোগ্রামিংয়ের মধ্যে সবচেয়ে প্রতিরক্ষামূলক)।


2
এর সমর্থনে একটি ভাল উদাহরণ: স্মৃতিটি বিকিরণের কারণে বিট ফ্লিপগুলি ( এসইইউ ) এর ঝুঁকির মধ্যে রয়েছে । intকোনও i != 15শর্তে ব্যবহার করার সময়, চতুর্থ বিটের উপরে কিছু উল্টানো থাকলে কাউন্টারটি দীর্ঘ সময়ের জন্য চলবে, বিশেষত যেখানে machines৪ টি মেশিনে sizeof(int)রয়েছে। উচ্চতর উচ্চতায় বা মহাকাশে (উচ্চ বিকিরণের কারণে) এসইইউগুলি একটি সত্যই উদ্বেগ , বা বড় সুপার কম্পিউটারগুলিতে (কারণ অনেক স্মৃতি উপস্থিত রয়েছে)।
জোশ সানফোর্ড

2
রেডিয়েশন যখন আপনার স্মৃতিশক্তি পরিবর্তন করবে তখন আপনার প্রোগ্রামটি ঠিক চলেছে এই ভেবে একটি আশাবাদী উপায় এবং অ্যান্টিক্যাটাস্ট্রোফিক চিন্তাভাবনার উপায় ... ভাল মন্তব্য! :)
লুইস কলোরাডো

37

আমি তর্ক করব যে মত একটি মতামত

for ( int i = 0 ; i < 100 ; ++i )
{
  ...
}

ইচ্ছার চেয়ে অভিপ্রায় ব্যক্তির চেয়ে বেশি অভিব্যক্তিপূর্ণ

for ( int i = 0 ; i != 100 ; ++i )
{
  ...
}

প্রাক্তনটি স্পষ্টভাবে কল করে যে শর্তটি একটি পরিসরে একচেটিয়া উপরের আবদ্ধের জন্য একটি পরীক্ষা; দ্বিতীয়টি একটি প্রস্থান শর্তের বাইনারি পরীক্ষা। এবং যদি লুপটির মূল অংশটি তুচ্ছ-তুচ্ছ হয় তবে এটি সূচকটি কেবলমাত্র forবিবৃতিতে পরিবর্তিত হয়েছে apparent


13
"আমি এই লুপটি সর্বোচ্চ 5 বার চালাতে চাই" বনাম। "আমি এই লুপটি ঠিক 5 বার বাদে প্রয়োজনীয় হিসাবে যতবার চালাতে চাই, যা আমি চাই না।"
বিশপ

একটি ব্যাপ্তির উপরের সীমাটি উল্লেখ করার জন্য +1। আমি মনে করি এটি সংখ্যা পরিসীমা জন্য গুরুত্বপূর্ণ। ! = এগুলির মতো লুপের জন্য একটি যথাযথ ব্যাপ্তি সংজ্ঞায়িত করে না
এলিমেন্ট 11

22

আপনি যখন প্রায়শই !=স্বরলিপি ব্যবহার করেন তখন ইলেটরগুলি একটি গুরুত্বপূর্ণ ক্ষেত্রে :

for(auto it = vector.begin(); it != vector.end(); ++it) {
 // do stuff
}

মঞ্জুর: বাস্তবে আমি একই উপর নির্ভর করে লিখব range-for:

for(auto & item : vector) {
 // do stuff
}

তবে বিন্দুটি রয়ে গেছে: একজন সাধারণত ==বা ব্যবহার করে পুনরাবৃত্তির তুলনা করে !=


2
আইট্রেটারদের প্রায়শই কেবল সাম্য / বৈষম্যের ধারণা থাকে এবং অর্ডার হয় না, এজন্য আপনি !=তাদের জন্য ব্যবহার করেন। উদাহরণস্বরূপ, একটিতে std::vectorআপনি ইটারেটরটি সূচক / পয়েন্টারের সাথে আবদ্ধ হিসাবে ব্যবহার করতে পারেন <তবে std::setএটিতে কোনও বাইনারি গাছের হাঁটাপথে কোনও কঠোর ক্রম নেই ing
মার্টিন সি

19

লুপ শর্তটি একটি বলপূর্বক লুপ আক্রমণকারী।

ধরুন আপনি লুপটির শরীরের দিকে তাকাবেন না:

for (int i = 0; i != 5; ++i)
{
  // ?
}

এই ক্ষেত্রে, আপনি জানেন যে লুপ পুনরাবৃত্তির iসমান নয় 5

for (int i = 0; i < 5; ++i)
{
  // ?
}

এই ক্ষেত্রে, আপনি iকম লুপ পুনরাবৃত্তির শুরুতে জানেন5

দ্বিতীয়টি অনেক, প্রথমের চেয়ে অনেক বেশি তথ্য, না? এখন, প্রোগ্রামারের অভিপ্রায়টি (প্রায় অবশ্যই) একই, তবে আপনি যদি বাগগুলি অনুসন্ধান করেন তবে কোডের একটি লাইন পড়ার আত্মবিশ্বাস রাখা ভাল জিনিস। এবং দ্বিতীয় প্রয়োগ যে পরিবর্তিত, যা কিছু বাগ আপনাকে প্রথমে ক্ষেত্রে দান্ত দিয়া ফুটা করা হবে মাত্র ঘটতে পারে না (বা মেমরি দুর্নীতি, বলে সৃষ্টি করে না) দ্বিতীয় ক্ষেত্রে মানে।

আপনি কম কোড পড়া থেকে, প্রোগ্রামের অবস্থা সম্পর্কে আরও জানেন <with!= । এবং আধুনিক সিপিইউগুলিতে তারা একই পরিমাণ সময় নেয় কোনও পার্থক্য হিসাবে।

যদি আপনার iলুপের বডিটিতে ম্যানিপুলেটেড না করা হয় এবং এটি সর্বদা 1 দ্বারা বৃদ্ধি করা হয়েছিল এবং এটি এর চেয়ে কম শুরু হয়েছিল5 তবে কোনও পার্থক্য হবে না। তবে এটি হেরফের হয়েছে কিনা তা জানতে, আপনাকে এই সত্যগুলির প্রত্যেকটি নিশ্চিত করতে হবে।

এর মধ্যে কয়েকটি সত্য তুলনামূলক সহজ, তবে আপনি ভুল করতে পারেন। লুপের পুরো শরীরটি পরীক্ষা করা অবশ্য একটি ব্যথা।

সি ++ তে আপনি indexesএমন টাইপ লিখতে পারেন যে:

for( const int i : indexes(0, 5) )
{
  // ?
}

উপরের দুটি forলুপগুলির মধ্যে একটির মতোই কাজ করে , এমনকি এটি একই কোডটিতে কমপ্লায়ার করে iler এখানে, তবে আপনি জানেন যে কোডটি কলুষিত মেমরি ছাড়াই iলুপের শরীরে ম্যানিপুলেট করা যায় না itconst

প্রসঙ্গটি না বুঝে কোডের একটি লাইন থেকে আপনি যত বেশি তথ্য পেতে পারেন, কী ভুল হচ্ছে তা সন্ধান করা আরও সহজ। <পূর্ণসংখ্যার লুপগুলির ক্ষেত্রে আপনাকে সেই লাইনে কোডের অবস্থা সম্পর্কে আরও তথ্য !=দেয়।


13

হ্যাঁ; ওপেনএমপি !=শর্তের সাথে লুপগুলিকে সমান্তরাল করে না ।


13

এটি ঘটতে পারে যে ভেরিয়েবলটি iকিছু বড় মানতে সেট করা থাকে এবং আপনি যদি কেবল !=অপারেটরটি ব্যবহার করেন তবে আপনি একটি অন্তহীন লুপে পৌঁছে যাবেন।


1
সত্যই অন্তহীন নয় - সি এর বেশিরভাগ বাস্তবায়নের ক্ষেত্রে, iসর্বাধিক যখন হয় তখন নিঃশব্দে তার চারপাশে মোড়ানো হবে। তবে হ্যাঁ, আপনি অপেক্ষা করার জন্য প্রস্তুত হওয়ার চেয়ে সম্ভবত দীর্ঘতর।
usr2564301

12

আপনি অন্যান্য অসংখ্য উত্তর থেকে দেখতে পাচ্ছেন, <ব্যবহারের পরিবর্তে! = ব্যবহার করার কারণ রয়েছে যা প্রান্তের ক্ষেত্রে, প্রাথমিক শর্তাদি, অযৌক্তিকভাবে লুপের পাল্টা পরিবর্তন, ইত্যাদিতে সহায়তা করবে ...

সত্যিই যদিও, আমি মনে করি না আপনি যথেষ্ট পরিমাণে সম্মেলনের গুরুত্বকে জোর দিতে পারেন can এই উদাহরণের জন্য অন্যান্য প্রোগ্রামারদের পক্ষে আপনি কী চেষ্টা করছেন তা দেখার পক্ষে সহজ হবে তবে এটি দ্বিগুণ গ্রহণের কারণ হবে। প্রোগ্রামিং করার সময় একটি কাজ এটিকে যতটা সম্ভব পঠনযোগ্য এবং প্রত্যেকের কাছে পরিচিত হিসাবে পরিচিত করে তোলা, সুতরাং অনিবার্যভাবে যখন কাউকে আপনার কোড আপডেট করতে / পরিবর্তন করতে হয় তখন আপনি বিভিন্ন কোড ব্লকে কী করছেন তা নির্ধারণ করার জন্য খুব বেশি প্রচেষ্টা গ্রহণ করতে হবে না । যদি আমি কাউকে ব্যবহার করতে দেখেছি !=, আমি ধরে নেব যে তারা এর পরিবর্তে এটি ব্যবহার করার কোনও কারণ ছিল <এবং যদি এটি একটি বড় লুপ হয় তবে আমি আপনাকে প্রয়োজনীয় জিনিসটি কী করেছে তা নির্ধারণের চেষ্টা করার জন্য পুরো জিনিসটি দেখব ... এবং এটিই নষ্ট সময়.


12

ইয়ান নিউজনের দ্বারা ইতিমধ্যে বলা হয়েছে, আপনি নির্ভরযোগ্যভাবে কোনও ভাসমান ভেরিয়েবলের উপরে লুপ করতে পারবেন এবং এর সাথে প্রস্থান করতে পারবেন না !=। এই ক্ষেত্রে,

for (double x=0; x!=1; x+=0.1) {}

প্রকৃতপক্ষে চিরকালের জন্য লুপ হয়ে যাবে, কারণ 0.1 ভাসমান পয়েন্টে হুবহু প্রতিনিধিত্ব করা যায় না, সুতরাং কাউন্টারটি সংকীর্ণভাবে মিস করে 1 দিয়ে < এটি শেষ হওয়ার ।

(তবে নোট করুন যে এটি মূলত অপরিবর্তিত আচরণ কিনা আপনি 0.9999 পেয়েছেন কিনা ... সর্বশেষ গৃহীত নম্বর হিসাবে - কোন ধরণের কম অনুমানের লঙ্ঘন করে - বা ইতিমধ্যে 1.0000000000000001 এ প্রস্থান করুন)


10

ভাষা আচরণ / তাত্পর্য এবং উত্পন্ন কোডের পারফরম্যান্সের মতো সংকলক পার্শ্ব প্রতিক্রিয়া বোঝাতে আমি সংযোজনীয় "প্রযুক্তিগত" নিই।

এই লক্ষ্যে, উত্তরটি হ'ল: না (*)। (*) হ'ল "দয়া করে আপনার প্রসেসরের ম্যানুয়ালটি পরামর্শ করুন"। আপনি যদি কিছু এজ-কেস আরআইএসসি বা এফপিজিএ সিস্টেমের সাথে কাজ করছেন, আপনাকে কোন নির্দেশাবলী উত্পন্ন এবং কী কী খরচ হবে তা খতিয়ে দেখার প্রয়োজন হতে পারে। কিন্তু আপনি যদি প্রায় কাছাকাছি কোনো প্রচলিত আধুনিক স্থাপত্য ব্যবহার করছেন, তারপর মধ্যে খরচের কোন উল্লেখযোগ্য প্রসেসর স্তর পার্থক্য নেই lt, eq, neএবং gt

যদি আপনি একটি প্রান্ত ক্ষেত্রে ব্যবহার করছেন আপনাকে খুঁজে পারে যে !=তিন কার্যকলাপ (প্রয়োজন cmp, not, beq) দুই বনাম ( cmp,blt xtr myo )। আবার সেই ক্ষেত্রে আরটিএম।

বেশিরভাগ ক্ষেত্রে, কারণগুলি রক্ষণাত্মক / শক্ত হওয়া, বিশেষত যখন পয়েন্টার বা জটিল লুপের সাথে কাজ করা হয়। বিবেচনা

// highly contrived example
size_t count_chars(char c, const char* str, size_t len) {
    size_t count = 0;
    bool quoted = false;
    const char* p = str;
    while (p != str + len) {
        if (*p == '"') {
            quote = !quote;
            ++p;
        }
        if (*(p++) == c && !quoted)
            ++count;
    }
    return count;
}

একটি সংক্ষিপ্ততর উদাহরণ হ'ল যেখানে আপনি ব্যবহারকারীর কাছ থেকে ডেটা গ্রহণ করে ইনক্রিমেন্টগুলি করতে রিটার্ন মানগুলি ব্যবহার করছেন:

#include <iostream>
int main() {
    size_t len = 5, step;
    for (size_t i = 0; i != len; ) {
        std::cout << "i = " << i << ", step? " << std::flush;

        std::cin >> step;
        i += step; // here for emphasis, it could go in the for(;;)
    }
}

এটি চেষ্টা করুন এবং 1, 2, 10, 999 মানগুলিকে ইনপুট করুন।

আপনি এটি প্রতিরোধ করতে পারেন:

#include <iostream>
int main() {
    size_t len = 5, step;
    for (size_t i = 0; i != len; ) {
        std::cout << "i = " << i << ", step? " << std::flush;
        std::cin >> step;
        if (step + i > len)
            std::cout << "too much.\n";
        else
            i += step;
    }
}

তবে আপনি সম্ভবত যা চেয়েছিলেন তা ছিল

#include <iostream>
int main() {
    size_t len = 5, step;
    for (size_t i = 0; i < len; ) {
        std::cout << "i = " << i << ", step? " << std::flush;
        std::cin >> step;
        i += step;
    }
}

একটি কনভেনশন পক্ষপাতেরও কিছু বিষয় রয়েছে <, কারণ স্ট্যান্ডার্ড পাত্রে অর্ডার করা প্রায়শই নির্ভর করে operator<, উদাহরণস্বরূপ বেশ কয়েকটি এসটিএল পাত্রে হ্যাশিং এই বলে সমতা নির্ধারণ করে

if (lhs < rhs) // T.operator <
    lessthan
else if (rhs < lhs) // T.operator < again
    greaterthan
else
    equal

যদি lhsএবং rhsকোনও ব্যবহারকারী সংজ্ঞায়িত শ্রেণি হয় তবে এই কোডটি লিখছেন

if (lhs < rhs) // requires T.operator<
    lessthan
else if (lhs > rhs) // requires T.operator>
    greaterthan
else
    equal

প্রয়োগকারী দুটি তুলনা ফাংশন প্রদান করতে হবে। তাই <পরিণত হয়েছে অপারেটর অপারেটর।


পঠনযোগ্যতার জন্য i + = পদক্ষেপটি নিয়ন্ত্রণের অংশে থাকা উচিত। যদি আপনি পদক্ষেপে = 0
মিক্কেল ক্রিশ্চেনসেন

1
যদিও এটি ভাল কোডের পাঠযোগ্যতায় সহায়তা করবে, আমি ভুল সংস্করণের ত্রুটির উপর জোর দিতে চেয়েছি
কেফসোন

9

যে কোনও ধরণের কোড (সাধারণত) লেখার বিভিন্ন উপায় রয়েছে, এই ক্ষেত্রে দুটি উপায় রয়েছে (যদি আপনি <= এবং> = গণনা করেন তবে তিনটি)।

এই ক্ষেত্রে, লোকেরা> এবং <কে নিশ্চিত করে তুলতে পছন্দ করে যে লুপে (বাগের মতো) কিছু অপ্রত্যাশিত ঘটনা ঘটলেও তা অসীমভাবে লুপ হবে না (বিএডি)। উদাহরণস্বরূপ নিম্নলিখিত কোডটি বিবেচনা করুন।

for (int i = 1; i != 3; i++) {
    //More Code
    i = 5; //OOPS! MISTAKE!
    //More Code
}

যদি আমরা (i <3) ব্যবহার করি তবে আমরা একটি অসীম লুপ থেকে নিরাপদ থাকব কারণ এটি আরও বড় বাধা রেখেছে।

আপনার প্রোগ্রামটি পুরো জিনিসটি বন্ধ করে দেওয়ার জন্য বা সেখানে বাগটি দিয়ে কাজ চালিয়ে যাওয়ার জন্য আপনার প্রোগ্রামটিতে কোনও ভুল চান কিনা তা সত্যিই আপনার পছন্দ।

আশা করি এটি সাহায্য করেছে!


কেউ যুক্তি দিতে পারে যে অসীম লুপটি ভুলের একটি ভাল সূচক হতে পারে তবে অন্য একটি যুক্তি দিয়ে বলবে যে i = 5 অগত্যা কোনও ভুল নয়
njzk2

7

ব্যবহারের সর্বাধিক সাধারণ কারণ <হ'ল কনভেনশন। আরও প্রোগ্রামাররা সূচক শেষ না হওয়া অবধি সূচকটি "পরিবর্তে" পরিবর্তে "এর চেয়ে বেশি থাকে" বলে লুপগুলি ভাবেন think আপনি করতে পারেন যখন কনভেনশনের মান মানা হয়।

অন্যদিকে, এখানে অনেক উত্তর দাবি করছে যে <ফর্মটি ব্যাগগুলি এড়াতে সহায়তা করে। আমি যুক্তি দিয়েছি যে অনেক ক্ষেত্রে এটি কেবল বাগগুলি আড়াল করতে সহায়তা করে । যদি লুপ সূচকটি শেষ মানটি পৌঁছানোর কথা বলে এবং এর পরিবর্তে এটি আসলে এর বাইরে চলে যায়, তবে এমন কিছু ঘটছে যা আপনি প্রত্যাশা করেননি যার ফলে কোনও সমস্যা দেখা দিতে পারে (বা অন্য কোনও বাগের পার্শ্ব প্রতিক্রিয়া হতে পারে)। <সম্ভবত বাগ আবিষ্কারের দেরী হবে। !=আরো একটি স্টল, Hang, অথবা এমনকি একটি ক্র্যাশ, যা আপনি বাগ শুভস্য স্পট সাহায্য করবে হতে পারে। যত তাড়াতাড়ি একটি বাগ পাওয়া যায়, এটি ঠিক করা সস্তা।

নোট করুন যে এই কনভেনশনটি অ্যারে এবং ভেক্টর সূচকের পক্ষে অদ্ভুত। প্রায় কোনও অন্য ধরণের ডেটা কাঠামোকে অনুসরণ করার সময়, আপনি একটি পুনরাবৃত্তকারী (বা পয়েন্টার) ব্যবহার করতে পারেন এবং একটি শেষ মানের জন্য সরাসরি যাচাই করতে পারেন। এই ক্ষেত্রে আপনাকে অবশ্যই নিশ্চিত হতে হবে যে পুনরুক্তিটি পৌঁছে যাবে এবং আসল শেষের মানটি ছাপিয়ে যাবে না।

উদাহরণস্বরূপ, আপনি যদি একটি সরল সি স্ট্রিংয়ের মধ্য দিয়ে পদক্ষেপ নিচ্ছেন তবে সাধারণত এটি লেখার পক্ষে আরও সাধারণ:

for (char *p = foo; *p != '\0'; ++p) {
  // do something with *p
}

চেয়ে

int length = strlen(foo);
for (int i = 0; i < length; ++i) {
  // do something with foo[i]
}

একটি জিনিসের জন্য, যদি স্ট্রিংটি খুব দীর্ঘ হয় তবে দ্বিতীয় রূপটি ধীর হবে কারণ strlenস্ট্রিংয়ের মধ্য দিয়ে এটি পাস করে।

C ++ std :: স্ট্রিংয়ের সাহায্যে আপনি দৈর্ঘ্য সহজেই উপলব্ধ থাকলেও লুপের জন্য একটি পরিসর-ভিত্তিক, একটি স্ট্যান্ডার্ড অ্যালগরিদম বা পুনরাবৃত্তকারী ব্যবহার করবেন। আপনি যদি পুনরাবৃত্তি ব্যবহার করছেন তবে কনভেনশনটি ব্যবহারের !=পরিবর্তে <, এর মতো:

for (auto it = foo.begin(); it != foo.end(); ++it) { ... }

একইভাবে, একটি গাছ বা একটি তালিকা বা একটি ডীক পুনরাবৃত্তি সাধারণত সূচক একটি পরিসীমা মধ্যে রয়ে গেছে কিনা তা পরীক্ষা করার পরিবর্তে নাল পয়েন্টার বা অন্য সেন্ডিনেলের জন্য জড়িত।


3
আপনি প্রোগ্রামিংয়ে মূর্খতার গুরুত্ব জোর দেওয়া ঠিক ঠিক। যদি আমি কিছু কোড দেখে থাকি এবং এটির একটি পরিচিত প্যাটার্ন থাকে তবে প্যাটার্নটি অনুমান করে আমার সময় নষ্ট করার দরকার নেই, তবে সরাসরি এটির মূলটিতে যেতে পারি। আমি অনুমান করি যে ইয়োদা তুলনাগুলির সাথে এটিই আমার মূল আকর্ষণ they এগুলি মূ .় মনে হয় না, তাই আমার মনে হয় তারা কী বোঝায় তা বোঝার জন্য আমি তাদের দু'বার পড়তে পেরেছি।
টবি স্পিড 22

7

এই নির্মাণটি ব্যবহার না করার একটি কারণ ভাসমান পয়েন্ট সংখ্যা। !=ভাসমানগুলির সাথে ব্যবহার করার জন্য এটি একটি অত্যন্ত বিপজ্জনক তুলনা কারণ এটি সংখ্যার মতো দেখা গেলেও এটি সত্যই খুব কমই মূল্যায়ন করবে। <বা >এই ঝুঁকি অপসারণ।


যদি আপনার লুপের পুনরাবৃত্তিটি একটি ভাসমান পয়েন্ট সংখ্যা হয় তবে !=বনাম <আপনার সমস্যাগুলির মধ্যে সর্বনিম্ন।
লন্ডিন

7

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

(1) কিছুটা বাড়াবাড়ি। প্রাকৃতিক ভাষায় আমরা সাধারণত কঠোরভাবে প্রয়োজনীয় কোডের চেয়ে বেশি তথ্য সরবরাহ করি, কোড সংশোধন করার ক্ষেত্রে ত্রুটির মতো। এখানে অতিরিক্ত তথ্য হ'ল লুপ ভেরিয়েবল i(দেখুন কীভাবে আমি এখানে অপ্রয়োজনীয়তা ব্যবহার করেছি? আপনি যদি 'লুপ ভেরিয়েবল' এর অর্থটি না জানতেন বা "লুপ ভেরিয়েবল i" পড়ার পরে আপনি যদি ভেরিয়েবলটির নাম ভুলে যান তবে আপনার সম্পূর্ণ তথ্য) লুপ চলাকালীন 5 এর চেয়ে কম হয়, 5 এর চেয়ে আলাদা নয় Red

(2) সম্মেলন। ভাষাগুলির নির্দিষ্ট পরিস্থিতি প্রকাশের নির্দিষ্ট মানক উপায় রয়েছে। আপনি যদি কিছু বলার প্রতিষ্ঠিত পদ্ধতি অনুসরণ না করেন তবে আপনি এখনও বুঝতে পারবেন তবে আপনার বার্তা প্রাপকের জন্য প্রচেষ্টা বেশি কারণ নির্দিষ্ট আশাবাদী কাজ করবে না। উদাহরণ:

হট ম্যাশের আশপাশে কথা বলবেন না। শুধু অসুবিধা আলোকিত!

প্রথম বাক্যটি হ'ল একটি জার্মান প্রবাদটির আক্ষরিক অনুবাদ। দ্বিতীয়টি প্রতিশব্দ দ্বারা প্রতিস্থাপিত মূল শব্দের সাথে একটি সাধারণ ইংরেজী প্রতিমা। ফলাফলটি বোধগম্য তবে এর চেয়ে বুঝতে অনেক বেশি সময় লাগে:

ঝোপের চারপাশে মারবেন না শুধু সমস্যাটি ব্যাখ্যা করুন!

প্রথম সংস্করণে ব্যবহৃত প্রতিশব্দ ইংরেজি আইডিয়ামের প্রচলিত শব্দের চেয়ে পরিস্থিতি আরও ভাল মানায় এমন ক্ষেত্রেও এটি সত্য। প্রোগ্রামাররা কোড পড়লে অনুরূপ বাহিনী কার্যকর হয়। এটি এমন কি কারণ 5 != iএবং যদি আপনি এমন পরিবেশে কাজ না করেন যেখানে এটি আরও স্বাভাবিক এবং এইভাবে অদলবদল করার মানসম্মত না হয় তবে5 > i এটি স্থাপনের অদ্ভুত উপায়গুলি । এই জাতীয় উপভাষাগুলি সম্প্রদায়ের অস্তিত্ব রয়েছে, কারণ সম্ভবত ধারাবাহিকতা প্রাকৃতিক তবে ত্রুটির প্রবণতার পরিবর্তে লিখতে সহজ মনে করে ।i != 5i < 55 == ii == 5


1
অজিজেইচনেট । একইভাবে, কেউ পরীক্ষাটি লিখবে না i < 17+(36/-3)(এমনকি এগুলি অন্য কোথাও ব্যবহৃত হয়; তখন অবশ্যই তাদের নামগুলি স্পষ্টতার জন্য লিখতে হবে !)।
usr2564301

6

এই জাতীয় ক্ষেত্রে সম্পর্কিত তুলনা ব্যবহার করা যে কোনও কিছুর চেয়ে জনপ্রিয় অভ্যাস habit এটি পুনরায় জনপ্রিয়তা অর্জন করেছিল যখন পুনরাবৃত্ত বিভাগগুলির মতো ধারণাগত বিবেচনা এবং তাদের তুলনীয়তা উচ্চ অগ্রাধিকার হিসাবে বিবেচিত হত না।

আমি বলব যে যখনই সম্ভব সামঞ্জস্য তুলনার তুলনায় সমতা তুলনা ব্যবহার করা পছন্দ করা উচিত, যেহেতু সমতার তুলনা মানগুলির তুলনায় মানগুলির তুলনায় কম প্রয়োজনীয়তা আরোপ করে। বিয়িং EqualityComparable থাকার চেয়ে একটি ক্ষুদ্রতর প্রয়োজন LessThanComparable

এই জাতীয় প্রেক্ষাপটে সমতা তুলনার বিস্তৃত প্রয়োগযোগ্যতার প্রমাণ দেয় এমন আরেকটি উদাহরণ হ'ল unsignedপুনরাবৃত্তিটি বাস্তবায়নের সাথে জনপ্রিয় ধাঁধা 0। এটি হিসাবে করা যেতে পারে

for (unsigned i = 42; i != -1; --i)
  ...

নোট করুন যে উপরেরটি স্বাক্ষরযুক্ত এবং স্বাক্ষরবিহীন পুনরাবৃত্তি উভয়ের ক্ষেত্রে সমানভাবে প্রযোজ্য, অপেক্ষাকৃত স্বাক্ষরযুক্ত প্রকারের সাথে সম্পর্কিত সংস্করণটি ভেঙে যায়।


2

উদাহরণগুলি ছাড়াও, যেখানে লুপ ভেরিয়েবল (অনিচ্ছাকৃত) দেহের অভ্যন্তরে পরিবর্তিত হবে, অপারেটরগুলির চেয়ে ছোট বা বৃহত্তর ব্যবহার করার জন্য অন্যান্য পদ্ধতি রয়েছে:

  • নেতিবাচকতাগুলি কোডগুলি বোঝা শক্ত করে তোলে
  • <বা >কেবল একটি চর, তবে !=দুটি

4
দ্বিতীয় বুলেট সেরা একটি অবুঝ কারণ। কোডটি সঠিক এবং পরিষ্কার হওয়া উচিত। কমপ্যাক্ট অনেক কম গুরুত্বপূর্ণ।
জোনাথন লেফলার

@ জোনাথনলফলার ওয়েল, একটি টিডিডি রিপলটিতে, অতিরিক্ত চরিত্রটি পার্স করার জন্য একটি অতিরিক্ত ন্যানো-সেকেন্ড এবং লেখার ফলে যে বাগটি পাওয়া গেছে তার সন্ধান করতে এক বিলিয়ন পুনরুক্তি হয়েছে 5 != $i, যা আমার জীবনের পুরো এক সেকেন্ড সময় নিয়েছিল। উহ ... স্নিকারক
বিশপ

1

এটি ঝুঁকি হ্রাস করে বলে উল্লেখ করা বিভিন্ন ব্যক্তি ছাড়াও এটি বিভিন্ন স্ট্যান্ডার্ড লাইব্রেরি উপাদানগুলির সাথে যোগাযোগের জন্য প্রয়োজনীয় ফাংশন ওভারলোডের সংখ্যাও হ্রাস করে। উদাহরণস্বরূপ, আপনি যদি নিজের প্রকারটি একটিতে স্ট্যাটিভড হতে চান std::setবা এর জন্য কী হিসাবে ব্যবহার করেন std::mapবা কিছু অনুসন্ধান এবং বাছাই করা অ্যালগরিদম ব্যবহার করেন তবে স্ট্যান্ডার্ড লাইব্রেরি সাধারণত std::lessবস্তুর তুলনা করতে ব্যবহার করে কারণ বেশিরভাগ অ্যালগরিদমে কেবল একটি কঠোর দুর্বল ক্রম প্রয়োজন । সুতরাং এটি <তুলনার পরিবর্তে তুলনাগুলি ব্যবহার করা ভাল অভ্যাস হয়ে যায় !=(যেখানে এটি অবশ্যই বোঝায়)।


1
আপনি ওভারলোডের সংখ্যায় সঠিক হতে পারেন, তবে অবজেক্টগুলির প্রয়োজনীয়তা বিবেচনা করার পরে প্রায় কোনও বস্তুর জন্য একজন !=অপারেটরকে সংজ্ঞায়িত করতে পারে , তবে একটি কঠোর দুর্বল ক্রম সংজ্ঞায়িত করা সর্বদা সম্ভব নয়। এই অর্থে !=আরও ভাল হবে, কারণ এটি ধরণের উপর কম প্রয়োজনীয়তা রাখে। যাইহোক, আমি এখনও সাথে থাকি <
idclev 463035818

0

সিনট্যাক্স দৃষ্টিকোণ থেকে কোনও সমস্যা নেই, তবে সেই অভিব্যক্তির পিছনে যুক্তিটি 5!=iযথাযথ নয়।

আমার মতে !=লুপের জন্য সীমানা নির্ধারণ করা যুক্তিযুক্তভাবে সাউন্ড নয় কারণ একটি লুপের জন্য হয় বার্ষিকী সূচককে বাড়িয়ে দেয় বা হ্রাস করে, সুতরাং পুনরাবৃত্তির জন্য লুপটি নির্ধারণ করা হবে যতক্ষণ না পুনরাবৃত্তির সূচকটি সীমা ছাড়িয়ে যায় (কোনও কিছুর !=জন্য) a যথাযথ বাস্তবায়ন

এটি কাজ করবে, তবে এটি খারাপ আচরণের ঝুঁকির সাথে যেহেতু !=একটি বর্ধিত সমস্যা ব্যবহার করার সময় সীমানা তথ্য হ্যান্ডলিং নষ্ট হয়ে গেছে (যার অর্থ আপনি যদি শুরু থেকে জানেন এটি যদি বৃদ্ধি হয় বা হ্রাস পায় তবে) এর পরিবর্তে !=এটি <>>==>ব্যবহার করা হয়।


2
যুক্তি পুরোপুরি ঠিক আছে। যখন iহয় 5লুপ করে প্রস্থান। তুমি কি অন্য কিছু বলতে চাও?
ড্যান গেটেজ

1
তাপের কারণে যদি ডেটাটি সঠিকভাবে স্থানান্তরিত না হয়, তবে বৈদ্যুতিন.চুম্বকীয় প্রভাবগুলি আপনার কোড চিরতরে চলে। আপনি যদি ইসিসি র‌্যাম সহ একটি নিয়মিত ওয়ার্কস্টেশন বা সার্ভারে এটি করেন তবে সমস্যা নেই (লজিক্যাল, প্রযুক্তিগত বা
শারীরিকও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.