प्रारंभिक / रीसेट संरचना को शून्य / अशक्त करने के लिए


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;

1
@ डेविड हेफर्नन: memsetयदि मैं केवल सब कुछ रीसेट करना चाहता हूं तो क्या यह उपयोग करने से बेहतर है 0??
हरि

9
@hari मैं खुद इस दृष्टिकोण को प्राथमिकता दूंगा। उपयोग करने memsetसे मुझे गंदा लगता है। मैं संकलक को जहां भी संभव हो मेमोरी लेआउट के बारे में चिंता करने देना पसंद करता हूं। कड़ाई से इस तरह के बोलना memsetगैर-पोर्टेबल है, लेकिन व्यवहार में अगर आप कभी भी अपने कोड को कहीं भी संकलित करते हैं तो मैं चकित रह जाऊंगा। इसलिए, यदि आप इसे पसंद करते हैं तो आप सुरक्षित रूप से मेमसेट का उपयोग कर सकते हैं।
डेविड हेफर्नन

2
@हारी, यह वैचारिक रूप से बेहतर है, जब आप एक डिफ़ॉल्ट आरंभीकरण मान प्रदान करते हैं (ऑब्जेक्ट फैक्ट्री पैटर्न जैसा कुछ।)
डिएगो सेविला

1
@cnicutar मुझे यह पता है। ध्यान दें कि मेरा उत्तर मेमसेट का उपयोग नहीं करने की सलाह देता है। टिप्पणी के बारे में भी टिप्पणी करें कि मैं अशक्त मूल्यों को निर्दिष्ट करने के साधन के रूप में मेमसेट के उपयोग की गैर-पोर्टेबिलिटी को इंगित करता हूं। मेरी पिछली टिप्पणी सिर्फ वास्तविकता को इंगित करती है कि 0 बिट्स फ्लोटिंग पॉइंट जीरो के अनुरूप हैं।
डेविड हेफर्नन

1
@ kp11 उद्धरण कृपया
डेविड

85

जब आपके पास आधुनिक सी (C99) है, तो ऐसा करने का तरीका एक यौगिक शाब्दिक का उपयोग करना है

a = (const struct x){ 0 };

यह कुछ हद तक डेविड के समाधान के समान है, केवल आपको खाली संरचना या इसे घोषित करने की घोषणा करने के लिए परेशान होने की आवश्यकता नहीं है static। यदि आप मेरे द्वारा किए गए अनुसार उपयोग करते हैं const, तो कंपाइलर कंपाउंड को शाब्दिक रूप से उपयुक्त होने पर रीड-ओनली स्टोरेज में स्टैटिकली आवंटित करने के लिए स्वतंत्र है।


क्या यह स्टैक पर x का एक उदाहरण बनाता है फिर उसे कॉपी करने के लिए? बड़ी संरचनाओं / छोटे ढेर के लिए जो एक समस्या हो सकती है।
.तिने

1
सभी अनुकूलन की तरह, यह पूरी तरह से कंपाइलर निर्भर है, इसलिए आपको यह जांचना होगा कि आपका कंपाइलर क्या उत्पादन करता है। "आमतौर पर" आधुनिक कंपाइलरों पर यह नहीं होता है, ये इनिशियलाइज़ेशन को बहुत अच्छी तरह से ट्रेस कर सकते हैं और केवल वही करते हैं जो आवश्यक है, अधिक नहीं। (और ऐसा मत सोचो कि ऐसी चीजें समस्याएं हैं इससे पहले कि आप एक वास्तविक धीमा उपाय करें। वे आमतौर पर नहीं होते हैं।)
जेन्स गुस्टेड

3
"लापता आरंभीकरण" चेतावनी वास्तव में फर्जी है। C मानक वास्तव में क्या होता है की तुलना में निर्धारित करता है, और { 0 }डिफ़ॉल्ट आरंभीकरण के रूप में forsees । चेतावनी है कि बंद करो, यह नकली गलत अलार्म है।
जेन्स गुस्टेड 16

1
@JensGustedt क्या इस टाइपकास्टिंग की वास्तव में जरूरत है? क्या मैं इसे इस तरह नहीं लिख सकता? संरचना xa = (const) {0};
पैट्रिक

1
@ पैट्रिक, हालांकि वाक्य रचना समान है यह एक कास्ट नहीं है बल्कि एक "यौगिक शाब्दिक" है। और आप आरंभीकरण और असाइनमेंट को मिला रहे हैं।
जेन्स गुस्तेद

58

उपरोक्त सभी से बेहतर है कि संरचित आरंभीकरण के लिए मानक C विनिर्देश का उपयोग किया जाए:

struct StructType structVar = {0};

यहां सभी बिट्स शून्य (कभी) हैं।


13
मुझे नहीं लगता कि आप हर बार एक लूप के आसपास ऐसा कर सकते हैं
डेविड हेफर्नन

2
यह वास्तव में काम करने के लिए लगता है। लेकिन दुर्भाग्य से, जीसीसी और जी ++ इसके बारे में शिकायत करते हैं। gcc चेतावनी देता है, जबकि g ++ एक त्रुटि उत्पन्न करता है। मुझे पता है कि इस पर जीसीसी एंड जी ++ गलत हैं (वे मानक सी विनिर्देश का पालन करने वाले हैं), लेकिन फिर भी, अच्छी पोर्टेबिलिटी के लिए, इस तरह की सीमा को ध्यान में रखना अनिवार्य है।
सियान

3
@ Cyan आप {}C ++ में उपयोग कर सकते हैं । सीसीसी देवता अनिश्चित हैं कि क्या सी ++ समर्थन करने वाला है{0} और मैं स्वयं मानक के उस हिस्से से परिचित नहीं हूं।
मैथ्यू पढ़ें

@ मैथ्यू: हां, वास्तव में, मैंने मेमसेट () का उपयोग करके समाप्त किया, क्योंकि {0}या के साथ बहुत अधिक पोर्टेबिलिटी मुद्दे थे {}। सुनिश्चित नहीं है कि इस मुद्दे पर C & C ++ मानक स्पष्ट हैं और सिंक में हैं, लेकिन जाहिर है, संकलक नहीं हैं।
सियान

ऐसे मामले में काम करेगा? struct StructType structVar = malloc (sizeof(StructType)); structVar ={0}
सैम थॉमस

34

सी में, एक structउपयोग के लिए मेमोरी को शून्य करना एक सामान्य मुहावरा है memset:

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

तकनीकी रूप से, मुझे विश्वास नहीं है कि यह पोर्टेबल है क्योंकि यह मानता है कि NULLएक मशीन पर सूचक पूर्णांक मान 0 द्वारा दर्शाया गया है, लेकिन इसका व्यापक रूप से उपयोग किया जाता है क्योंकि अधिकांश मशीनों में ऐसा होता है।

यदि आप C से C ++ तक जाते हैं, तो सावधान रहें कि इस तकनीक का उपयोग हर वस्तु पर न करें। C ++ केवल किसी भी सदस्य कार्यों और कोई विरासत के साथ वस्तुओं पर यह कानूनी बनाता है।


2
C मानक बताता है कि NULL हमेशा 0. होता है। यदि मशीन को इस तरह से डिज़ाइन किया गया है कि एक पूर्व निर्धारित अवैध पता शाब्दिक रूप से 0 नहीं है, तो उस आर्किटेक्चर के संकलनकर्ता को संकलन के दौरान समायोजित करना होगा।
केविन एम

8
@ केविनम हां, प्रतीक "0" हमेशा NULL पॉइंटर के अनुरूप होता है, भले ही वह ऑल-जीरो हो; लेकिन वहाँ कुछ भी नहीं है संकलक कर सकते हैं यदि आप बिट्स को सेट करने के लिए शून्य का उपयोग करते हैं।
एड्रियन रत्नापाल

"C ++ केवल बिना किसी सदस्य कार्यों और कोई विरासत के साथ वस्तुओं पर यह कानूनी बनाता है।" यह इस बारे में है कि क्या प्रकार को 'सादा पुराना डेटा' माना जाता है। मापदंड C ++ भाषा के संस्करण पर निर्भर करते हैं।
मैक्स बर्राक्लो

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));

1
मुझे नहीं लगता कि यहां कास्ट जरूरी है। क्या यह?
टेम्प्लेटेटेपीडिफ

खैर, मैं C ++ के लिए बहुत अभ्यस्त हूं ... ठीक है, यह C ++ में भी काम करेगा, इसलिए मैं इसे बोझ के रूप में नहीं देखता हूं।
डिएगो सेविला

हाँ, मैं पर्याप्त विशिष्ट नहीं था। यह cv योग्य T के लिए कोई भी सूचक है जिसे cv योग्य शून्य * में परिवर्तित किया जा सकता है। कोई भी डेटा पॉइंटर, फंक्शन पॉइंटर्स पूरी तरह से अलग मामला है। कुडोस @ केविन
मार्कस

memsetएक विकल्प है, लेकिन इसका उपयोग करते समय, आपको यह सुनिश्चित करना होगा कि लिखी गई मेमोरी तीसरे पैरामीटर के समान आकार की है, इसीलिए वास्तविक वस्तु के आकार को संदर्भित करना बेहतर है, न कि आपके प्रकार का आकार वर्तमान में यह पता है। IOW memset (&x_instance, 0, sizeof(x_instance));एक बेहतर विकल्प है। BTW: (void*)कलाकार C ++ में भी शानदार है।
वुल्फ

(क्षमा करें, मैं इस प्रश्न को देखने से चूक गया, यह अब बेहतर है)
वुल्फ

5

मेरा मानना ​​है कि आप खाली {}चर ( ) को अपने चर में नियत कर सकते हैं।

struct x instance;

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


-1

छवि विवरण यहां दर्ज करें gnu11 से आश्चर्यचकित करें!

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

TgotoData tmpData = { 0 };

कुछ भी शून्य नहीं है।


1
यह "मैं सभी क्षेत्रों को 0 पर कैसे रीसेट कर सकता हूं" के प्रश्न का उत्तर देने का प्रयास नहीं करता है
एमएम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.