2009-08-25 12 views
57

निम्नलिखित कार्यक्रम को देखते हुए,जब किसी फ़ंक्शन में एक विशिष्ट-आकार सरणी पैरामीटर होता है, तो इसे पॉइंटर के साथ क्यों बदला जाता है?

#include <iostream> 

using namespace std; 

void foo(char a[100]) 
{ 
    cout << "foo() " << sizeof(a) << endl; 
} 

int main() 
{ 
    char bar[100] = { 0 }; 
    cout << "main() " << sizeof(bar) << endl; 
    foo(bar); 
    return 0; 
} 

आउटपुट

main() 100 
foo() 4 
  1. क्यों सरणी पहला तत्व के सूचक के रूप पारित हो जाता है?
  2. क्या यह सी से विरासत है?
  3. मानक क्या कहता है?
  4. सी ++ की सख्त प्रकार-सुरक्षा क्यों गिरा दी गई है?
+0

मैं हमेशा एसटीडी का उपयोग :: सरणी इन मामलों में, इस तरह की समस्या से निपटने के लिए होने और एसटीडी एल्गोरिदम के साथ भी काम करता है – paulm

+2

क्या सख्त प्रकार सुरक्षा रोकता है? सख्त प्रकार की सुरक्षा का वादा किसने किया है? सी ++ में ऐसी कोई बात नहीं है। –

+0

टीएल; नीचे दिए गए उत्तरों के लिए डीआर: समारोह में पारित होने पर Arrays पॉइंटर्स बन जाते हैं, इसलिए जब आप अपना आकार जांचते हैं तो आपको पॉइंटर का आकार मिलता है। यदि आप केवल सी के साथ काम कर रहे हैं, तो मैं सुझाव दे सकता हूं कि आप किसी अन्य पैरामीटर के रूप में सरणी से बाहर निकलने का प्रयास कर रहे आकार को पहले से गणना करें। –

उत्तर

63

हाँ, यह सी से विरासत में मिली है समारोह:

void foo (char a[100]); 

पैरामीटर एक सूचक होने के लिए समायोजित किया होगा, और इतना हो जाता है:

void foo (char * a); 

यदि आप चाहते हैं कि सरणी प्रकार संरक्षित है, तो आपको सरणी के संदर्भ में पास होना चाहिए:

void foo (char (&a)[100]); 

सी ++ '03 8.3.5/3:

... एक समारोह के प्रकार के निम्नलिखित नियमों का उपयोग निर्धारित होता है। प्रत्येक पैरामीटर का प्रकार अपने स्वयं के घोषित-विनिर्देशक-सेक और घोषणाकर्ता से निर्धारित होता है। प्रत्येक पैरामीटर के प्रकार का निर्धारण करने के बाद, "सरणी की टी" या "फ़ंक्शन रिटर्निंग टी" के किसी पैरामीटर को क्रमशः "पॉइंटर टू टी" या "ट्रिगर रिटर्निंग टी के लिए सूचक" के रूप में समायोजित किया जाता है ....

वाक्य रचना की व्याख्या करने के लिए: गूगल में "सही-बाएँ" शासन के लिए

चेक; मुझे here का एक विवरण मिला।

यह रूप में लगभग इस उदाहरण पर लागू किया जाएगा इस प्रकार है: पहचानकर्ता में 'एक'

'एक' एक

चाल सही है

void foo (char (&a)[100]); 

प्रारंभ - हम पाते हैं ) इसलिए हम ( की तलाश में दिशा को उलट देते हैं। हम छोड़ दिया ले जाते हैं हम &

पारित 'एक' एक संदर्भ

& हम उद्घाटन ( तो हम फिर से रिवर्स और सही लग रही तक पहुँचने के बाद है। अब हम देखते हैं [100]

'एक' 100

की एक सरणी के लिए एक संदर्भ है और हम फिर से दिशा रिवर्स जब तक हम char तक पहुँचने:

'एक' के लिए एक संदर्भ है 100 वर्णों की एक सरणी

+1

बाद वाले को फ़ंक्शन हस्ताक्षर में सरणी आकार को हार्डवायर करने का नुकसान होता है। एक फ़ंक्शन टेम्पलेट इससे बच सकता है। – sbi

+0

कुछ हद तक संबंधित नोट पर, क्या कोई मेरे लिए उपरोक्त के वाक्यविन्यास को साफ़ कर सकता है? मुझे स्पष्ट रूप से कुछ याद आ रहा है, लेकिन मुझे नहीं लगता कि यह एक सरणी के संदर्भ में कैसे मूल्यांकन करता है; यह संदर्भों की एक सरणी की तरह दिखता है। – suszterpatt

+4

यह शायद उल्लेखनीय है कि एक std :: वेक्टर का उपयोग करके गुजरने वाले सरणी से संबंधित सभी समस्याओं को अच्छी तरह से कदम उठाएंगे। – markh44

12

हां। सी और सी ++ में आप कार्यों के लिए सरणी पास नहीं कर सकते हैं। यह वैसा ही है जैसा होना चाहिए।

आप सादे सरणी क्यों कर रहे हैं? क्या आपने boost/std::tr1::array/std::array या std::vector पर देखा है?

ध्यान दें कि आप, फ़ंक्शन टेम्पलेट पर मनमाने ढंग से लंबाई की सरणी के संदर्भ को पारित कर सकते हैं। मेरे सिर के ऊपर बंद:

template< std::size_t N > 
void f(char (&arr)[N]) 
{ 
    std::cout << sizeof(arr) << '\n'; 
} 
+5

लेकिन आप "सरणी के संदर्भ" में जा सकते हैं। –

+0

बस कुछ विरासत कोड – CsTamas

+0

@ रिचर्ड: जब आप अपनी टिप्पणी लिखते थे तो मैं इसे जोड़ रहा था। ':)' – sbi

1

सी/सी ++ शब्दावली में शानदार शब्द है जिसका उपयोग स्थिर सरणी के लिए किया जाता है डी फ़ंक्शन पॉइंटर्स - क्षय। निम्नलिखित कोड पर विचार करें:

int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints 
//... 
void f(int a[]) { 
    // ... 
} 
// ... 
f(intArray); // only pointer to the first array element is passed 
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5) 
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system 
+1

और? यह, सबसे अच्छा, परोक्ष रूप से _what_ होता है इंगित करता है। ओपी पूछ रहा था _why_ भाषा इस तरह से स्थापित है। साथ ही, "स्थैतिक सरणी" एक भ्रमित शब्द है जब आप वास्तव में क्या मतलब गतिशील आवंटित किया जाता है; तकनीकी रूप से, आपके द्वारा दिखाए गए सरणी में 'बाहरी' लिंक है, न कि 'स्थिर '। और मुझे यकीन नहीं है कि फ़ंक्शन पॉइंटर्स को यहां कुछ भी करना है? –

संबंधित मुद्दे

 संबंधित मुद्दे