আমি বেশ কয়েকবার এই প্রশ্নোত্তর নিয়ে ছুটে এসেছি এবং আরও বিস্তৃত উত্তর দিতে চাইছি। আমি মনে করি এটির কল্পনা করার সর্বোত্তম উপায় হ'ল কলকে কীভাবে ত্রুটি ফিরে পাওয়া যায় এবং আপনি কী ফিরে আসেন।
কিভাবে
একটি ফাংশন থেকে তথ্য ফেরত দেওয়ার জন্য 3 টি উপায় রয়েছে:
- ফেরত মূল্য
- আর্গুমেন্ট (গুলি)
- ব্যান্ডের বাইরে, এতে নন-লোকাল গোতো (সেটজ্যাম্প / লংজ্যাম্প), ফাইল বা গ্লোবাল স্কোপড ভেরিয়েবলগুলি, ফাইল সিস্টেম ইত্যাদি অন্তর্ভুক্ত রয়েছে includes
ফেরত মূল্য
আপনি কেবলমাত্র একক বস্তু হিসাবে মান ফিরিয়ে দিতে পারেন তবে এটি একটি স্বেচ্ছাসেবী জটিল হতে পারে। এখানে ত্রুটি ফিরে আসার একটি উদাহরণ:
enum error hold_my_beer();
রিটার্ন মানগুলির একটি সুবিধা হ'ল এটি কম অনুপ্রেরণামূলক ত্রুটি পরিচালনার জন্য কলগুলিতে শৃঙ্খলাবদ্ধ করে:
!hold_my_beer() &&
!hold_my_cigarette() &&
!hold_my_pants() ||
abort();
এটি কেবল পঠনযোগ্যতা সম্পর্কে নয়, একই ধরণের ফাংশন পয়েন্টারগুলির একটি অ্যারে প্রক্রিয়াকরণের অনুমতি দিতে পারে।
আর্গুমেন্ট (গুলি)
আপনি আর্গুমেন্টের মাধ্যমে একাধিক বস্তুর মাধ্যমে আরও বেশি ফিরে আসতে পারেন, তবে সেরা অনুশীলনটি যুক্তিগুলির মোট সংখ্যা কম রাখার পরামর্শ দেয় (বলুন, <= 4):
void look_ma(enum error *e, char *what_broke);
enum error e;
look_ma(e);
if(e == FURNITURE) {
reorder(what_broke);
} else if(e == SELF) {
tell_doctor(what_broke);
}
ব্যান্ড আউট
সেটজ্যাম্প () এর সাহায্যে আপনি একটি স্থান নির্ধারণ করে এবং কীভাবে আপনি কোনও মান মান হ্যান্ডেল করতে চান এবং আপনি লংজ্যাম্প () এর মাধ্যমে সেই স্থানটিতে নিয়ন্ত্রণ স্থানান্তর করেন। সি তে সেটজ্যাম্প এবং লংজ্যাম্পের ব্যবহারিক ব্যবহার দেখুন ।
কি
- ইনডিকেটর
- কোড
- উদ্দেশ্য
- কলব্যাক
ইনডিকেটর
একটি ত্রুটি সূচক কেবল আপনাকে বলে যে একটি সমস্যা আছে তবে বলেন সমস্যার প্রকৃতি সম্পর্কে কিছুই নয়:
struct foo *f = foo_init();
if(!f) {
/// handle the absence of foo
}
ত্রুটি পরিস্থিতি যোগাযোগের জন্য কোনও ফাংশনের পক্ষে এটি সর্বনিম্ন শক্তিশালী উপায়, তবে, যদি কলার কোনওভাবেই স্নাতকৃত পদ্ধতিতে ত্রুটির প্রতিক্রিয়া না জানায় তবে তা নিখুঁত।
কোড
একটি ত্রুটি কোড কলকারীকে সমস্যার প্রকৃতি সম্পর্কে জানায় এবং উপযুক্ত প্রতিক্রিয়ার জন্য অনুমতি দিতে পারে (উপরের দিক থেকে)। এটি রিটার্ন মান হতে পারে, বা ত্রুটির যুক্তির উপরে look_ma () উদাহরণের মতো হতে পারে।
উদ্দেশ্য
একটি ত্রুটিযুক্ত বস্তুর সাথে, কলকারীকে নির্বিচারে জটিল সমস্যা সম্পর্কে অবহিত করা যেতে পারে। উদাহরণস্বরূপ, একটি ত্রুটি কোড এবং একটি উপযুক্ত মানব পাঠযোগ্য বার্তা। এটি কলকারীকে আরও জানাতে পারে যে একাধিক জিনিস ভুল হয়েছে, বা কোনও সংগ্রহ প্রক্রিয়া করার সময় আইটেম প্রতি ত্রুটি:
struct collection friends;
enum error *e = malloc(c.size * sizeof(enum error));
...
ask_for_favor(friends, reason);
for(int i = 0; i < c.size; i++) {
if(reason[i] == NOT_FOUND) find(friends[i]);
}
ত্রুটি অ্যারে প্রাক-বরাদ্দ পরিবর্তে, আপনি অবশ্যই (পুনরায়) অবশ্যই প্রয়োজন হিসাবে গতিশীল বরাদ্দ করতে পারেন।
কলব্যাক
ত্রুটিগুলি হ্যান্ডেল করার সবচেয়ে শক্তিশালী উপায় হ'ল কলব্যাক, কারণ কিছু ভুল হয়ে গেলে আপনি কী আচরণটি দেখতে চান তা ফাংশনটি বলতে পারেন। প্রতিটি ফাংশনে একটি কলব্যাক আর্গুমেন্ট যুক্ত করা যেতে পারে, বা যদি কাস্টমাইজেশন ইউআইএস কেবলমাত্র এর মতো স্ট্রাক্টের জন্য প্রয়োজন হয়:
struct foo {
...
void (error_handler)(char *);
};
void default_error_handler(char *message) {
assert(f);
printf("%s", message);
}
void foo_set_error_handler(struct foo *f, void (*eh)(char *)) {
assert(f);
f->error_handler = eh;
}
struct foo *foo_init() {
struct foo *f = malloc(sizeof(struct foo));
foo_set_error_handler(f, default_error_handler);
return f;
}
struct foo *f = foo_init();
foo_something();
কলব্যাকের একটি আকর্ষণীয় সুবিধা হ'ল এটি একাধিকবার আহ্বান করা যেতে পারে, বা ত্রুটির অভাবে যখন কোনও সুখী পথের উপরে ওভারহেড না থাকে তখন কিছুই নয়।
নিয়ন্ত্রণের একটি বিপরীততা আছে। কলব্যাকটি কলব্যাকটি চালিত হয়েছিল কিনা তা জানে না। এর মতো, এটি একটি সূচক ব্যবহার করাও বোধগম্য হতে পারে।