স্ট্যান্ডার্ড সি-তে সমতার জন্য স্ট্রাক্টের দুটি উদাহরণকে আপনি কীভাবে তুলনা করবেন?
স্ট্যান্ডার্ড সি-তে সমতার জন্য স্ট্রাক্টের দুটি উদাহরণকে আপনি কীভাবে তুলনা করবেন?
উত্তর:
সি এটি করার জন্য কোনও ভাষার সুবিধা সরবরাহ করে না - আপনাকে নিজেরাই এটি করতে হবে এবং প্রতিটি কাঠামোর সদস্যকে সদস্য দ্বারা তুলনা করতে হবে।
0.0, -0.0 NaN
করা একটি সমস্যা memcmp()
। বাইনারি উপস্থাপনায় পৃথক পয়েন্টারগুলি একই অবস্থানের দিকে নির্দেশ করতে পারে (যেমন ডস: সেগ: অফসেট) এবং তাই সমান। কিছু সিস্টেমে একাধিক নাল পয়েন্টার রয়েছে যা সমানভাবে তুলনা করে। int
অপ্রয়োজনীয় এনকোডিং সহ -0 এবং ভাসমান পয়েন্ট ধরণের অস্পষ্টতার জন্য একই । (ইন্টেল দীর্ঘ ডাবল, দশমিক ,৪, ইত্যাদি) এই সমস্যাগুলির কোনও পার্থক্য নেই যে calloc()
ব্যবহৃত হয় না বা প্যাডিং হয়।
==
স্ট্রাকচার (আমার মত), দয়া করে দেখুন সঙ্গে কাজ করছে না stackoverflow.com/questions/46995631/...
আপনি ব্যবহার করতে প্রলুব্ধ হতে পারে memcmp(&a, &b, sizeof(struct foo))
, তবে এটি সমস্ত পরিস্থিতিতে কার্যকর নাও হতে পারে। সংকলকটি কোনও কাঠামোতে প্রান্তিককরণ বাফার স্থান যুক্ত করতে পারে এবং বাফার স্পেসে থাকা মেমরির অবস্থানগুলিতে পাওয়া মানগুলি কোনও নির্দিষ্ট মান হওয়ার নিশ্চয়তা দেয় না।
কিন্তু, যদি আপনি ব্যবহার calloc
বা memset
তাদের ব্যবহার করার আগে স্ট্রাকচার পূর্ণ আকার, আপনি করতে পারেন একটি অগভীর সঙ্গে তুলনা memcmp
করে (যদি আপনার গঠন পয়েন্টার রয়েছে, এটি শুধুমাত্র ম্যাচ হবে ঠিকানা পয়েন্টার প্রতি নির্দেশ করা হয় একই থাকেন)।
memcmp
প্রথমে স্মৃতি পরিষ্কার হয়ে গেলে আপনি অগভীর তুলনা করতে পারেন । যা কাজ করার কাছাকাছি কিন্তু সঠিক নয়। ওএফসি প্রশ্নটি "সাম্যতা" সংজ্ঞায়িত করে না, সুতরাং আপনি যদি "অবজেক্টের উপস্থাপনার বাইট-বুদ্ধিমান সাম্যতা" বোঝাতে চান তবে memcmp
ঠিক তা (মেমরিটি পরিষ্কার হয়েছে কিনা) does
আপনি যদি এটি অনেক কিছু করেন তবে আমি একটি ফাংশন লেখার পরামর্শ দেব যা দুটি কাঠামোর সাথে তুলনা করে। এইভাবে, আপনি যদি কখনও কাঠামো পরিবর্তন করেন তবে আপনাকে কেবল এক জায়গায় তুলনা পরিবর্তন করতে হবে।
এটি কীভাবে করবেন .... আপনার প্রতিটি উপাদান পৃথকভাবে তুলনা করতে হবে
স্ট্রাক্টের ক্ষেত্রে ক্ষেত্রের মধ্যে সম্ভাব্য র্যান্ডম প্যাডিং অক্ষরের কারণে সাম্যের জন্য স্ট্রাকগুলি তুলনা করতে আপনি মেমক্যাম্প ব্যবহার করতে পারবেন না।
// bad
memcmp(&struct1, &struct2, sizeof(struct1));
উপরেরগুলি এই জাতীয় কাঠামোর জন্য ব্যর্থ হবে:
typedef struct Foo {
char a;
/* padding */
double d;
/* padding */
char e;
/* padding */
int f;
} Foo ;
নিরাপদ থাকতে আপনাকে সদস্যবিহীন তুলনা ব্যবহার করতে হবে।
@ গ্রেগ সঠিক যে সাধারণ ক্ষেত্রে একটি সুস্পষ্ট তুলনা ফাংশন লিখতে হবে।
এটি ব্যবহার করা সম্ভব memcmp
যদি:
NaN
।-Wpadded
এটি পরীক্ষা করার জন্য ঝাঁকুনির সাথে ব্যবহার করুন ) অথবা স্ট্রাক্টগুলি স্পষ্টভাবে দিয়ে শুরু করা হয়memset
করা হয়।BOOL
) আলাদা নয় তবে সমমানের মান রয়েছে।আপনি এম্বেড থাকা সিস্টেমগুলির জন্য প্রোগ্রামিং না করা (বা তাদের উপর ব্যবহৃত হতে পারে এমন একটি গ্রন্থাগার লেখার জন্য), আমি সি স্ট্যান্ডার্ডের কয়েকটি কোণার বিষয়ে চিন্তা করব না। নিকটতম বনাম দূরের পয়েন্টার পার্থক্যটি কোনও 32- বা 64- বিট ডিভাইসে বিদ্যমান নেই। আমি জানি না এমন কোনও অ-এমবেডেড সিস্টেমের একাধিক নেইNULL
পয়েন্টার নেই।
আরেকটি বিকল্প হ'ল সাম্যতা ফাংশনগুলি স্বয়ংক্রিয়ভাবে উত্পন্ন করা। আপনি যদি আপনার স্ট্রাক্ট সংজ্ঞাগুলি একটি সহজ উপায়ে রেখে দেন তবে সাধারণ কাঠামো সংজ্ঞাগুলি পরিচালনা করতে সাধারণ পাঠ্য প্রক্রিয়াকরণ ব্যবহার করা সম্ভব। আপনি সাধারণ কেসের জন্য লাইব্লাক্ল্যাং ব্যবহার করতে পারেন - যেহেতু এটি ক্ল্যাংয়ের মতো একই সীমানা ব্যবহার করে, এটি কোণার সমস্ত ক্ষেত্রে সঠিকভাবে পরিচালনা করে (বাগগুলি ব্যতীত)।
এরকম কোড জেনারেশন লাইব্রেরি আমি দেখিনি। তবে এটি তুলনামূলক সহজ appears
যাইহোক, এটি এমনও হয় যে এই জাতীয় উত্পন্ন সমতা ফাংশনগুলি প্রায়শই প্রয়োগ পর্যায়ে ভুল কাজ করে। উদাহরণস্বরূপ, UNICODE_STRING
উইন্ডোজের দুটি স্ট্রাকের অল্প বা গভীরভাবে তুলনা করা উচিত ?
memset
, ইত্যাদি একটি struct উপাদানে আরও লেখা পরে প্যাডিং বিট মান নিশ্চয়তা দেয় না, দেখুন: stackoverflow.com/q/52684192/689161
দ্রষ্টব্য আপনি প্যাডিংয়ের বিষয়ে চিন্তা না করেই স্ট্যাটাসহীন স্টাচচারে মেমক্যাম্প () ব্যবহার করতে পারেন, যতক্ষণ না আপনি সমস্ত সদস্যকে (একবারে) আরম্ভ করবেন। এটি সি 90 দ্বারা সংজ্ঞায়িত করা হয়েছে:
{0, }
কোনও প্যাডিং বাইটও শূন্য করবে?
আপনি যে প্রশ্নটি জিজ্ঞাসা করছেন তা এটি নির্ভর করে:
তারা একই বস্তু কিনা তা জানতে, সমতার জন্য দুটি স্ট্রকের সাথে পয়েন্টারগুলি তুলনা করুন। আপনি যদি সাধারণভাবে তাদের যদি একই মান দেখতে চান তবে আপনাকে গভীর তুলনা করতে হবে। এর সাথে সমস্ত সদস্যের তুলনা জড়িত। সদস্যরা যদি অন্য স্ট্রাক্টগুলিতে পয়েন্টার হয় তবে আপনাকেও সেই স্ট্রাইকগুলির মধ্যে পুনরাবৃত্তি করতে হবে।
বিশেষ ক্ষেত্রে যেখানে স্ট্রাইকগুলিতে পয়েন্টার থাকে না আপনি তথ্যের অর্থ কী তা জেনেও প্রতিটিতে থাকা তথ্যের সাথে কিছুটা তুলনা করার জন্য একটি মেমক্যাম্প করতে পারেন।
প্রতিটি সদস্যের জন্য 'সমান' এর অর্থ কী তা আপনি জানেন তা নিশ্চিত করুন - এটি ভাসমান-পয়েন্টের মান বা ব্যবহারকারী-সংজ্ঞায়িত ধরণের ক্ষেত্রে ইন্টের পক্ষে সুস্পষ্ট তবে আরও সূক্ষ্ম।
memcmp
কাঠামো তুলনা করে না, memcmp
বাইনারি তুলনা করে, এবং সর্বদা আবর্জনা থাকে, সুতরাং এটি সর্বদা তুলনায় মিথ্যা বেরিয়ে আসে।
উপাদানটিকে নিরাপদ হিসাবে উপাদানটির সাথে তুলনা করুন এবং ব্যর্থ হন না।
যদি স্ট্রাক্টগুলিতে কেবল আদিম থাকে বা আপনি যদি কঠোর সাম্যের দিকে আগ্রহী হন তবে আপনি এর মতো কিছু করতে পারেন:
ইন্ট মাই_স্ট্রিক্ট_সিএমপি (কনস্ট্রাক্ট মাই_স্ট্রাক্ট * এলএইচএস, কনস্ট্রাক্ট মাই_স্ট্রিক্ট * আরএইচএস) { রিটার্ন মেমক্যাম্প (এলএইচএস, আরশ, মাপ (স্ট্রাক্ট মাই_স্ট্রিক্ট)); }
তবে, যদি আপনার স্ট্রাক্টগুলিতে অন্যান্য স্ট্রাক্ট বা ইউনিয়নগুলিতে পয়েন্টার থাকে তবে আপনাকে এমন একটি ফাংশন লিখতে হবে যা আদিমদের সঠিকভাবে তুলনা করবে এবং অন্যান্য কাঠামোর তুলনায় যথাযথ তুলনা কল করবে make
তবে সচেতন থাকুন যে আপনার এডিটি আরম্ভের অংশ হিসাবে কাঠামোগুলির মেমরির পরিসীমা শূন্য করতে আপনার মেমসেট (& a, মাপের (স্ট্রাক্ট মাই_স্ট্রাক্ট), 1) ব্যবহার করা উচিত ছিল।
এই অনুবর্তী উদাহরণটি কাঠামোর সদস্যদের যথাসম্ভব শক্তভাবে প্যাক করা হয়েছে তা নিশ্চিত করার জন্য মাইক্রোসফ্ট ভিজ্যুয়াল স্টুডিও থেকে # প্রগমা প্যাক সংকলক এক্সটেনশন ব্যবহার করে:
#include <string.h>
#pragma pack(push, 1)
struct s {
char c;
int i;
char buffer[13];
};
#pragma pack(pop)
void compare(const struct s *left, const struct s *right) {
if (0 == memcmp(left, right, sizeof(struct s))) {
/* ... */
}
}