हर सी प्रोग्रामर इस प्रसिद्ध मैक्रो के साथ एक सरणी में तत्वों की संख्या निर्धारित कर सकते हैं:मज़बूती से एक सरणी में तत्वों की संख्या का निर्धारण
int numbers[] = {2, 3, 5, 7, 11, 13, 17, 19};
printf("%lu\n", NUM_ELEMS(numbers)); // 8, as expected
:
#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
यहाँ एक ठेठ उपयोग मामला है
हालांकि, कुछ भी नहीं गलती से एक सरणी के बजाय एक सूचक पारित करने से रोकता है प्रोग्रामर:
int * pointer = numbers;
printf("%lu\n", NUM_ELEMS(pointer));
मेरे सिस्टम पर, यह 2 प्रिंट करता है, क्योंकि स्पष्ट रूप से, एक सूचक एक पूर्णांक के रूप में दोगुना बड़ा होता है। मैं कैसे गलती से एक सूचक पारित करने से प्रोग्रामर को रोकने के लिए के बारे में सोचा है, और मैं एक समाधान मिला:
#define NUM_ELEMS(a) (assert((void*)&(a) == (void*)(a)), (sizeof(a)/sizeof 0[a]))
यह काम करता है क्योंकि एक सरणी के लिए सूचक अपनी पहली तत्व के सूचक के रूप में एक ही मूल्य है। यदि आप इसके बजाय एक पॉइंटर पास करते हैं, तो पॉइंटर की तुलना एक सूचक के साथ की जाएगी, जो लगभग हमेशा झूठी होती है। (एकमात्र अपवाद एक पुनरावर्ती शून्य सूचक, वह है, एक शून्य सूचक है जो अपने आप को इंगित करता है मुझे लगता है कि के साथ रह सकते हैं।।)
गलती से एक सरणी के बजाय एक सूचक गुजर अब कार्यावधि में एक त्रुटि से चलाता है:
Assertion `(void*)&(pointer) == (void*)(pointer)' failed.
अच्छा!
अल्पविराम अभिव्यक्ति मान्य मानक सी के बाईं संकार्य के रूप में
assert
की मेरी उपयोग है: अब मैं सवालों की एक जोड़ी है? यही है, क्या मानक मुझे अभिव्यक्ति के रूप मेंassert
का उपयोग करने की अनुमति देता है? क्षमा करें अगर यह एक मूक सवाल :)जांच किसी भी तरह संकलन समय पर किया जा सकता है है?
मेरे सी संकलक सोचता है कि
int b[NUM_ELEMS(a)];
एक VLA है। अन्यथा उसे मनाने के लिए कोई रास्ता?मैं पहली बार इस के बारे में सोचना है? यदि हां, तो मैं स्वर्ग में मेरे लिए कितने कुंवारी इंतजार कर सकता हूं? :)
भाग के लिए (4), यह सुनिश्चित है कि यह * 72 * नहीं है। मुझे लगता है कि टी टोपी किसी और चीज के लिए आरक्षित मूल्य है ... –
क्या आपका मतलब है 'आकार [0] '? –
प्रत्येक वास्तविक सी प्रोग्रामर जानता है कि सरणी के आकार का ट्रैक रखना उनकी समस्या है, न कि कंपाइलर्स और "इसे समझने" के लिए ये चाल सख्ती से सीमित उपयोगिता के कारण हैं क्योंकि वह जानकारी केवल दायरे में ही बरकरार है।यदि आप चाहते हैं कि संकलक आपके लिए इसका ख्याल रखे, तो एक स्मार्ट भाषा का उपयोग करें। मेरा मतलब है, आपको केवल सी ++ पर जाना होगा और 'std :: vector' या (C++ 11 के साथ)' std :: array' का उपयोग करना होगा, इसलिए यह एक बड़ा बदलाव नहीं है। – dmckee