मैं सिर्फ C सीख रहा हूं और सोच रहा था कि इनमें से कौन सी अपनी मुख्य विधि का उपयोग करूं। क्या कोई अंतर है? कौन सा अधिक आम है?
char **argv
बराबर है । 2. सरणियाँ संकेत नहीं हैं। char *argv[]
मैं सिर्फ C सीख रहा हूं और सोच रहा था कि इनमें से कौन सी अपनी मुख्य विधि का उपयोग करूं। क्या कोई अंतर है? कौन सा अधिक आम है?
char **argv
बराबर है । 2. सरणियाँ संकेत नहीं हैं। char *argv[]
जवाबों:
जैसा कि आप अभी C सीख रहे हैं, मैं आपको आम चीज़ों के बजाय पहले सरणियों और बिंदुओं के बीच के अंतर को समझने की कोशिश करने की सलाह देता हूँ ।
मापदंडों और सरणियों के क्षेत्र में, कुछ भ्रमित करने वाले नियम हैं जो जाने से पहले स्पष्ट होना चाहिए। सबसे पहले, आप एक पैरामीटर सूची में जो घोषित करते हैं वह विशेष माना जाता है। ऐसी परिस्थितियां हैं जहां सी। में फ़ंक्शन पैरामीटर के रूप में चीजें समझ में नहीं आती हैं
दूसरा शायद तुरंत स्पष्ट नहीं है। लेकिन यह स्पष्ट हो जाता है जब आप समझते हैं कि सरणी आयाम का आकार C में प्रकार का हिस्सा है (और ऐसा सरणी जिसका आयाम आकार नहीं दिया गया है, अधूरा प्रकार है)। इसलिए, यदि आप एक ऐसा फंक्शन बनाएंगे जो एक सरणी बाय-वैल्यू (एक कॉपी प्राप्त करता है), तो वह केवल एक आकार के लिए ऐसा कर सकता है! इसके अलावा, सरणियां बड़ी हो सकती हैं, और सी जितना संभव हो उतना तेज़ होने की कोशिश करता है।
C में, इन कारणों से, सरणी-मान मौजूद नहीं हैं। यदि आप किसी सरणी का मान प्राप्त करना चाहते हैं, तो आपको इसके बजाय जो मिलता है, वह उस सरणी के पहले तत्व का सूचक है। और यहाँ वास्तव में पहले से ही समाधान निहित है। एक सरणी पैरामीटर ड्राइंग के बजाय-सामने अमान्य, एक सी संकलक होगा परिणत संबंधित पैरामीटर के प्रकार के एक सूचक माना जाता है। यह याद रखें, यह बहुत महत्वपूर्ण है। पैरामीटर एक सरणी नहीं होगा, लेकिन इसके बजाय यह संबंधित तत्व प्रकार के लिए एक संकेतक होगा।
अब, यदि आप किसी ऐरे को पास करने की कोशिश करते हैं, तो इसके बजाय जो पास किया गया है, वह एरे के पहले एलिमेंट का पॉइंटर है।
पूरा करने के लिए, और क्योंकि मुझे लगता है कि इससे आपको मामले को बेहतर ढंग से समझने में मदद मिलेगी, आइए देखें कि जब आप एक पैरामीटर के रूप में फ़ंक्शन करने का प्रयास करते हैं तो स्थिति क्या होती है। वास्तव में, पहले इसका कोई मतलब नहीं होगा। एक पैरामीटर एक फ़ंक्शन कैसे हो सकता है? हुह, हम निश्चित रूप से उस जगह पर एक चर चाहते हैं! तो ऐसा होने पर कंपाइलर क्या करता है, फिर से, फंक्शन को फंक्शन पॉइंटर में बदलने के लिए । किसी फ़ंक्शन को पास करने की कोशिश करने से उस संबंधित फ़ंक्शन के लिए एक पॉइंटर पास किया जाएगा। तो, निम्नलिखित समान हैं (सरणी उदाहरण के अनुरूप):
void f(void g(void));
void f(void (*g)(void));
ध्यान दें कि चारों ओर कोष्ठक *g
की आवश्यकता है। अन्यथा, यह किसी फ़ंक्शन को इंगित void*
करने वाले के बजाय एक फ़ंक्शन लौटने के लिए एक फ़ंक्शन को निर्दिष्ट करेगा void
।
अब, मैंने शुरुआत में कहा कि सरणियों का एक अधूरा प्रकार हो सकता है - जो तब होता है जब आप अभी तक एक आकार नहीं देते हैं। चूंकि हमने पहले ही पता लगा लिया है कि एक सरणी पैरामीटर मौजूद नहीं है, लेकिन इसके बजाय किसी भी सरणी पैरामीटर एक सूचक है, सरणी का आकार कोई फर्क नहीं पड़ता। इसका मतलब है, कंपाइलर निम्नलिखित सभी का अनुवाद करेगा, और सभी एक ही चीज़ हैं:
int main(int c, char **argv);
int main(int c, char *argv[]);
int main(int c, char *argv[1]);
int main(int c, char *argv[42]);
बेशक, इसका कोई मतलब नहीं है कि इसमें कोई भी आकार डाल सकता है, और यह सिर्फ दूर फेंक दिया जाता है। उस कारण से, C99 उन संख्याओं के लिए एक नया अर्थ लेकर आया, और अन्य चीजों को कोष्ठक के बीच प्रदर्शित करने की अनुमति देता है:
// says: argv is a non-null pointer pointing to at least 5 char*'s
// allows CPU to pre-load some memory.
int main(int c, char *argv[static 5]);
// says: argv is a constant pointer pointing to a char*
int main(int c, char *argv[const]);
// says the same as the previous one
int main(int c, char ** const argv);
अंतिम दो पंक्तियों का कहना है कि आप फ़ंक्शन के भीतर "argv" को बदलने में सक्षम नहीं होंगे - यह एक कॉन्स्टेंट पॉइंटर बन गया है। हालांकि कुछ ही C कंपाइलर्स उन C99 फीचर्स को सपोर्ट करते हैं। लेकिन ये विशेषताएं यह स्पष्ट करती हैं कि "सरणी" वास्तव में एक नहीं है। यह एक पॉइंटर है।
ध्यान दें कि ऊपर कहा गया सब तभी सत्य है जब आपको किसी फ़ंक्शन के पैरामीटर के रूप में एक सरणी मिली हो । यदि आप स्थानीय सरणियों के साथ काम करते हैं, तो एक सरणी पॉइंटर नहीं होगी। यह एक सूचक के रूप में व्यवहार करेगा , क्योंकि जैसा कि पहले बताया गया है कि एक सरणी को सूचक में परिवर्तित किया जाएगा जब इसका मूल्य पढ़ा जाता है। लेकिन यह संकेतकर्ताओं के साथ भ्रमित नहीं होना चाहिए।
एक क्लासिक उदाहरण निम्नलिखित है:
char c[10];
char **c = &c; // does not work.
typedef char array[10];
array *pc = &c; // *does* work.
// same without typedef. Parens needed, because [...] has
// higher precedence than '*'. Analogous to the function example above.
char (*array)[10] = &c;
आप या तो उपयोग कर सकते हैं। वे पूरी तरह से समकक्ष हैं। देखें लिब की टिप्पणियाँ और उसका उत्तर ।
यह वास्तव में निर्भर करता है कि आप इसका उपयोग कैसे करना चाहते हैं (और आप किसी भी स्थिति में उपयोग कर सकते हैं):
// echo-with-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char **argv)
{
while (--argc > 0)
{
printf("%s ", *++argv);
}
printf("\n");
return 0;
}
// echo-without-pointer-arithmetic.c
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i=1; i<argc; i++)
{
printf("%s ", argv[i]);
}
printf("\n");
return 0;
}
जिसके लिए अधिक आम है - इससे कोई फर्क नहीं पड़ता। आपके कोड को पढ़ने वाला कोई भी अनुभवी सी प्रोग्रामर दोनों को विनिमेय (सही परिस्थितियों में) के रूप में देखेगा। जैसे एक अनुभवी अंग्रेजी वक्ता "वे" और "वे" समान रूप से आसानी से पढ़ते हैं।
अधिक महत्वपूर्ण यह है कि आप उन्हें पढ़ना सीखें और पहचानें कि वे कितने समान हैं। आप लिखने से अधिक कोड पढ़ रहे होंगे, और आपको दोनों के साथ समान रूप से सहज होने की आवश्यकता होगी।
char**
क्योंकि यह मुझे याद दिलाता है कि इसे वास्तविक सरणी के रूप में नहीं माना जाना चाहिए, जैसे करना sizeof[arr] / sizeof[*arr]
।
आप दो प्रकारों में से किसी एक का उपयोग कर सकते हैं, जैसा कि सी सरणियों और संकेत फ़ंक्शन पैरामीटर सूचियों में विनिमेय हैं। Http://en.wikipedia.org/wiki/C_(programming_language)#Array-pointer_interchangeability देखें ।
मुझे दूसरे के बजाय किसी भी दृष्टिकोण का उपयोग करने की कोई विशेष योग्यता नहीं दिखाई देती है - उस सम्मेलन का उपयोग करें जो आपके बाकी कोड के अनुरूप है।
मुझे पता है कि यह पुराना है, लेकिन अगर आप सी प्रोग्रामिंग भाषा सीख रहे हैं और इसके साथ कुछ भी नहीं कर रहे हैं, तो कमांड-लाइन विकल्पों का उपयोग न करें।
यदि आप कमांड लाइन तर्कों का उपयोग नहीं कर रहे हैं, तो या तो उपयोग न करें। मुख्य समारोह को घोषित करें जैसे कि int main()
आप
-help
, /?
या किसी भी अन्य बात यह है कि के बाद चला जाता है program name
टर्मिनल में या शीघ्र कमान)जो भी आप के लिए और अधिक समझ में आता है का उपयोग करें। अन्यथा, बस उपयोग करें int main()
आखिरकार, यदि आप कमांड-लाइन विकल्प जोड़ना चाहते हैं, तो आप उन्हें बाद में आसानी से संपादित कर सकते हैं।