2014-04-07 5 views
6

"Difference between passing array and array pointer into function in C" के अनुसार, पैरामीटर घोषित करने के इन दो तरीकों के बीच कोई अर्थपूर्ण अंतर नहीं है क्योंकि "सरणी पैरामीटर [माना जा रहा है] जैसे कि उन्हें पॉइंटर्स के रूप में घोषित किया गया था"।किसी ने कभी भी प्रकार सरणी का पैरामीटर घोषित क्यों किया?

void f1(int a[]) { /* ... */ } 
void f2(int* a) { /* ... */ } 

हालांकि, सरणी और पॉइंटर्स से निपटने के बीच एक बड़ा अंतर है। उदाहरण के लिए, sizeof(some_array) का उपयोग करके सरणी का आकार पता लगा सकता है। एक पॉइंटर से निपटने पर, हालांकि, यह सिर्फ पॉइंटर के आकार को प्रकट करने जा रहा है। (Sidenote: This उस मुद्दे से संबंधित एक सुंदर साफ कामकाज है।)

यही कारण है कि मुझे इसे पैरामीटर घोषित करने के लिए भ्रामक लगता है: f1(int a[])djechlin "Difference between array and pointer as a function's argument in c" में इंगित किया गया है, मुझे लगता है कि यह सोचने में एक चाल कर सकता है कि वास्तव में केवल पॉइंटर्स की बजाय सरणी से निपट रहा है: "इसलिए मैं हमेशा पॉइंटर फॉर्म पसंद करता हूं, क्योंकि सरणी फॉर्म सूक्ष्म भ्रम पैदा कर सकता है। "

कहा जा रहा है, मुझे आश्चर्य है कि लोग "सरणी रूप" का उपयोग क्यों करते रहते हैं क्योंकि ऐसा करने का कोई कारण नहीं है। मुझे यहां क्या समझ नहीं आ रहा है? अपनी पुस्तक Learn C The Hard Way में, Zed Shaw वास्तव में दोनों तरीकों से घुलमिल:

void print_arguments(int argc, char *argv[]) { /* ... */ } 

उन्होंने यह भी कश्मीर & R2 में करते हैं।

क्यों? मैं इसे करने के कारणों से परिचित हूं, लेकिन पेशेवर क्या हैं?

+6

सरणी नोटेशन इंगित करता है * इरादा *: सूचक एक तत्व के बजाय एक सरणी में इंगित करने के लिए है। –

+1

'char * argv []' स्ट्रिंग की सरणी होने के तुरंत बाद स्पष्ट है। 'char ** argv' काफी स्पष्ट रूप से लिखा नहीं गया है। – Matt

+0

कारण कोड इंडेंटेशन और लंबे पहचानकर्ताओं का उपयोग करने के लिए समान है। आप जानते हैं, वे कोई अर्थपूर्ण अंतर नहीं बनाते हैं। –

उत्तर

2

कौन सा समझने के लिए आसान है:

char *argv[] is intended to be an array of pointers to chars 

या

char **argv is a pointer to a pointer to a char 

हाँ, आप एक गैर सहज तरीके से सी कोड कर सकते हैं, लेकिन आप क्यों करेंगे?

जो तुम करना पसंद करते हैं:

a[2] 
*(a + 2) 
*(2 + a) 
2[a] 

सभी एक ही प्रभाव है।[] का उपयोग क्यों करें जब यह सिंटैक्टिक चीनी है? क्योंकि यह अधिक पठनीय है। इसी तरह की नस में: (*ps).memberps->member

3

तकनीकी रूप से, मुझे किसी भी कारण से अनजान है, लेकिन अर्थात् अर्थ बहुत स्पष्ट है।

यदि मुझे लगता है कि कोई फ़ंक्शन किसी चीज़ को पॉइंटर लेता है, तो मैं उम्मीद करता हूं कि यह एक ही आइटम हो, जब तक वेरिएबल नाम (और/या संभवतः फ़ंक्शन नाम) यह स्पष्ट नहीं करता कि यह एक सरणी की अपेक्षा करेगा।

जबकि अगर इसे सरणी लेने के रूप में लेबल किया गया है, तो यह काफी स्पष्ट है। यह विशेष रूप से ** के साथ मामला है - char *argv[] उदाहरण लें। यह स्पष्ट रूप से char* (यानी तार) की सरणी के लिए एक सूचक है। char **argv वह हो सकता है, लेकिन यह एक परिवर्तनीय सूचक भी हो सकता है (उदा। मुक्त करने के लिए)। जबकि char argv[][] एक दो आयामी सरणी इंगित करेगा (कुछ char *argv[] नहीं करता है)।

0

हालांकि दोनों घोषणाएं समान हैं, पहले जब आप एक सरणी को पॉइंटर पास करना चाहते हैं तो सबसे पहले बेहतर होता है। कोई आसानी से समझ सकता है।
बाद के मामले में, यह अनुमान लगाने योग्य नहीं है कि क्या आप एक तत्व या सरणी में पॉइंटर पास कर रहे हैं।

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

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