2014-08-29 4 views
6

मैं एक (C++) कोड जहां सरणियोंक्यों "int * और name" के रूप में सरणी पास करें?

void fun(int *& name){...} 

का उपयोग कर पारित कर रहे हैं दिया गया था, लेकिन उस के पीछे विचार यह क्या है? मुझे लगता है कि इसका मतलब है "संदर्भों की एक सरणी" लेकिन जब आप पहले तत्व को पॉइंटर पास करते हैं जो ठीक होगा, है ना? तो इस तरह से करने के लिए प्रेरणा क्या है?

+3

इसका मतलब है एक सूचक चर के संदर्भ। इसका उद्देश्य पॉइंटर वैरिएबल को पास करना है। –

+3

Arrays? ऐसे पैरामीटर के माध्यम से वास्तविक सरणी वस्तुओं को पार करना संभव नहीं है। आप जो पास कर सकते हैं वह एक * सूचक * है जो कुछ सरणी तत्व को इंगित करता है, लेकिन सरणी स्वयं ही नहीं। उदाहरण के लिए, आप इस फ़ंक्शन में सीधे 'int [10]' सरणी पास नहीं कर पाएंगे। – AnT

+0

यह जानना महत्वपूर्ण है कि ** सरणी पॉइंटर्स नहीं हैं, और पॉइंटर्स सरणी नहीं हैं **। उस पर अधिक जानकारी के लिए [** यह पोस्ट **] देखें (http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c)। – juanchopanza

उत्तर

5

फ़ंक्शन को पॉइंटर का संदर्भ प्राप्त होता है। इसका अर्थ यह है कि फ़ंक्शन केवल int को संशोधित नहीं कर सकता है जो कि name द्वारा इंगित किया गया है, लेकिन यह भी कि कॉलर में फ़ंक्शन कॉल में किए गए परिवर्तनों को भी बाहर दिखाई देगा।

उदाहरण:

#include <iostream> 

int* allocate() 
{ 
    return new int(); 
} 

void destroy(int*& ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int* foo = allocate(); 

    std::cout << foo << std::endl; 

    destroy(foo); 

    std::cout << foo << std::endl; 

    return 0; 
} 

आउटपुट है:

0x82dc008 
0 
1

इसका मतलब है कि समारोह फोन करने वाले में सूचक के मूल्य को संशोधित कर सकते हैं।

अर्थात

myName* foo; /* ToDo - initialise foo in some way*/ 
fun(foo); 
/* foo might now point to something else*/ 

मैं एक विरोधी पैटर्न के रूप में इस में मानते हैं। कारण यह है कि आपके कोड को पढ़ने वाले लोग foo को इस तरह से संशोधित करने की उम्मीद नहीं करेंगे क्योंकि कॉलिंग सिंटैक्स अधिक सामान्य फ़ंक्शन void anotherFun(int * name){...} से अलग नहीं है।

ऐसे कोड की स्थिरता भुगत सकती है। इस प्रकार, मैं आपके void fun(int ** name){...} का उपयोग करने की सलाह दूंगा। कॉलिंग सिंटैक्स तब fun(&foo) बन जाता है जो फ़ंक्शन उपयोगकर्ता को इंगित करता है कि foo संशोधित किया जा सकता है।

+1

मैं कहूंगा कि जब आप किसी संदर्भ का उपयोग कर सकते हैं तो पॉइंटर का उपयोग करने के लिए यह एक विरोधी पैटर्न है। लेकिन मैं कुछ अलग भी करता हूं: 'int * मजेदार (int * name);', और नया मान वापस करें। – juanchopanza

+0

खैर, मैं व्यक्तिगत रूप से पॉइंटर सिंटैक्स को पॉइंटर पसंद नहीं करता जहां इसकी वास्तव में आवश्यकता नहीं होती है। तो यह व्यक्तिगत वरीयता पर निर्भर करता है। हालांकि, मैं मानता हूं कि आम तौर पर यह कॉलर के लिए अप्रत्याशित हो सकता है कि सूचक को संशोधित किया जा सकता है। आपके द्वारा प्रस्तावित 'int **' का उपयोग करने का एक विकल्प है कि कार्यों के लिए चुने गए नामों के साथ एक स्पष्ट और अच्छी तरह से प्रलेखित एपीआई होना चाहिए, उदा। एक फ़ोल्डर के लिए हटाएं और SetNull (int * & ptr) 'जो एक सूचक को हटा देता है और इसे पूर्ण पर सेट करता है। – oxygene

+0

यह मजाकिया है कि यह कैसे विभाजित है: मैं स्पष्ट रूप से आपकी राय का सम्मान करता हूं और 'int * fun (int * name)' का उपयोग करने के प्रस्ताव की तरह। मैं ओपी के तरीके में इस्तेमाल किए गए संदर्भों को नापसंद करता हूं क्योंकि वे कोड को पढ़ने के लिए कड़ी मेहनत करते हैं और सहयोगी परियोजनाओं पर काम कर रहे जूनियर द्वारा बग पेश किए जा सकते हैं। यदि संभव हो तो कम से कम 'const & 'का उपयोग करें। – Bathsheba

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