সি স্ট্রাক্টে ডিফল্ট মান


93

আমার এই জাতীয় ডেটা স্ট্রাকচার রয়েছে:

    কাঠামো ফু {
        আইটি আইডি;
        int রুট;
        int ব্যাকআপ_রোট;
        ইন্ট কারেন্ট_আউরোট;
    }

এবং আপডেট () নামে পরিচিত একটি ফাংশন যা এতে পরিবর্তনের জন্য অনুরোধ করা হয়।

  আপডেট (42, dont_care, dont_care, new_route);

এটি সত্যিই দীর্ঘ এবং আমি যদি কাঠামোর সাথে কিছু যুক্ত করি তবে আপডেট (...) করার জন্য প্রতিটি কলটিতে আমাকে একটি 'ডন্ট_ কেয়ার' যুক্ত করতে হবে।

আমি পরিবর্তে এটি একটি স্ট্রাক পাস করার কথা ভাবছি তবে 'dont_care' দিয়ে স্ট্রাক্ট পূর্বে পূরণ করা ফাংশন কলটিতে কেবল এটি বানান করার চেয়ে আরও ক্লান্তিকর। আমি কি যত্নের ডিফল্ট মান সহ কোথাও কাঠামো তৈরি করতে পারি এবং স্থানীয় ভেরিয়েবল হিসাবে ঘোষণার পরে কেবল আমার যত্ন নেওয়া ক্ষেত্রগুলি সেট করতে পারি?

    কাঠামো foo বার = {। আইড = 42, .ক্রেন_আরউট = নতুন_রোট};
    আপডেট (& বার);

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

এবং আমি অন্য সব কিছু -1 এ ডিফল্ট করতে চাই ('যত্ন নেওয়ার' জন্য গোপন কোড)

উত্তর:


157

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

এই কোডটির কার্যত দিকনির্দেশনা বোঝার কোনও মানসিক ওভারহেড নেই এবং এটি খুব স্পষ্ট যে barআপনি কোন ক্ষেত্রগুলি সুস্পষ্টভাবে সেট করেছেন যখন (নিরাপদে) আপনি সেট করেন নি সেগুলি উপেক্ষা করে।


6
এই পদ্ধতির আর একটি বোনাস হ'ল এটি কাজ করার জন্য কোনও সি 99 বৈশিষ্ট্যের উপর নির্ভর করে না।
ডি.শ্যাওলি

25
আমি যখন এই 500 লাইনে পরিবর্তিত হয়েছি তখন প্রকল্পটির "ঝরে পড়ে"। আমি যদি এই একের জন্য দুবার ভোট দিতে পারি!
আর্থার উলফেল্ট

4
PTHREAD_MUTEX_INITIALIZERএটিও ব্যবহার করে।
ইঙ্গিত করা হয়েছে

স্ট্রাক্টে উপস্থিত উপাদানগুলির সংখ্যার উপর নমনীয় হওয়ার জন্য আমি এক্স-ম্যাক্রোসের উপর নির্ভর করে নীচে একটি উত্তর যুক্ত করেছি ।
আন্তোনিও

16

আপনি নিজের গোপন বিশেষ মানটিকে 0 এ পরিবর্তন করতে পারেন এবং সি এর ডিফল্ট কাঠামো-সদস্য শব্দার্থবিজ্ঞান কাজে লাগাতে পারেন

তারপরে ইনিশিয়ালাইজারে নির্ধারিত বারের সদস্য হিসাবে 0 পাস করবে।

অথবা আপনি এমন ম্যাক্রো তৈরি করতে পারেন যা আপনার জন্য ডিফল্ট সূচনা করবে:


FOO_INIT কাজ করে? সংকলকটির অভিযোগ করা উচিত, আমি মনে করি, যদি আপনি একই সদস্যকে দু'বার শুরু করেন।
জোনাথন লেফলার

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

4
C99: open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf : 7..8.৮.১৯: আরম্ভের সূচনাটি অর্ডারে ঘটবে, প্রতিটি ইনিশিয়ালাইজার একটি নির্দিষ্ট সাবওবজেক্টের জন্য সরবরাহ করা হবে যার জন্য পূর্বের কোনও তালিকাভুক্ত আরম্ভকারীকে ওভাররাইড করে subobject;
অ্যালেন্ডেস্কি

4
যদি এটি সত্য হয় তবে আপনি কি ডিএএফএএলএলএফইউ সংজ্ঞায়িত করতে পারবেন না, যার মধ্যে সমস্ত প্রারম্ভিক রয়েছে এবং তারপরে স্ট্রাক্ট foo বার = {DEFAULT_FOO, .id = 10}; ?
জন

7

<stdarg.h>আপনাকে বৈকল্পিক ফাংশনগুলি সংজ্ঞায়িত করতে দেয় (যা অনির্দিষ্ট সংখ্যক যুক্তি গ্রহণ করে, যেমন printf())। আমি এমন একটি ফাংশন সংজ্ঞায়িত করব যা সংযোজন যুক্তিগুলির একটি ইচ্ছামত সংখ্যক সংযোজন নিয়েছিল, যা সম্পত্তি আপডেট করার জন্য নির্দিষ্ট করে এবং একটি যা মান নির্দিষ্ট করে। enumসম্পত্তির নাম নির্দিষ্ট করতে একটি বা একটি স্ট্রিং ব্যবহার করুন ।


হাই @ ম্যাট, ফিল্ডে enumভেরিয়েবল কীভাবে ম্যাপ করবেন struct? হার্ডকোড এটা? তারপরে এই ফাংশনটি শুধুমাত্র নির্দিষ্ট ক্ষেত্রে প্রযোজ্য হবে struct
মিসেসপ্রিট

5

পরিবর্তে একটি প্রাক প্রসেসর ম্যাক্রো সংজ্ঞা ব্যবহার বিবেচনা করুন:

যদি আপনার (স্ট্রাক্ট ফু) উদাহরণটি বিশ্বব্যাপী হয় তবে অবশ্যই আপনার অবশ্যই প্যারামিটারের দরকার নেই। তবে আমি ধরে নিচ্ছি আপনার সম্ভবত একাধিক উদাহরণ রয়েছে। ({...}) ব্লকটি ব্যবহার করা একটি জিএনইউ-ইস্ম যা জিসিসিতে প্রয়োগ হয়; ব্লক হিসাবে লাইনগুলি একসাথে রাখার এটি একটি দুর্দান্ত (নিরাপদ) উপায়। আপনার যদি পরে ম্যাক্রোগুলিতে যেমন পরিসীমা বৈধতা যাচাইয়ের জন্য আরও যুক্ত করতে হয়, তবে / অন্য বিবৃতি এবং এর মতো কিছু ভাঙার বিষয়ে আপনাকে চিন্তা করতে হবে না।

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


4

একটি প্যাটার্ন গবজেক্ট ব্যবহারগুলি হ'ল একটি বৈচিত্র্যময় ফাংশন এবং প্রতিটি সম্পত্তির জন্য গণনা করা মান। ইন্টারফেসটি দেখতে এমন কিছু দেখাচ্ছে:

ভারার্গস ফাংশনটি লেখা সহজ - http://www.eskimo.com/~scs/cclass/int/sx11b.html দেখুন । কেবল কী -> মান জোড়গুলি মেলে এবং উপযুক্ত কাঠামোর বৈশিষ্ট্যগুলি সেট করুন।


4

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

যেমন

বা আরও ভাল প্রতিটি পরিবর্তন ক্ষেত্রে জন্য একটি ফাংশন লিখুন। আপনি ইতিমধ্যে লক্ষ্য করেছেন যে আপনি একই সাথে প্রতিটি সম্পত্তি পরিবর্তন করবেন না, তাই একবারে কেবলমাত্র একটি সম্পত্তি পরিবর্তন করা সম্ভব করে তুলুন। এটি কেবল পঠনযোগ্যতার উন্নতি করে না, তবে বিভিন্ন কেসগুলি পরিচালনা করতেও আপনাকে সহায়তা করে, যেমন আপনাকে সমস্ত "dont_care" পরীক্ষা করতে হবে না কারণ আপনি জানেন যে কেবলমাত্র বর্তমান রুটটি পরিবর্তিত হয়েছে।


কিছু ক্ষেত্রে একই কলে তাদের 3 টি পরিবর্তন হবে।
আর্থার উলফেল্ট

আপনার এই ক্রমটি থাকতে পারে: set_current_rout (আইডি, রুট); set_route (আইডি, রুট); প্রয়োগ_দেশ (আইডি); অথবা অনুরুপ. আমি যা মনে করি তা হ'ল প্রতিটি সেটারের জন্য আপনার এক ফাংশন কল থাকতে পারে। এবং পরবর্তী বিন্দুতে আসল গণনা (বা যা কখনও) করুন।
কুইনমার্স

4

যেমন কিছু সম্পর্কে:

সঙ্গে:

এবং:

এবং অনুরূপ:

সি ++ তে অনুরূপ প্যাটার্নটির একটি নাম রয়েছে যা আমি এখনই মনে করি না।

সম্পাদনা : এটিকে নামকরণকৃত প্যারামিটার ইডিয়াম বলা হয় ।


আমি বিশ্বাস করি এটাকে একজন কনস্ট্রাক্টর বলা হয়।
অজানা

না, আমি যা করতে চাইছিলাম তা বোঝাতে চেয়েছিলাম: আপডেট করুন (বার.init_id (42) _
রুনুনেন


2

আমি স্ট্রাক্টগুলির সাথে মরিচা করছি, তাই আমি সম্ভবত এখানে কয়েকটি কীওয়ার্ড অনুপস্থিত। তবে ডিফল্টগুলির সাথে আরম্ভ করা বৈশ্বিক কাঠামো কেন শুরু করবেন না, এটি আপনার স্থানীয় ভেরিয়েবলে অনুলিপি করুন, তারপরে এটি পরিবর্তন করুন?

একটি প্রাথমিককরণ যেমন:

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


2

আপনি কোনও এক্স-ম্যাক্রো দিয়ে সমস্যার সমাধান করতে পারেন

আপনি আপনার কাঠামোর সংজ্ঞাটি এতে পরিবর্তন করবেন:

এবং তারপরে আপনি সহজেই একটি নমনীয় ফাংশন সংজ্ঞায়িত করতে সক্ষম হবেন যা সমস্ত ক্ষেত্রকে সেট করে dont_care

এখানে আলোচনা অনুসরণ করে , কেউ এইভাবে একটি ডিফল্ট মানও সংজ্ঞায়িত করতে পারে:

যা অনুবাদ করে:

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

আমি প্রথম এক্স-ম্যাক্রো ধারণা যখন আমি মোকাবেলার ছিল শিখেছি এই সমস্যা

এটি স্ট্রাক্টে যুক্ত হওয়া নতুন ক্ষেত্রগুলির জন্য অত্যন্ত নমনীয়। আপনি বিভিন্ন ধরনের তথ্য থাকে, তাহলে আপনি বিভিন্ন সংজ্ঞায়িত করতে পারে dont_careডাটা টাইপ উপর নির্ভর করে মান: থেকে এখানে , আপনি অনুপ্রেরণা নিতে পারে ফাংশন দ্বিতীয় উদাহরণে মান প্রিন্ট করতে ব্যবহৃত।

যদি আপনি সমস্ত কাঠামোর সাথে ঠিক থাকেন intতবে আপনি ডাটা টাইপটি বাদ দিতে পারেন LIST_OF_foo_MEMBERSএবং স্ট্রাক্ট সংজ্ঞাটির এক্স ফাংশনটি সহজেই পরিবর্তন করতে পারেন#define X(name) int name;


এই কৌশলটি কাজে লাগায় যে সি প্রিপ্রোসেসর দেরীতে বাইন্ডিং ব্যবহার করে এবং এটি খুব কার্যকর হতে পারে যখন আপনি কোনও একক জায়গাটি কোনও কিছুর সংজ্ঞা দিতে চান (উদাহরণস্বরূপ বলা হয়) এবং তারপরে 100% নিশ্চিত হন যে যখনই ব্যবহৃত আইটেমগুলি সর্বদা একই ক্রমে থাকে, নতুন আইটেম স্বয়ংক্রিয়ভাবে যুক্ত এবং মুছে ফেলা আইটেম সরানো হয়। আমি সংক্ষিপ্ত নামগুলি পছন্দ করতে পছন্দ করি না Xএবং সাধারণত _ENTRYতালিকার নামের সাথে যুক্ত করে থাকেন, যেমন #define LIST_SOMETHING LIST_SOMETHING_ENTRY(a1, a2, aN) \ LIST_SOMETHING_ENTRY(b1, b2, bN) ...
hlovdal

1

সর্বাধিক মার্জিত উপায় হ'ল update()ফাংশনটি ব্যবহার না করেই স্ট্রাক্ট ফিল্ডগুলি সরাসরি আপডেট করা - তবে সম্ভবত এটি ব্যবহারের উপযুক্ত কারণ রয়েছে যা প্রশ্নে আসে না।

অথবা আপনি যেমন পুক্কুর পরামর্শ মতো কাঠামোর প্রতিটি ক্ষেত্রের জন্য পৃথক অ্যাক্সেস ফাংশন তৈরি করতে পারেন।

অন্যথায় আমি যে সর্বোত্তম সমাধানটির কথা ভাবতে পারি তা স্ট্রাক্ট ফিল্ডে '0' এর মানটিকে 'আপডেট করবেন না' পতাকা হিসাবে চিকিত্সা করা - যাতে আপনি একটি শূন্য আউট স্ট্রাক্ট ফিরিয়ে দেওয়ার জন্য একটি ফানসিটন তৈরি করেন, এবং তারপরে এটি আপডেট করার জন্য ব্যবহার করুন।

তবে, 0 এটি স্ট্রাক্টের ক্ষেত্রগুলির জন্য বৈধ মান হলে, এটি খুব সম্ভবত ব্যবহারযোগ্য হবে না।


একটি নেটওয়ার্ক একটি ভাল কারণ =) তবে যদি -1 হ'ল 'যত্ন না' মানটি হয় তবে কেবল খালি_ফু () ফাংশনটি পুনরায় নিষ্ক্রিয় করুন, এবং সেই পদ্ধতির ব্যবহার করবেন?
gnud

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