आप मानक C में समानता के लिए संरचना के दो उदाहरणों की तुलना कैसे करते हैं?
आप मानक C में समानता के लिए संरचना के दो उदाहरणों की तुलना कैसे करते हैं?
जवाबों:
सी ऐसा करने के लिए कोई भाषा सुविधाएं प्रदान नहीं करता है - आपको इसे स्वयं करना होगा और सदस्य द्वारा प्रत्येक संरचना के सदस्य की तुलना करनी होगी।
0.0, -0.0 NaN
करना एक समस्या है memcmp()
। बाइनरी प्रतिनिधित्व में भिन्न होने वाले पॉइंटर्स एक ही स्थान (जैसे DOS: seg: ऑफसेट) की ओर इशारा कर सकते हैं और इसी तरह समान हैं। कुछ प्रणालियों में कई अशक्त बिंदु होते हैं जो समान रूप से तुलना करते हैं। int
अनावश्यक और अतिक्रमण के साथ -0 और अस्थायी बिंदु प्रकारों के साथ अस्पष्ट के लिए भी । (इंटेल लॉन्ग डबल, दशमलव 64, आदि) इन मुद्दों से कोई फर्क नहीं पड़ता है कि calloc()
इसका उपयोग किया जाता है या नहीं या पैडिंग।
==
संरचनाओं के साथ काम क्यों नहीं किया जा रहा है (मेरी तरह), तो कृपया देखें stackoverflow.com/questions/46995631/…
आप का उपयोग करने के लिए परीक्षा हो सकती है memcmp(&a, &b, sizeof(struct foo))
, लेकिन यह सभी स्थितियों में काम नहीं कर सकता है। संकलक एक संरचना में संरेखण बफर स्थान जोड़ सकता है, और बफर स्थान में पड़े मेमोरी स्थानों पर पाए जाने वाले मान किसी विशेष मूल्य के होने की गारंटी नहीं है।
लेकिन, यदि आप उपयोग करने से पहले संरचनाओं का उपयोग calloc
या memset
पूर्ण आकार देते हैं, तो आप उथले तुलना कर सकते हैं (यदि आपकी संरचना में संकेत होते हैं, तो यह केवल तभी मेल करेगा जब संकेत उसी ओर इशारा कर रहे हों)।memcmp
memcmp
बशर्ते कि मेमोरी पहले साफ़ हो गई हो। जो काम करने के करीब है लेकिन सही नहीं है। Ofc प्रश्न भी "समानता" को परिभाषित नहीं करता है, इसलिए यदि आप इसका अर्थ "ऑब्जेक्ट प्रतिनिधित्व की बाइट-वार समानता" लेते हैं, तो memcmp
ठीक यही करता है (चाहे मेमोरी क्लियर हो या नहीं)।
यदि आप इसे बहुत कुछ करते हैं तो मैं एक ऐसा कार्य लिखने का सुझाव दूंगा जो दो संरचनाओं की तुलना करता है। इस तरह, यदि आप कभी संरचना को बदलते हैं तो आपको केवल एक ही स्थान पर तुलना को बदलना होगा।
यह कैसे करना है के रूप में .... आपको प्रत्येक तत्व की व्यक्तिगत रूप से तुलना करने की आवश्यकता है
आप स्ट्रक्चर्स में फ़ील्ड के बीच संभावित बेतरतीब पैडिंग कैरेक्टर के कारण समानता के लिए स्ट्रक्चर्स की तुलना करने के लिए मेम्कैंप का उपयोग नहीं कर सकते।
// bad
memcmp(&struct1, &struct2, sizeof(struct1));
इस तरह की संरचना के लिए उपरोक्त विफल होगा:
typedef struct Foo {
char a;
/* padding */
double d;
/* padding */
char e;
/* padding */
int f;
} Foo ;
आपको सुरक्षित रहने के लिए सदस्य-वार तुलना का उपयोग करना होगा।
@Greg सही है कि किसी को सामान्य मामले में स्पष्ट तुलना कार्य लिखना चाहिए।
memcmp
यदि इसका उपयोग करना संभव है :
NaN
।-Wpadded
इसे जांचने के लिए क्लैंग के साथ उपयोग करें) या स्ट्रक्चर्स को स्पष्ट रूप से इनिशियलाइज़ेशन के साथ शुरू किया memset
जाता है।BOOL
) में अलग-अलग लेकिन समान मूल्य नहीं हैं।जब तक आप एम्बेडेड सिस्टम के लिए प्रोग्रामिंग नहीं कर रहे हैं (या उन पर इस्तेमाल होने वाली लाइब्रेरी लिख रहे हैं), मैं सी मानक में कोने के कुछ मामलों के बारे में चिंता नहीं करूंगा। निकट बनाम दूर सूचक भेद किसी भी 32- या 64-बिट डिवाइस पर मौजूद नहीं है। कोई भी गैर-एम्बेडेड सिस्टम जो मुझे पता है कि कई NULL
पॉइंटर्स हैं।
एक अन्य विकल्प समानता कार्यों को ऑटो-जनरेट करना है। यदि आप अपनी संरचना परिभाषाओं को सरल तरीके से रखते हैं, तो सरल संरचना परिभाषाओं को संभालने के लिए सरल पाठ प्रसंस्करण का उपयोग करना संभव है। आप सामान्य मामले के लिए libclang का उपयोग कर सकते हैं - चूंकि यह क्लैंग के रूप में एक ही दृश्यपटल का उपयोग करता है, यह सभी कोने के मामलों को सही ढंग से (बैरिंग कीड़े) को संभालता है।
मैंने ऐसी कोड जनरेशन लाइब्रेरी नहीं देखी है। हालाँकि, यह अपेक्षाकृत सरल प्रतीत होता है।
हालांकि, यह भी मामला है कि इस तरह के उत्पन्न समानता कार्य अक्सर आवेदन स्तर पर गलत काम करेंगे। उदाहरण के लिए, UNICODE_STRING
विंडोज में दो संरचनाओं की तुलना उथली या गहराई से की जानी चाहिए ?
ध्यान दें कि जब तक आप सभी सदस्यों को एक बार में आरंभ नहीं करते हैं, तब तक आप पैडिंग की चिंता किए बिना नॉन स्टैटिक स्ट्रेक्चर पर मेम्कैंप () का उपयोग कर सकते हैं। यह C90 द्वारा परिभाषित किया गया है:
{0, }
किसी भी पेडिंग बाइट को शून्य करेगा?
यह इस बात पर निर्भर करता है कि आप जो प्रश्न पूछ रहे हैं वह है:
यह पता लगाने के लिए कि क्या वे समान वस्तु हैं, समानता के लिए दो संरचनाओं की ओर संकेत करते हैं। यदि आप सामान्य रूप से यह पता लगाना चाहते हैं कि क्या उनका समान मूल्य है तो आपको गहरी तुलना करनी होगी। इसमें सभी सदस्यों की तुलना करना शामिल है। यदि सदस्य अन्य संरचनाओं के संकेत हैं, तो आपको उन संरचनाओं में भी पुनरावृत्ति करने की आवश्यकता है।
विशेष मामले में जहां संरचनाओं में पॉइंटर्स नहीं होते हैं, आप प्रत्येक डेटा में मौजूद डेटा की एक बिटवाइज़ तुलना करने के लिए एक मेम्कप कर सकते हैं, बिना यह जाने कि डेटा का क्या मतलब है।
सुनिश्चित करें कि आप जानते हैं कि प्रत्येक सदस्य के लिए sure बराबरी ’का क्या अर्थ है - यह फ़्लोट-पॉइंट मान या उपयोगकर्ता-परिभाषित प्रकार की बात होने पर, इन्टल्स के लिए अधिक सूक्ष्म है।
memcmp
संरचना की तुलना नहीं करता है, memcmp
बाइनरी की तुलना करता है, और संरचना में हमेशा कचरा होता है, इसलिए यह तुलना में हमेशा गलत निकलता है।
तत्व की तुलना अपने सुरक्षित तत्व से करें और असफल न हों।
यदि संरचनाओं में केवल आदिम हैं या यदि आप सख्त समानता में रुचि रखते हैं तो आप ऐसा कुछ कर सकते हैं:
int my_struct_cmp (const संरचना my_struct * lhs, const संरचना my_struct * rhs) { वापसी मेम्कम्प (lhs, rsh, sizeof (स्ट्रक्चर my_struct)); }
हालाँकि, यदि आपकी संरचना में अन्य संरचनाओं या यूनियनों के संकेत होते हैं, तो आपको एक फ़ंक्शन लिखना होगा जो प्राथमिकताओं की ठीक से तुलना करता है और अन्य संरचनाओं के खिलाफ तुलनात्मक कॉल को उपयुक्त बनाता है।
हालाँकि, अवगत रहें, कि आपको ADT इनिशियलाइज़ेशन के भाग के रूप में स्ट्रक्चर्स की मेमोरी रेंज को शून्य करने के लिए मेमसेट (&, a, sizeof (स्ट्रक्चर माय_स्ट्रैक), 1) का उपयोग करना चाहिए था।
यह अनुपालन उदाहरण Microsoft Visual Studio से #pragma पैक कंपाइलर एक्सटेंशन का उपयोग करता है ताकि यह सुनिश्चित हो सके कि संरचना सदस्यों को कसकर पैक किया गया है:
#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))) {
/* ... */
}
}