{…} করার সময় (মিথ্যা)


125

আমি কোনও ব্যক্তির দ্বারা কিছু কোডের দিকে তাকিয়ে ছিলাম এবং লক্ষ্য করেছি যে তার ফাংশনগুলিতে একটি প্যাটার্ন রয়েছে:

<return-type> function(<params>)
{
 <initialization>

 do
 {
   <main code for function>
 }
 while(false);

 <tidy-up & return>
}

এটি খারাপ নয় , আরও অদ্ভুত (আসল কোডটি বেশ ঝরঝরে এবং উদ্বেগজনক)। এটি এমন কিছু নয় যা আমি এর আগে দেখেছি এবং আমি ভাবছিলাম যে কেউ যদি এর পিছনে কোনও যুক্তি সম্পর্কে চিন্তা করতে পারে - তবে ভিন্ন ভাষায় ব্যাকগ্রাউন্ড হতে পারে?


2
আপনি কি এটি "সাধারণ" সংস্করণে পরিবর্তন করার চেষ্টা করেছেন এবং এটি এখনও সংকলন করেছেন কিনা তা দেখার চেষ্টা করেছেন? এটি সাধারণত লেখার সময় সংকলন করতে ব্যর্থ হলে, সংকলক ত্রুটিটি কেন এটি করা হয়েছিল তা সম্পর্কে একটি সূত্র দিতে পারে।
মার্ক বাইয়ার্স

11
কেন আমাদের উদ্দেশ্য সম্পর্কে অনুমান জিজ্ঞাসার চেয়ে "ব্যক্তি" জিজ্ঞাসা করবেন না?

1
হতে পারে তার অধ্যাপকের প্রয়োজন ছিল সে একটি ব্যবহার করবে do...while()এবং সেই কোডটি সেহেতু সেটিকে একটি ফাংশন টেম্পলেট হিসাবে ব্যবহার করেছে।
হোগান

6
@ নীল ... আমি যখন তার মুখোমুখি হই তখন আমি বোবা দেখা এড়াতে চাই এবং তিনি যে সুপার-অ্যাডভান্সড সি ++ ব্যবহারের কথা কখনও ভাবেননি সে সম্পর্কে তিনি ব্যাখ্যা করেন।
মিঃ বয়

6
ইতিমধ্যে বেশ কয়েকটি পৃথক উত্তর রয়েছে বলে মনে হচ্ছে, আপনি কি মূল লেখককে তাদের উদ্দেশ্য কী তা জিজ্ঞাসা করতে পারেন এবং ফিরে পোস্ট করতে পারেন?
nevets1219

উত্তর:


174

আপনি breakবাইরে পারেন do{...}while(false)


95
+1 কারণ এটি সম্ভবত কোডের উদ্দেশ্য, তবে এরকম কিছু করা কেবল একটি বোকামি ছদ্মবেশী গোটো। যদি আপনি মনে করেন যে কাজের জন্য কোনও গোটো হ'ল সঠিক সরঞ্জাম, তবে আপনার কেবল একটি # $ (* # @ @
গোটো

55
এটি একটি ছদ্মবেশী গোটো চেয়ে বেশি। এটি একটি সীমাবদ্ধ (কাঠামোগত) গোটো।
টমাস এডিং

19
কীভাবে এটি "সীমাবদ্ধ"? কেবল সামনের দিকে ঝাঁপিয়ে পড়া খুব কমই "সীমাবদ্ধতা"। গোটো একটি গোটো, এবং এটিকে সাজানোর জন্য এটি সাজানোর জন্য এটি প্রথমে গুটো ব্যবহারের চেয়ে খারাপ নয়।
আনন

44
@ অ্যান .: ফরোয়ার্ডে ঝাঁপ দেওয়া গোটোয়ের উপর একটি বিধিনিষেধ এবং জাম্পিং-আউট লাফানো অবশ্যই একটি বিধিনিষেধ। গোটোসের সাথে আসল সমস্যাটি হ'ল স্প্যাগেটি কোড এবং একটি ফরোয়ার্ড এবং আউট জাম্প সীমাটি যা ব্যাপকভাবে।
ডেভিড থর্নলি

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

125

অনেক লোক ইঙ্গিত করে যে এটি প্রায়শই বিরতিতে "গোটো" লেখার এক বিশ্রী পদ্ধতি হিসাবে ব্যবহৃত হয়। এটি সরাসরি ফাংশনে লেখা থাকলে এটি সম্ভবত সত্য।

ম্যাক্রোতে ওটিওএইচ, ম্যাক্রো অনুরোধের পরে অর্ধিকোলন কাটা do { something; } while (false)করার একটি সুবিধাজনক উপায়, অন্য কোনও টোকেন অনুসরণ করার অনুমতি নেই।

এবং আরেকটি সম্ভাবনা হ'ল এখানে একবার লুপ ছিল বা পুনরাবৃত্তি ভবিষ্যতে যোগ করার পূর্বে প্রত্যাশিত ছিল (যেমন পরীক্ষার দ্বারা চালিত বিকাশে, পরীক্ষাগুলি পাস করার জন্য পুনরাবৃত্তির প্রয়োজন ছিল না, তবে যৌক্তিকভাবে এটি লুপটি বোঝাতে সক্ষম হবে যদি বর্তমানে প্রয়োজনের তুলনায় ফাংশনটি কিছুটা বেশি সাধারণ হওয়া দরকার)


18
ম্যাক্রোগুলিতে এর ইউটিলিটি উল্লেখ করার জন্য +1; আমি অবাক হয়েছি আর কারও উল্লেখ নেই!
নিক মায়ার

7
হ্যাঁ, ম্যাক্রো জিনিসটি এটির পুরোপুরি বৈধ ব্যবহার। অবশ্যই, ম্যাক্রোর বাইরে, এটি কেবল নির্বোধ ...;)
জলফ

12
এটি বিশ্রী নয়, এটি দরকারী, কারণ এটি একটি স্কোপড গোটো - এর অর্থ হ'ল ডু লুপে আপনি যে কোনও ভেরিয়েবল ঘোষণা করেন তা ধ্বংস হয়ে যায়, যদিও গোটো তা করে না।
আনা বেটস

9
@ পল: গোটো দিয়ে এই আচরণকে বাধ্য করার জন্য আপনাকে কিছু কিছু বিবৃতিতে ব্রেস যোগ করতে বাধা দেয় না।
এরিক্ক্যালেন

5
@ পল: একটি ব্লকের বাইরে চলে যাওয়ার ফলে অবশ্যই স্থানীয় পরিবর্তনগুলি সি ++ এ নষ্ট হওয়ার কারণ হয়ে যায় break এবং সি ভেরিয়েবলগুলি সত্যই ধ্বংস হয় না, তাদের স্ট্যাকের স্থানটি সহজেই পুনরুদ্ধার করা হয়।
বেন ভয়েগ্ট

25

গোটো হিসাবে বিরতি সম্ভবত উত্তর, তবে আমি অন্য একটি ধারণা সামনে রাখব।

সম্ভবত তিনি স্থানীয়ভাবে সংজ্ঞায়িত ভেরিয়েবলগুলি রাখতে চেয়েছিলেন এবং একটি নতুন সুযোগ পাওয়ার জন্য এই নির্মাণটি ব্যবহার করেছিলেন।

মনে রাখবেন যে সাম্প্রতিক সি ++ {...}যে কোনও জায়গায় অনুমতি দেয় , এটি সর্বদা ক্ষেত্রে ছিল না।


30
সেক্ষেত্রে তিনি কেবল কোঁকড়ানো ধনুর্বন্ধনী ব্যবহার করতে পারতেন।
নেমানজা ত্রিফুনোভিচ

2
@ নেমানজা, আপনি কতজন বিকাশকারী তা জানেন না এবং আপনি হোগান যে পরামর্শ
দিচ্ছেন

8
@ পোলারিস @ নেমঞ্জা, আমি সি / সি ++ তে 4 বছর বয়সের মতো প্রোগ্রামিং করছিলাম ততক্ষণ এটি ছিল না যে আপনি বুঝতে পেরেছিলেন যে আপনি {} যে কোনও জায়গায় একটি নতুন স্থানীয় সুযোগ তৈরি করতে পারেন .. এটি switch-caseকোডে বিশেষভাবে কার্যকর
আর্লজ

1
@ নিমঞ্জা: আমি ঠিক কখন জানি না, তবে আমি নিশ্চিত যে {...}কোথাও কোথাও সি ++ এর আরও আধুনিক বিকাশ রয়েছে (মনে রাখবেন যে প্রথম সি ++ আমি প্রি-প্রসেসর দিয়ে প্রয়োগ করেছি এবং এটি এই আধুনিক ব্যবহারের অনুমতি দেয়নি।) সম্ভবত লেখক ঠিক পুরানো স্কুল ছিল।
হোগান

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

20

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

এটি যদি ক্লান্তিকর হয়ে উঠতে পারে তবে / অন্যথায়-যদি গাছটি পড়া খুব সহজ হয়, তবে যখনই কোনও প্রস্থান পয়েন্ট পৌঁছায় কেবল তখনই ভেঙে যেতে হবে, তারপরে বাকী যুক্তিযুক্ত ইনলাইনটি রেখে।

এই প্যাটার্নটি এমন ভাষাগুলিতেও কার্যকর যাগুলির গোটো স্টেটমেন্ট নেই। সম্ভবত সেখানেই মূল প্রোগ্রামারটি প্যাটার্নটি শিখেছে।


15
তারপরে পাতলা ছদ্মবেশী গোটোর পরিবর্তে কেবল একটি সৎ, সরল গোটো ব্যবহার করুন।
dsimcha

4
আমি এইভাবে ভাল পছন্দ। এটি পড়া সহজ এবং গোটো এর কলঙ্ক বহন করে না।
ক্যামেরন

8
স্বল্প ও স্থানীয়ভাবে যদি ব্যবহার করা হয় তবে গোটস পড়তে পুরোপুরি সহজ। তারা প্রবাহ নিয়ন্ত্রণের প্রধান ফর্ম এবং শত শত লাইন পেরিয়ে যখন লাফিয়ে উঠছিল তখন তারা পিছন থেকে তাদের কলঙ্ক পেয়েছিল।
dsimcha

13
"কলঙ্কের কারণে" গোটো ব্যবহার না করা কার্গো-কাল্ট প্রোগ্রামিংয়ের একটি নিশ্চিত লক্ষণ।
আনন

6
পরিষ্কার নয় যে প্রচুর পরিচ্ছন্নতার কোডের দুর্গন্ধ mention এটি সি ++ হ'ল, ক্লিনআপ কোডটি সাধারণত রাই প্রসেসিংয়ের সময় ডাস্টস্ট্রাক্টরে থাকা উচিত।
ডেভিড থর্নলি


10

whileগোটো goto tidy-upশব্দটি ব্যবহার না করেই এর সিমেটিক্স অর্জনের এটি কেবল একটি বিকৃতি is

এটা খারাপ ফর্ম কারণ যখন আপনি ব্যবহার অন্যান্য বাইরের ভিতরে লুপ পাঠক দ্ব্যর্থক হয়ে। "এটি কি প্রস্থান করার কথা? নাকি এটি কেবল অভ্যন্তরীণ লুপটি ভেঙে ফেলার জন্যই উদ্দেশ্য?"whilebreaks


10

আমি মনে করি এটি breakপরিবর্তে লিখতে আরও সুবিধাজনকgoto end । এমনকি আপনি লেবেলের জন্য এমন কোনও নামও চিন্তা করতে হবে না যা উদ্দেশ্যটি আরও পরিষ্কার করে দেয়: আপনি কোনও নির্দিষ্ট নামের সাথে কোনও লেবেলে ঝাঁপিয়ে পড়তে চান না। আপনি এখান থেকে উঠতে চান

সম্ভাবনা হ'ল যাইহোক আপনার ধনুর্বন্ধনী প্রয়োজন হবে। সুতরাং এটি do{...}while(false);সংস্করণ:

do {
   // code
   if (condition) break; // or continue
   // more code
} while(false);

আপনি যদি এটি ব্যবহার করতে চান তবে আপনাকে এটি প্রকাশ করতে হবে goto:

{
   // code
   if (condition) goto end;
   // more code
}
end:

আমি মনে করি প্রথম সংস্করণটির অর্থ বোঝা আরও সহজ। এছাড়াও এটি লেখার পক্ষে সহজ, প্রসারিত করা সহজ goto, সমর্থন করে না এমন ভাষায় অনুবাদ করা সহজ ইত্যাদি etc.


ব্যবহার সম্পর্কে সর্বাধিক উল্লিখিত উদ্বেগ breakহ'ল এটি একটি খারাপভাবে ছদ্মবেশ ধারণ করেছে goto। তবে আসলে এর breakসাথে আরও সাদৃশ্য রয়েছে return: উভয় নির্দেশাবলীর তুলনায় তুলনামূলকভাবে অনেকটা কাঠামোগত কোডের একটি ব্লক থেকে ঝাঁপ দাও goto। তবুও উভয় নির্দেশাবলী কোডের একটি ব্লকে একাধিক প্রস্থান পয়েন্টগুলিকে অনুমতি দেয় যা কখনও কখনও বিভ্রান্ত হতে পারে। সর্বোপরি আমি সর্বাধিক স্পষ্ট সমাধানের জন্য চেষ্টা করব, যা নির্দিষ্ট পরিস্থিতিতে রয়েছে।


ওহ, আমি কেবল লক্ষ্য করেছি যে উত্তর দেওয়ার আগে আমি পুরোপুরি প্রশ্নটি বুঝতে পারি না। আমি ভেবেছিলাম এটি do{ ... }while(false);সাধারণভাবে ব্যবহার সম্পর্কে । তবে আসলে এটি কোনওরকম অনুকরণ করার জন্য এটি ব্যবহার করার বিষয়ে try{ ... }finally{ ... }
রবার্ট

গোটো না হয়ে ব্রেক এবং রিটার্নের মধ্যে সমান্তরাল সম্পর্কে ভাল পর্যবেক্ষণ। সম্মত হন যে সবচেয়ে পরিষ্কার সমাধান সবচেয়ে ভাল। বেশিরভাগ ক্ষেত্রে এটির নিজস্ব আলাদা ফাংশনে কোডটি এনক্যাপসুলেট করা সম্ভবত পরিষ্কার হয় যা বিরতির পরিবর্তে রিটার্ন ব্যবহার করে এবং তারপরে কলিং ফাংশনে ক্লিনআপ করে।
উত্তোলন করুন

7

এই কৌশলটি প্রোগ্রামাররা ব্যবহার gotoকরেন যা তাদের কোডে একটি স্পষ্ট ব্যবহার করতে খুব লজ্জাজনক । উপরের কোডটির লেখক কোডের মাঝামাঝি থেকে সরাসরি "ক্লিনআপ এবং ফিরে" পয়েন্টে ঝাঁপিয়ে পড়ার ক্ষমতা অর্জন করতে চেয়েছিলেন। তবে তারা কোনও লেবেল এবং স্পষ্টত ব্যবহার করতে চায় নি goto। পরিবর্তে, তারা breakএকই প্রভাব অর্জন করতে উপরের "নকল" চক্রের দেহের অভ্যন্তরে কোনও অভ্যন্তর ব্যবহার করতে পারে।


7

এটি একটি খুব সাধারণ অনুশীলন। ইন সি । আমি এটিকে ভাববার চেষ্টা করি যেন আপনি নিজেকে "আমি ব্যবহার করি না" এমনভাবে মিথ্যা বলতে চান goto। এটি সম্পর্কে চিন্তা করে, এ এর ​​সাথে কোনও ভুল হবে নাgoto একইভাবে ব্যবহৃত ব্যবহারে । আসলে এটি ইনডেন্টেশন স্তর হ্রাস করবে।

এটি বলেছিল, যদিও, আমি লক্ষ্য করেছি, খুব প্রায়শই এই do..whileলুপগুলি বৃদ্ধি পেতে থাকে। এবং তারপরে তারা ifএস এবং elseএস ভিতরে পাবে, কোডটি খুব বেশি পঠনযোগ্য নয় এমনভাবে রেন্ডারিং করে, পরীক্ষার জন্য ছেড়ে দেওয়া হোক।

do..whileসাধারণত একটি কি উদ্দেশ্যে করা হয় ক্লিন-আপ । সমস্ত উপায়ে সম্ভব আমি আরএআইআই ব্যবহার করতে পছন্দ করব এবং একটি সংক্ষিপ্ত ফাংশন থেকে তাড়াতাড়ি ফিরে আসব । অন্যদিকে, সি আপনাকে পরিচ্ছন্নতা করার জন্য সেরা পদ্ধতির একটি তৈরি করে, সি ++ এর মতো সুবিধা দেয় না ।do..while


6

এটি দেখতে একজন সি প্রোগ্রামারের মতো। সি ++ এ, স্বয়ংক্রিয় ভেরিয়েবলগুলির ডেস্ট্রাক্টর রয়েছে যা আপনি পরিষ্কার করতে ব্যবহার করেন, সুতরাং ফিরে আসার আগে আর কিছু দেওয়ার দরকার নেই। সি-তে, আপনার এই আরআইআইআই প্রবাদ নেই, সুতরাং আপনার যদি সাফ সাফল্যের কোড থাকে তবে আপনি gotoএটি ব্যবহার করেন বা উপরে হিসাবে একবারের মাধ্যমে লুপ ব্যবহার করেন।

সি ++ ইডিয়মের তুলনায় এর প্রধান অসুবিধা হ'ল যদি কোনও ব্যতিক্রম শরীরে ফেলে দেওয়া হয় তবে এটি পরিষ্কার করা হবে না। সি এর ব্যতিক্রম ছিল না, সুতরাং এটি কোনও সমস্যা ছিল না, তবে এটি সি ++ এ এটির একটি খারাপ অভ্যাস তৈরি করে।


4

বিভিন্ন ব্যাখ্যা। প্রথমটি সাধারণ, দ্বিতীয়টি প্যারামিটার সহ সি প্রিপ্রোসেসর ম্যাক্রোগুলির সাথে নির্দিষ্ট:

প্রবাহ নিয়ন্ত্রণ

আমি এটি প্লেইন সি কোডে ব্যবহার করে দেখেছি। মূলত, এটি গোটোর একটি নিরাপদ সংস্করণ, কারণ আপনি এটিটি ভেঙে ফেলতে পারেন এবং সমস্ত স্মৃতি সঠিকভাবে পরিষ্কার হয়ে যায়।

gotoভালো কিছু হবে কেন ? ওয়েল, যদি আপনি কোড প্রায় কাছাকাছি যেখানে প্রত্যেক লাইন একটি ত্রুটি আসতে পারেন, কিন্তু আপনি তাদের সব একই ভাবে প্রতিক্রিয়া প্রয়োজন (যেমন হস্তান্তর পরিষ্কার আপ করার পর আপনার আহ্বানকারী ত্রুটির দ্বারা), এটি সাধারণত আরো পাঠযোগ্য একটি এড়াতে এর if( error ) { /* cleanup and error string generation and return here */ }যেমন এটি ক্লিন-আপ কোডটির সদৃশতা এড়িয়ে চলে।

যাইহোক, সি ++ এ আপনার ঠিক এই উদ্দেশ্যে ব্যতিক্রম আছে + আরআইআইআই, সুতরাং আমি এটিকে খারাপ কোডিং শৈলী বিবেচনা করব।

সেমিকোলন চেকিং

যদি আপনি কোনও ফাংশনের মতো ম্যাক্রো অনুরোধের পরে সেমিকোলনটি ভুলে যান তবে যুক্তিগুলি অনাকাঙ্ক্ষিত উপায়ে চুক্তি করতে পারে এবং বৈধ বাক্য গঠনতে সংকলন করতে পারে। ম্যাক্রো কল্পনা করুন

#define PRINT_IF_DEBUGMODE_ON(msg) if( gDebugModeOn ) printf("foo");

এটিকে দুর্ঘটনাক্রমে বলা হয়

if( foo )
    PRINT_IF_DEBUGMODE_ON("Hullo\n")
else
    doSomethingElse();

"অন্য" সাথে যুক্ত করার বিবেচনা করা হবে gDebugModeOn, তাই যখন fooহয় false, সঠিক কি ঘটবে জন্যই ছিল এর বিপরীত।

অস্থায়ী ভেরিয়েবলের জন্য সুযোগ সরবরাহ করা।

যেহেতু কর / যখন কোঁকড়া ধনুর্বন্ধনী রয়েছে, অস্থায়ী ভেরিয়েবলগুলির স্পষ্টভাবে সংজ্ঞায়িত সুযোগ থাকে যে তারা পালাতে পারে না।

"সম্ভবত অবাঞ্ছিত সেমিকোলন" সতর্কতা এড়ানো

কিছু ম্যাক্রো কেবল ডিবাগ বিল্ডগুলিতে সক্রিয় হয়। আপনি তাদের এগুলি সংজ্ঞায়িত করুন:

#if DEBUG
#define DBG_PRINT_NUM(n) printf("%d\n",n);
#else
#define DBG_PRINT_NUM(n) 
#endif

এখন আপনি যদি এটি শর্তাধীন অভ্যন্তরে কোনও রিলিজ বিল্ডে ব্যবহার করেন তবে এটি সংকলন করে

if( foo )
    ;

অনেক সংকলক এটিকে একই হিসাবে দেখেন

if( foo );

যা প্রায়শই দুর্ঘটনাক্রমে লেখা হয়। সুতরাং আপনি একটি সতর্কতা পেতে। (মিথ্যা) এইটি সংকলকটি থেকে লুকিয়ে রাখে এবং আপনি সত্যিকার অর্থে এখানে কিছুই করতে চান না এমন ইঙ্গিত হিসাবে এটি দ্বারা গৃহীত হয় ।

শর্তসাপেক্ষে লাইনগুলি ক্যাপচার করা এড়ানো

পূর্ববর্তী উদাহরণ থেকে ম্যাক্রো:

if( foo )
    DBG_PRINT_NUM(42)
doSomething();

এখন, একটি ডিবাগ বিল্ডে, যেহেতু আমরা অভ্যাসগতভাবে সেমিকোলনটিও অন্তর্ভুক্ত করেছি, এটি ঠিকঠাক সংকলন করে। তবে রিলিজের বিল্ডটি হঠাৎ করে এটিকে রূপান্তরিত করে:

if( foo )

doSomething();

বা আরও পরিষ্কারভাবে ফর্ম্যাট করা

if( foo )
    doSomething();

যা উদ্দেশ্য ছিল তা মোটেই নয়। ম্যাক্রোর চারপাশে একটি (false ...}) যুক্ত করা নিখোঁজ অর্ধপরিবাহকে একটি সংকলন ত্রুটিতে পরিণত করে।

ওপি এর অর্থ কী?

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


স্কোপিং সম্পর্কিত, আপনার লুপ সরঞ্জামের প্রয়োজন নেই; একটি "অনলঙ্কৃত" ব্লক আইনি হল: x =1; y = 2; { int tmp = y; y = x; x = tmp; }
চিপনার

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

ম্যাক্রোর আরও ভাল সংজ্ঞা প্রদান করে কি এড়ানো যায় না? #define DBG_PRINT_NUM(n) {}
চিপনার

1
না, কারণ {} একটি সম্পূর্ণ বিবৃতি, অর্থাৎ ""; "এর সমতুল্য। সুতরাং আপনি লিখলে if(a) DBG_PRINT_NUM(n); else other();এটি সংকলন হবে না। কেবল if(a) {} else other();বা if(a) ; else other();বৈধ, তবে if(a) {}; else other();তা নয়, কারণ এটি "যদি" ধারাটি দুটি বিবৃতি নিয়ে গঠিত।
uliwitness

2

হতে পারে এটি ব্যবহার করা হয়েছে যাতে breakকোনও কোডে আরও কোডের প্রয়োগ বাতিল করতে অভ্যন্তরে ব্যবহার করা যেতে পারে:

do {
    if (!condition1) break;
    some_code;
    if (!condition2) break;
    some_further_code;
    // …
} while(false);

7
এমনটি করা যেন gotoকেউ এটিকে "খারাপ" শুনেছেন কেবল তা ব্যবহার করা এড়ানোর চেষ্টা বলে মনে হচ্ছে ।
আনন

1
সম্ভবত, তবে সি ++ এর এই কারণেই ব্যতিক্রম রয়েছে।
টেড


2

এটি সহজ: স্পষ্টতই আপনি breakবিবৃতিটি ব্যবহার করে যে কোনও সময় নকল লুপ থেকে ঝাঁপিয়ে যেতে পারেন । তদতিরিক্ত, doব্লকটি একটি পৃথক সুযোগ (যা কেবলমাত্র দিয়েও অর্জন করা যেতে পারে { ... })।

এমন পরিস্থিতিতে, RAII (ফাংশন শেষ হয়ে গেলে স্বয়ংক্রিয়ভাবে সঠিকভাবে ধ্বংসকারী বস্তু) ব্যবহার করা ভাল ধারণা হতে পারে। আর একটি অনুরূপ নির্মাণের ব্যবহার হ'ল goto- হ্যাঁ, আমি জানি এটি খারাপ , তবে এটির মতো সাধারণ ক্লিনআপ কোড ব্যবহার করতে ব্যবহার করা যেতে পারে:

<return-type> function(<params>)
{
 <initialization>

 <main code for function using "goto error;" if something goes wrong>

 <tidy-up in success case & return>

 error:

 <commmon tidy-up actions for error case & return error code or throw exception>
}

(একদিকে যেমন: লুয়ায় অনুপস্থিত continueবিবৃতি প্রকাশের জন্য ডু-উইল মিথ্যা কনস্ট্রাক্ট ব্যবহৃত হয় ))


2

অনেক উত্তরদাতাই এর কারণ দিয়েছেন do{(...)break;}while(false)। আমি ছবিটির আরও একটি বাস্তব জীবনের উদাহরণ দ্বারা পরিপূরক চাই।

নিম্নলিখিত কোডে আমাকে পয়েন্টার operationদ্বারা নির্দেশিত ঠিকানার ভিত্তিতে গণক সেট করতে হয়েছিল data। কারণ একটি স্যুইচ-কেস কেবলমাত্র স্কেলার প্রকারে ব্যবহার করা যেতে পারে আমি প্রথমে এটি অদক্ষভাবে এটি করেছি

if (data == &array[o1])
    operation = O1;
else if (data == &array[o2])
    operation = O2;
else if (data == &array[on])
    operation = ON;

Log("operation:",operation);

তবে যেহেতু লগ () এবং বাকী কোড অপারেশনের জন্য নির্বাচিত কোনও মানটির পুনরাবৃত্তি করে আমি ঠিক তখনই ঘোরাফেরা করছিলাম যখন ইতিমধ্যে ঠিকানাটি সন্ধান করা হয়ে গেছে তখন কীভাবে বাকি তুলনাগুলি এড়ানো যায়। এবং এই যেখানে কাজ do{(...)break;}while(false)আসে।

do {
    if (data == &array[o1]) {
        operation = O1;
        break;
    }
    if (data == &array[o2]) {
        operation = O2;
        break;
    }
    if (data == &array[on]) {
        operation = ON;
        break;
    }
} while (false);

Log("operation:",operation);

কেউ ভাবতে পারেন যে কেন তিনি breakএকটি ifবিবৃতিতে একই কাজ করতে পারেন নি , যেমন:

if (data == &array[o1])
{
    operation = O1;
    break;
}
else if (...)

breakকেবলমাত্র নিকটতম ঘেরযুক্ত লুপ বা স্যুইচের সাথে ইন্টারেক্ট করে , এটি এটি for, whileবা do .. whileটাইপ হ'ল দুর্ভাগ্যক্রমে এটি কাজ করবে না।


1

লেখকের বয়স কত ছিল?

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


1

ইতিমধ্যে উল্লিখিত 'গোটো উদাহরণগুলি' ছাড়াও, কর ... যখন (0) আইডিয়ামটি কখনও কখনও সংজ্ঞাতে বন্ধনী সরবরাহের জন্য ম্যাক্রো সংজ্ঞাতে ব্যবহৃত হয় এবং এখনও শেষে একটি অর্ধ কোলন যুক্ত করে সংকলক কাজ করে থাকে একটি ম্যাক্রো কল

http://groups.google.com/group/comp.soft-sys.ace/browse_thread/thread/52f670f1292f30a4?tvc=2&q=while+(0)


0

আমি পাতলা ছদ্মবেশী গোটো হিসাবে ব্যবহার সম্পর্কে বেশিরভাগ পোস্টারের সাথে একমত। শৈলীতে কোড লেখার সম্ভাব্য অনুপ্রেরণা হিসাবে ম্যাক্রোসকেও উল্লেখ করা হয়েছে।

আমি এই নির্মাণটি দরিদ্র ব্যক্তির ব্যতিক্রম হিসাবে মিশ্র সি / সি ++ পরিবেশে ব্যবহৃত দেখেছি। "বিরতি" সহ "কর" (মিথ্যা) "কোড ব্লকের শেষে এড়াতে ব্যবহার করা যেতে পারে এমন কোনও কিছু যা লুপটিতে সাধারণত একটি ব্যতিক্রমের নিশ্চয়তা দেয়।

আমি দোকানগুলিতে এই কনস্ট্রাক্টটি ব্যবহার করেছি যেখানে "ফাংশন প্রতি একক রিটার্ন" আদর্শ প্রয়োগ করা হয়। আবার এটি সুস্পষ্ট "গোটো" এর পরিবর্তে - তবে অনুপ্রেরণা হ'ল একাধিক রিটার্ন পয়েন্টগুলি এড়ানো, কোডটি "এড়িয়ে যাওয়া" না করা এবং সেই ফাংশনের মধ্যে প্রকৃত বাস্তবায়ন চালিয়ে যাওয়া।


0

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


0

অনেকে ইতিমধ্যে এই নির্মাণ এবং ক এর মধ্যে সাদৃশ্য বর্ণনা gotoকরেছেন এবং গোটোটির পক্ষে অগ্রাধিকার প্রকাশ করেছেন। সম্ভবত এই ব্যক্তির পটভূমিতে এমন একটি পরিবেশ অন্তর্ভুক্ত ছিল যেখানে নির্দেশিকাগুলি কোডিংয়ের মাধ্যমে গোটোকে কঠোরভাবে নিষিদ্ধ করা হয়েছিল?


0

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

আপনি কেন এগুলি চান তা নিশ্চিত নয়, সম্ভবত পরিবর্তনশীল সুযোগ বা কোনও ডিবাগার দিয়ে সুবিধা।

লুফের সময় তুচ্ছ করণীয় দেখুন , এবং সি 2 থেকে বন্ধনীগুলি ভাল

আমার পরিভাষাটি স্পষ্ট করার জন্য (যা আমি বিশ্বাস করি যে মানক ব্যবহার অনুসরণ করা হয়):

নগ্ন ধনুর্বন্ধনী :

init();
...
{
c = NULL;
mkwidget(&c);
finishwidget(&c);
}
shutdown();

খালি ধনুর্বন্ধনী (NOP):

{}

যেমন

while (1)
   {}  /* Do nothing, endless loop */

ব্লক :

if (finished)
{
     closewindows(&windows);
     freememory(&cache);
}

যা হয়ে যাবে

if (finished)
     closewindows(&windows);
freememory(&cache);

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

নগ্ন ধনুর্বন্ধনী বা একটি ব্লক কোডের যে কোনও বিভাগকে চিহ্নিত করতে ইচ্ছুক হতে পারে এমন কোনও (ইনলাইন) ফাংশন সম্ভাব্য হতে পারে যা আপনি চিহ্নিত করতে চান, তবে সেই সময় রিফ্যাক্টর নয়।


সত্যি? এটা লজ্জার. সি সম্পর্কে আমি যে কয়েকটি জিনিস পছন্দ করেছি তার মধ্যে একটি হ'ল এটি আপনাকে যে কোনও জায়গায় নতুন নেস্টেড স্কোপ ঘোষণা করতে দেয়।
টেড

1
ন্যাং ব্রেসগুলি মাঝেমধ্যে অদ্ভুত ক্র্যাশগুলি ঠিক করতে সহায়ক। ব্লগস.এমএসডন.ল্ডনেউথিং / অর্চিভ/2004/05/20/135841 . aspx দেখুন ।
ব্রায়ান

1
সি ++ তে, একটি ব্লক (যেমন আপনার "নগ্ন ধনুর্বন্ধনী") যে কোনও জায়গায় যে কোনও একক বিবৃতি অনুমোদিত হতে পারে ব্যবহার করা যেতে পারে।
বেন ভয়েগ্ট

@ বেনওয়েগট খালি ধনুর্বন্ধনী অর্থাৎ একটি এনওপি একটি "নগ্ন ধনুর্বন্ধনী" থেকে পৃথক যা নির্দেশের লিনিয়ার অনুক্রমের চারপাশে যুক্ত একটি ব্লক। যেমন `প্রিন্টফ (" হ্যালো "); {পুতচর (','); putchar (0x20); } প্রিন্টফ ("ওয়ার্ল্ড! \ n"); `যেখানে বন্ধনীগুলি লুপ বা শাখা নিয়ন্ত্রণের অংশ নয়
mctylr

@ এমটাইলার: আমি খালি ধনুর্বন্ধনী সম্পর্কে কথা বলছিলাম না।
বেন ভয়েগট

0

GOTOএই দুটি ব্যবহারিকভাবে অভিন্ন হিসাবে এটি অনুকরণ করার একটি স্বীকৃত উপায় :

// NOTE: This is discouraged!
do {
    if (someCondition) break;
    // some code be here
} while (false);
// more code be here

এবং:

// NOTE: This is discouraged, too!
if (someCondition) goto marker;
// some code be here
marker:
// more code be here

অন্যদিকে, এই দুটিই সত্যই দিয়ে করা উচিত if:

if (!someCondition) {
    // some code be here
}
// more code be here

যদিও আপনি যদি কেবল ফরওয়ার্ড- GOTOএর একটি দীর্ঘ স্ট্রিংটিকে নেস্টেড ifএস-তে পরিণত করেন তবে বাসা কিছুটা কুৎসিত হতে পারে । আসল উত্তরটি হ'ল যথাযথ রিফ্যাক্টরিং, যদিও, প্রত্নতাত্ত্বিক ভাষার নির্মাণের অনুকরণ না করে।

আপনি যদি মরিয়া হয়ে GOTOএর মধ্যে একটি অ্যালগরিদম প্রতিলিপি করার চেষ্টা করছিলেন তবে আপনি সম্ভবত এই প্রতিমাটি দিয়ে এটি করতে পারতেন। এটি অবশ্যই অ-মানক এবং একটি ভাল সূচক যা আপনি ভাষার প্রত্যাশিত প্রতিমাগুলির সাথে নিবিড়ভাবে অনুসরণ করছেন না।

আমি এমন কোনও সি-এর মতো ভাষা সম্পর্কে সচেতন নই যেখানে আসলে / যখন কোনও কিছুর জন্য মূর্তিযুক্ত সমাধান হয়।

আপনি সম্ভবত পুরো মেসটিকে আরও বুদ্ধিমান এবং আরও বেশি পঠনযোগ্য করে তুলতে আরও বুদ্ধিমান কিছুতে পরিণত করতে পারেন।


1
অ্যালান, do..while(false)হয় না চলমান সময়ের "undefined" সংখ্যার জন্য, এটা চলমান জন্য একবার
দিমিত্রি

2
আমি যেমন continueদেখিয়েছি শেষে আপনার শর্তাধীন বিবৃতি থাকলে এটি একটি অনির্ধারিত সংখ্যা চলছে running দ্বারা undefinedআমি কেবল বলতে চাচ্ছি যে আপনি জানেন না তা একবার যদি না আপনি পূর্বাভাস দিতে পারি অবস্থার একটি নির্দিষ্ট পুনরাবৃত্তির এ পূরণ করা হবে কিনা চেয়ে বেশি চালাচ্ছে। কোনো ছাড়া continueএতে এস, do..while(false)একবার চালানো হবে, কিন্তু কোনো ছাড়া breakএতে এস, while(true)সব সময় প্রবেশ করুন চালানো হবে, তাই "ডিফল্ট আচরণ" সত্যিই বুঝতে কি প্রাসঙ্গিক নয় পারবেন লুপ সঙ্গে সম্পন্ন করা।
অ্যালান বরই

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

5
কেউ এর শব্দার্থবিজ্ঞান বুঝতে পারে না continuecontinueলুপ পুনরাবৃত্তি না। "দ্যcontinue বিবৃতিটি একটি পুনরাবৃত্তির বিবৃতিতে উপস্থিত হবে এবং ক্ষুদ্রতম সংলগ্ন পুনরাবৃত্তির বিবৃতি , অর্থাৎ লুপের শেষের দিকে লুপ-ধারাবাহিকতা অংশে নিয়ন্ত্রণ করায় " "
বেন ভয়েগট

-1, @ বেনভয়েট যে কারণে উল্লেখ করেছেন তার জন্য শীর্ষ দুটি বিবৃতি অভিন্ন নয়।
সেমিঃ

0

কিছু কোডার কেবলমাত্র তাদের ফাংশন থেকে একক প্রস্থান / ফিরে আসতে পছন্দ করে। একটি ডামি do The ....} ব্যবহারের সময় (মিথ্যা); একবার শেষ করার পরেও ডামি লুপটি "ব্রেকআউট" করতে দেয় এবং তারপরেও একক রিটার্ন পাওয়া যায়।

আমি জাভা কোডার, তাই আমার উদাহরণটি এরকম হবে

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class p45
{
    static List<String> cakeNames = Arrays.asList("schwarzwald torte", "princess", "icecream");
    static Set<Integer> forbidden = Stream.of(0, 2).collect(Collectors.toSet());

    public static  void main(String[] argv)
    {
        for (int i = 0; i < 4; i++)
        {
            System.out.println(String.format("cake(%d)=\"%s\"", i, describeCake(i)));
        }
    }


    static String describeCake(int typeOfCake)
    {
        String result = "unknown";
        do {
            // ensure type of cake is valid
            if (typeOfCake < 0 || typeOfCake >= cakeNames.size()) break;

            if (forbidden.contains(typeOfCake)) {
                result = "not for you!!";
                break;
            }

            result = cakeNames.get(typeOfCake);
        } while (false);
        return result;
    }
}


-1

এটা মজাদার। অন্যরা যেমন বলেছে সম্ভবত লুপের অভ্যন্তরে বিরতি রয়েছে। আমি এটি এভাবেই করতাম:

while(true)
{
   <main code for function>
   break; // at the end.
}

2
চিরকালের লুপিংয়ের সম্ভাবনা নিয়ে? do..while(false)সর্বদা প্রস্থান করে, while(true)ঝুঁকিপূর্ণ দিক থেকে বেশি।
দিমিত্রি

1
while(true)বেশিরভাগ ভাষায় সঠিক পরিচয় om আপনি প্রোগ্রামটির মূল লুপ হিসাবে প্রায়শই এটি জিইউআই অ্যাপ্লিকেশনগুলিতে পাবেন। যেহেতু আপনি মূলত ধরেই নিচ্ছেন যে প্রোগ্রামটি না করা অবধি মরতে হবে না, এটি do..while(false)সমস্ত ধরণের যুক্তিযুক্ত যুক্তি তৈরি করবে। পারফেকশনিস্ট পিওভির কাছ থেকে এই পদ্ধতিটি আরও ঝুঁকিপূর্ণ হতে পারে তবে এটি শব্দার্থগতভাবে সহজ এবং এইভাবে মানব প্রোগ্রামারদের জন্য কম ত্রুটিযুক্ত (দুঃখিত, স্কাইনেট)।
অ্যালান বরই

2
@ দিমিত্রি do{...}while(false)ঠিক ঠিক এর মতোইwhile(true){ .. break;}
এন 1.1

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