2010-07-19 6 views
16

मैं किसी अन्य प्रश्न के उत्तर में इसे पहले देखकर याद कर रहा हूं, लेकिन खोज जवाब देने में विफल रही है।सी में, पॉइंटर्स घोषित करने के लिए सही वाक्यविन्यास क्या है?

मुझे याद नहीं है कि उचित पॉइंटर्स के रूप में घोषित करने के लिए उचित तरीका क्या है। यह है:

Type* instance; 

या: हालांकि मैं जानता हूँ कि दोनों ज्यादातर मामलों में संकलित कर देगा

Type *instance; 

, मेरा मानना ​​है कि वहाँ कुछ उदाहरण हैं, जहां यह एक ही प्रकार के एकाधिक चर घोषित करने से संबंधित महत्वपूर्ण है, संभवतः हैं एक ही पंक्ति पर, और इसलिए एक दूसरे की तुलना में अधिक समझ में आता है।

+0

संभावित डुप्लिकेट [सी ++ में पॉइंटर घोषणाएं: तारांकन की नियुक्ति] (http://stackoverflow.com/questions/180401/pointer-declarations-in-c-placement-of-the-asterisk) – Qadi

उत्तर

21

यह बस आप कैसे इसे पढ़ने के लिए पसंद की बात है: यदि आप एक सूचक int करने के लिए के रूप में p2 घोषित करने के लिए कामना की, तो आप लिखने के लिए की है।

कारण यह है कि कुछ लोगों को इस तरह रखा:

Type *instance; 

है क्योंकि यह कहते हैं कि केवल उदाहरण सूचक है। क्योंकि अगर आप चर की एक सूची है:

int* a, b, c; 

केवल एक एक सूचक है, तो यह तो

int *a, b, c, *d; 

कहाँ दोनों एक और घ संकेत दिए गए हैं की तरह आसान है। यह वास्तव में कोई फर्क नहीं पड़ता, यह सिर्फ पठनीयता के बारे में है।

अन्य लोगों को * प्रकार के बगल में रखने की तरह, क्योंकि (अन्य कारणों से) वे इसे "एक पूर्णांक के लिए सूचक" मानते हैं और सोचते हैं कि * प्रकार के साथ संबंधित है, चर नहीं।

व्यक्तिगत रूप से, मैं हमेशा

Type *instance; 

करते लेकिन यह वास्तव में आप पर निर्भर है, और आपकी कंपनी/स्कूल कोड शैली दिशानिर्देश।

+0

यह था, मुझे लगता है। यह एक पंक्ति में कई चर घोषित कर रहा था, और मुझे याद नहीं आया कि कंपाइलर ने "टाइप *" को एक प्रकार के रूप में माना था, या फिर * एक चर पर एक संशोधक की तरह था, यह बताता है कि यह एक प्रकार के उदाहरण के लिए सूचक था "प्रकार"। 'int * ए, बी, सी 'मुझे भ्रमित कर देगा, इसलिए कोई अन्य दिशानिर्देश होने के मामले में मैं' टाइप * इंस्टेंस 'का उपयोग करूंगा। – Edd

+0

मैं सी ++ में सी और 'int *' में 'int *' का उपयोग करता हूं। सी ++ में पहचानकर्ताओं को एक-एक करके घोषित करना आम तौर पर अच्छा अभ्यास होता है, इसलिए तर्क "int * a, b, c' fluffy" कम अर्थपूर्ण है। टाइप सिस्टम स्थिरता सी ++ मामले में चिंता का विषय है। –

3

वे दोनों बिल्कुल वही हैं।

हालांकि, कई चर घोषित करने के लिए, नीचे के रूप में के प्रयोजनों के लिए:

int * p1, p2; 

जहां p1 int करने के लिए प्रकार सूचक की है, लेकिन p2 प्रकार int की है।

int *p1, *p2; 
+0

यह सच है , एकल घोषणा के मामले में ओपी है, लेकिन सामान्य मामले में नहीं। – Puppy

+0

@DeadMG: यह सही है, स्पष्ट करने के लिए संपादित किया गया है। –

10

वे दोनों समान हैं। हालांकि, अगर आप कई घोषणाएं करते हैं, तो पूर्व आपको फंस सकता है।

int* pi, j;

किसी पूर्णांक सूचक (pi) और एक पूर्णांक (j) की घोषणा की।

1

उत्सुकता से, यदि नियम C++ 0x में टाइप किया जाता है तो यह नियम लागू नहीं होता है।

int a; 
decltype(&a) i, j; 

मैं और जे दोनों int * हैं।

Type *pointer; 

क्यों:

+2

मुझे नहीं लगता कि आपको ऐसे व्यवहार के लिए सी ++ 0x की आवश्यकता है। बस एक 'टाइपपीफ int * IntPtr;' बनाओ, फिर 'IntPtr i, j;' वही व्यवहार दिखाता है। – Philipp

2

मैं निम्नलिखित शैली पसंद करते हैं? क्योंकि यह मानसिकता के साथ संगत है भाषा के रचनाकारों की स्थापना करने की कोशिश की: "। एक चर की नकल करता है के लिए घोषणा की वाक्य रचना भाव की वाक्य रचना है, जिसमें चर प्रकट हो सकता है"

(The C Programming Language ब्रायन डब्ल्यू Kernighan & डेनिस एम रिची, ANSI C संस्करण, पेज 94 द्वारा) में

यह किसी भी भाषा में FORTRAN लिखना आसान है, लेकिन आप हमेशा लिखना चाहिए [प्रोग्रामिंग भाषा X] [प्रोग्रामिंग भाषा एक्स]।

6

यह सी सिंटैक्स का दुर्घटना है जिसे आप इसे किसी भी तरह लिख सकते हैं; हालांकि, यह हमेशा

Type (*pointer); 

है कि के रूप में पार्स किया जाता है, * हमेशा declarator, नहीं प्रकार निर्दिष्टकर्ता के लिए बाध्य है। यदि आप

Type* pointer1, pointer2; 

ने लिखा कि यह रूप में

Type (*pointer1), pointer2; 

इसलिए केवल pointer1 एक सूचक प्रकार के रूप में घोषित किया जाएगा पार्स किया जाएगा।

सी "घोषणा नकल उपयोग" प्रतिमान का पालन करता है; घोषणा की संरचना को जितना संभव हो सके कोड में उपयोग की जाने वाली समतुल्य अभिव्यक्ति की नकल करना चाहिए। उदाहरण के लिए, यदि आपके पास arr नामित int के लिए पॉइंटर्स की एक सरणी है, और आप सरणी में i'th तत्व द्वारा इंगित पूर्णांक मान को पुनर्प्राप्त करना चाहते हैं, तो आप सरणी को सब्सक्राइब करेंगे और परिणाम को dereference करेंगे, जो *arr[i] के रूप में लिखा गया है (*(arr[i]) के रूप में पार्स किया गया)। अभिव्यक्ति*arr[i]int है के प्रकार, तो arr के लिए घोषणा

int *arr[N]; 

रास्ता कौन सा सही है के रूप में लिखा है? इस पर निर्भर करता है कि आपने किससे पूछा है। मेरे जैसे पुराने सी farts T *p का पक्ष है क्योंकि यह व्याकरण में वास्तव में क्या हो रहा है दर्शाता है। कई सी ++ प्रोग्रामर T* p का पक्ष लेते हैं क्योंकि यह p के प्रकार पर जोर देता है, जो कई परिस्थितियों में अधिक प्राकृतिक महसूस करता है (मेरे स्वयं के कंटेनर प्रकार लिखने के बाद, मैं बिंदु देख सकता हूं, हालांकि यह अभी भी मुझे गलत लगता है)।

आप एक से अधिक संकेत घोषित करने के लिए चाहते हैं, तो आप या तो उन सब को स्पष्ट रूप से इस तरह के रूप घोषणा कर सकते हैं,:

T *p1, *p2, *p3; 

या आप एक typedef बना सकते हैं:

typedef T *tptr; 
tptr p1, p2, p3; 

हालांकि मैं व्यक्तिगत रूप से नहीं है सिफारिश करें; यदि आप सावधान नहीं हैं तो टाइपिफ के पीछे कुछ चीज के पॉइंटर-नेस को छिपाना आपको काट सकता है।

+0

स्मार्ट पॉइंटर्स का उपयोग करते समय टाइपिफ़ के साथ किसी चीज के पॉइंटर-नेस को छिपाना काफी आसान हो सकता है। 'MyClassPtr' लिखना' बूस्ट :: shared_ptr 'से बहुत तेज है, उदाहरण के लिए। –

+0

यह गधे में भी दर्द होता है जब आपको टेम्पलेट डायग्नोस्टिक्स की कई सौ पंक्तियों के माध्यम से ट्रैवल करना पड़ता है क्योंकि एक इटरेटर को ठीक से संदर्भित नहीं किया जाता है; यानी, आपको '(* it) -> foo()' के बजाय 'foo()' लिखना था, लेकिन क्योंकि इटरेटर को 'वेक्टर :: iterator' के बजाय घोषित किया गया था' वेक्टर :: इटरेटर ', आपको एहसास नहीं हुआ कि अतिरिक्त अव्यवस्था आवश्यक थी। वह सबसे अधिक उत्पादक दोपहर नहीं था। –

0

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

  • char *x मतलब यह है कि अगर आप *x करते हैं, आप एक char मिलता है।
  • int f(int x) का अर्थ है कि यदि आप उदा। f(0), आपको int मिलता है।
  • const char *foo[3] का अर्थ है कि यदि आप उदा। *foo[0] (जो *(foo[0]) जैसा है), आपको const char मिलता है। इसका तात्पर्य है कि foo पॉइंटर्स के const char पर एक सरणी (इस मामले में आकार 3 का) होना चाहिए।
  • unsigned int (*foo)[3] का अर्थ है कि यदि आप उदा। (*foo)[0], आपको unsigned int मिलता है। इसका तात्पर्य है कि foounsigned int (इस मामले में आकार 3 के) की एक सरणी के लिए एक सूचक होना चाहिए।

ढीले तौर पर, सामान्य वाक्यविन्यास [what you get] [how you get it] है। चाल यह है कि इसे एक साथ कई चीजों की घोषणा करने के लिए [what you get] [how you get it], [how you get it], ... तक बढ़ाया जा सकता है। इसलिए, निम्नलिखित तीन घोषणाओं -

int *p; 
int f(int x); 
int a[3]; 

- एक पंक्ति के रूप में इस प्रकार में जोड़ा जा सकता (और हाँ, यह भी समारोह घोषणाओं के लिए काम करता है वे इस संबंध में विशेष नहीं हैं।):

int *p, f(int x), a[3]; 
1

इन सभी के संकलन होगा, कानूनी रहे हैं और बराबर हैं:

Type* instance; 
Type * instance; 
Type *instance; 

एक शैली उठाओ और अनुरूप होना।

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

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