স্ট্রাইকটি শূন্য / নাল থেকে শুরু / পুনরায় সেট করুন


92
struct x {
    char a[10];
    char b[20];
    int i;
    char *c;
    char *d[10];
};

আমি এই কাঠামোটি পূরণ করছি এবং তারপরে মানগুলি ব্যবহার করছি। পরবর্তী পুনরাবৃত্তিতে, আমি সমস্ত ক্ষেত্রগুলিকে পুনরায় ব্যবহার শুরু করার আগে 0বা তার nullআগে পুনরায় সেট করতে চাই ।

আমি এটা কিভাবে করবো? আমি কি ব্যবহার করতে পারি memsetবা আমাকে সমস্ত সদস্যের মধ্যে দিয়ে যেতে হবে এবং তারপরে স্বতন্ত্রভাবে তা করতে পারি?

উত্তর:


109

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

উদাহরণ স্বরূপ:

static const struct x EmptyStruct;

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

তারপরে, প্রতিটি সময় লুপটি লিখতে পারেন:

myStructVariable = EmptyStruct;

4
@ ডেভিড হেফারনান: memsetআমি যদি কেবল সমস্ত কিছু পুনরায় সেট করতে চাই তবে এটি ব্যবহার করার চেয়ে কি ভাল 0??
হরি

9
@ হরি আমি এই পদ্ধতির নিজেকে পছন্দ করি। ব্যবহার memsetআমাকে নোংরা বোধ করে। আমি যেখানেই সম্ভব মেমরির বিন্যাস সম্পর্কে সংকলকটিকে উদ্বিগ্ন হতে পছন্দ করি। কঠোরভাবে এই ধরনের ব্যবহার memsetঅ-বহনযোগ্য হিসাবে ব্যবহার করা হয় তবে বাস্তবে আপনি যদি আপনার কোডটি যে কোনও জায়গাতেই গুরুত্বপূর্ণ হয় তা কম্পাইল করে দিলে আমি হতবাক হয়ে যাব। সুতরাং, আপনি যদি পছন্দ করেন তবে আপনি সম্ভবত নিরাপদে মেমসেট ব্যবহার করতে পারেন।
ডেভিড হেফারনান

4
@ হরি, এটি ধারণাগতভাবে আরও ভাল, আপনি একটি ডিফল্ট সূচনা মান সরবরাহ করার সাথে সাথে (কোনও বস্তুর কারখানার প্যাটার্নের মতো কিছু))
দিয়েগো সেভিলা

4
@ স্নিগুটার আমি এটি জানি মনে রাখবেন যে আমার উত্তরটি মেমসেট ব্যবহার না করার প্রস্তাব দেয়। নাল মান নির্ধারণের উপায় হিসাবে আমি মেমসেট ব্যবহারের অ পোর্টিবিলিটিটি কোথায় চিহ্নিত করেছি সে সম্পর্কেও মন্তব্যটি নোট করুন। আমার পূর্ববর্তী মন্তব্যটি কেবলমাত্র বাস্তবতাটি দেখায় যে 0 বিট অবিচ্ছিন্নভাবে ভাসমান পয়েন্ট জিরোগুলির সাথে মিলে যায়।
ডেভিড হেফারনান

4
@ কেপি 11 উদ্ধৃতি দয়া করে
ডেভিড

85

আপনার কাছে যখন আধুনিক সি (সি 99) রয়েছে তখন এমন কাজ করার উপায়টি হল যৌগিক আক্ষরিক ব্যবহার ।

a = (const struct x){ 0 };

এটি ডেভিডের সমাধানের সাথে কিছুটা মিল, কেবল আপনাকে খালি কাঠামো ঘোষণার জন্য বা এটি ঘোষণার বিষয়ে চিন্তা করতে হবে না static। আপনি যদি constআমি যেমনটি ব্যবহার করি তবে সংযোজকটি যথাযথভাবে কেবল পঠনযোগ্য স্টোরেজে স্থিতিশীলভাবে যৌগিক বরাদ্দ করতে বিনামূল্যে।


এটি স্ট্যাকের উপর x এর একটি উদাহরণ তৈরি করে তা এটিকে অনুলিপি করতে? বড় স্ট্রাকচার / ছোট স্ট্যাকের জন্য যা কোনও সমস্যা হতে পারে।
Étienne

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

4
"অনুপস্থিত আরম্ভকারী" সতর্কতাগুলি সত্যই জাল। সি স্ট্যান্ডার্ডটি ঠিক কি হবে তার চেয়ে বেশি নির্ধারণ করে { 0 }এবং ডিফল্ট আরম্ভকারী হিসাবে orse সেই সতর্কবার্তাটি বন্ধ করুন, এটি উত্সাহজনক মিথ্যা বিপদাশঙ্কা।
জেনস গুষ্ট্ড্ট

4
@ জেনস গুস্ট্ট এই টাইপকাস্টিংয়ের কি সত্যিই প্রয়োজন? আমি কি এভাবে লিখতে পারি না? স্ট্রাক্ট xa = (কনস্ট্যান্ট) {0};
প্যাট্রিক

4
@ পেট্রিক, যদিও সিনট্যাক্সটি একই রকম তবে এটি castালাই নয় তবে "যৌগিক আক্ষরিক"। এবং আপনি সূচনা এবং অ্যাসাইনমেন্ট মিশ্রিত করছেন।
জেনস গুস্ট্ট

58

স্ট্রাক্ট আরম্ভের জন্য সর্বোপরি সর্বোত্তম স্ট্যান্ডার্ড সি স্পেসিফিকেশন ব্যবহার করা:

struct StructType structVar = {0};

এখানে সমস্ত বিট শূন্য (সর্বদা)।


13
আমি মনে করি না আপনি প্রতিবার একটি লুপের চারপাশে এটি করতে পারবেন
ডেভিড হেফারনান

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

4
@ সায়ান আপনি {}সি ++ এ ব্যবহার করতে পারেন । সিসি ++ সমর্থন করবে কিনা{0} এবং আমি নিজেই সেই স্ট্যান্ডার্ডের সেই অংশটির সাথে পরিচিত নই The
ম্যাথিউ

@ ম্যাথুজ: হ্যাঁ, আসলে আমি মেমসেট () ব্যবহার করে শেষ করেছি, কারণ {0}বা এর সাথে অনেকগুলি বহনযোগ্য সমস্যা ছিল {}। নিশ্চিত নয় যে সি ও সি ++ মানদণ্ডগুলি এই বিষয়ে সুনির্দিষ্ট এবং সিঙ্কে রয়েছে, তবে দৃশ্যত, সংকলকগুলি তা নয়।
সায়ান

এই ক্ষেত্রে এই কাজ করবে? struct StructType structVar = malloc (sizeof(StructType)); structVar ={0}
স্যাম থমাস

35

সিতে এটি structব্যবহারের জন্য মেমরিটি শূন্য করা একটি সাধারণ প্রতিমা memset:

struct x myStruct;
memset(&myStruct, 0, sizeof(myStruct));

প্রযুক্তিগতভাবে বলতে গেলে, আমি বিশ্বাস করি না যে এটি পোর্টেবল কারণ এটি ধরে নেওয়া হয় যে NULLকোনও মেশিনের পয়েন্টারটি পূর্ণসংখ্যা মান 0 দ্বারা উপস্থাপিত হয় তবে এটি ব্যাপকভাবে ব্যবহৃত হয় কারণ বেশিরভাগ মেশিনেই এটি হয়।

আপনি যদি সি থেকে সি ++ এ চলে যান তবে প্রতিটি বিষয়টিতে এই কৌশলটি ব্যবহার না করার বিষয়ে সতর্ক হন। সি ++ কেবল সদস্যবিহীন কার্যাবলী এবং কোনও উত্তরাধিকারহীন বস্তুগুলিতে এই আইনী করে তোলে।


4
সি স্ট্যান্ডার্ডটি জানিয়েছে যে নুল সবসময় 0 থাকে the মেশিনটি এমনভাবে তৈরি করা হয়েছে যে পূর্বনির্ধারিত অবৈধ ঠিকানাটি আক্ষরিক 0 নয়, তবে সেই স্থাপত্যের সংকলকটি সংকলনের সময় অবশ্যই সমন্বয় করতে হবে।
কেভিন এম

9
@ কেভিনম হ্যাঁ, প্রতীক "0" সর্বদা শূন্য হলেও NUL পয়েন্টারের সাথে মিল রাখে; আপনি মেমসেট ব্যবহার করে শূন্যে বিট সেট করলে সংকলক কিছুই করতে পারে না।
অ্যাড্রিয়ান রত্নপালা

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

19

আপনার কাছে যদি C99 অনুবর্তী কম্পাইলার থাকে তবে আপনি ব্যবহার করতে পারেন

mystruct = (struct x){0};

অন্যথায় আপনার ডেভিড হেফারনান যা লিখেছিলেন তা করা উচিত, যেমন ঘোষণা করুন:

struct x empty = {0};

এবং লুপে:

mystruct = empty;

6

আপনি memsetকাঠামোর আকারের সাথে ব্যবহার করতে পারেন :

struct x x_instance;
memset (&x_instance, 0, sizeof(x_instance));

4
আমি মনে করি না এখানে castালাই প্রয়োজনীয়। তাই কি?
টেম্পলেটটিফাইফ

ভাল, আমি সি ++ তে এতটাই অভ্যস্ত যে ... ভাল, এটি সি ++ তেও কাজ করবে, তাই আমি এটিকে বোঝা হিসাবে দেখছি না।
দিয়াগো সেভিলা

হ্যাঁ, আমি যথেষ্ট নির্দিষ্ট ছিল না। এটি সিভি কোয়ালিটিফাইড টির যে কোনও পয়েন্টারকে সিভি কোয়ালিড বায়োড * তে রূপান্তর করা যায়। যে কোনও ডেটা পয়েন্টার, ফাংশন পয়েন্টারগুলি সম্পূর্ণ আলাদা জিনিস। কুডোস @ কেভিন
মার্কস বোরকেনহেগেন

memsetএকটি বিকল্প, কিন্তু যখন এটা ব্যবহার করে, আপনি যে কেন এটা ভালো প্রকৃত বস্তুর আকার, না টাইপ মাপ উল্লেখ করতে, নিশ্চিত করুন যে মেমরি লিখিত ঠিক তৃতীয় প্যারামিটার হিসাবে একই আকার হয় করতে হবে আপনি জানি এটা বর্তমানে নেই। আইডাব্লু memset (&x_instance, 0, sizeof(x_instance));একটি আরও ভাল পছন্দ। বিটিডাব্লু: (void*)সি ++ তেও কাস্ট অতিমাত্রায় lu
ওল্ফ

(দুঃখিত, আমি প্রশ্নটি দেখার জন্য মিস করেছি, এখন এটি আরও ভাল)
ওল্ফ

4

আমি বিশ্বাস করি আপনি কেবল {}আপনার ভেরিয়েবলের জন্য খালি সেট ( ) নির্ধারণ করতে পারেন ।

struct x instance;

for(i = 0; i < n; i++) {
    instance = {};
    /* Do Calculations */
}

এটি বৈধ সি নয়, এমনকি সি 99ও নয়। এটি উপরের জেন্সগাস্ট্টের উত্তরের মতো যৌগিক আক্ষরিক হওয়া দরকার।
অ্যান্ডার্স


-1

চিত্রের বিবরণ এখানে প্রবেশ করুন gnu11 থেকে একটি অবাক করুন!

typedef struct {
    uint8_t messType;
    uint8_t ax;  //axis
    uint32_t position;
    uint32_t velocity;
}TgotoData;

TgotoData tmpData = { 0 };

কিছুই শূন্য নয়।


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