2012-01-20 24 views
11

जब सी में संकेत घोषणा करते हुए देखते हैं 2 (संपादित करें: 3) वेरिएंट:क्या सी में सूचक घोषणाओं के लिए कोई सम्मेलन है?

संस्करण एक:
int* ptr;

संस्करण बी:
int *ptr;

संस्करण सी:
int * ptr;

  • ए में, इंडिकेशन ऑपरेटर को इस प्रकार जोड़ा गया है।
  • बी में, इंडिकेशन ऑपरेटर को चर के लिए प्रीपेड किया गया है।
  • सी में, संकेतक ऑपरेटर प्रकार और चर के बीच स्वतंत्र रूप से खड़ा है।

जिस तरह से एक पॉइंटर घोषित किया गया है, वह दस्तावेज के प्रकार के आधार पर भिन्न होता है। कुछ लेखकों को कुछ रूपों के लिए प्राथमिकता प्रतीत होती है, अन्य कई का उपयोग करते हैं।

  • क्या मुझे लगता है कि अलग-अलग रूपों के बीच कार्यक्षमता में कोई अंतर नहीं है?
  • यदि हां, तो क्या कोई ऐसा सम्मेलन है जिसके लिए सी में सी का उपयोग किया जाना चाहिए?
+3

मुझे नहीं पता कि लोग इसे बंद करने के लिए क्यों मतदान कर रहे हैं।यह मेरे लिए एक वैध सवाल की तरह लगता है, लेकिन फिर मैं केवल 1 9 80 से हैकिंग सी रहा हूं। –

+1

@ पीटररवेल: इस तरह के मामूली सवाल के साथ एकमात्र समस्या यह है कि कोई भी Google या किसी अन्य खोज के साथ इसका उत्तर ऑनलाइन प्राप्त कर सकता है सेकंड के मामले में इंजन। और सी पर किसी भी सभ्य पुस्तक को भी यह समझा जाना चाहिए। उनका उपयोग क्यों नहीं करें? हालांकि, मैंने इसे बंद करने के लिए वोट नहीं दिया था। –

+1

संभावित डुप्लिकेट [क्या इससे कोई फर्क पड़ता है कि सी ++ में पॉइंटर्स घोषित करते समय मैं तारांकन कहां रखता हूं?] (Http://stackoverflow.com/questions/5449908/does-it-matter-where-i-place-the-asterisk-when -declaring-pointers-in-c) –

उत्तर

11

वहाँ

int* ptr; 

और

int *ptr; 

आप किसका उपयोग आप पर निर्भर है के बीच कार्यक्षमता में बिल्कुल कोई अंतर नहीं है, एक से अधिक परस्पर विरोधी कोडिंग शैलियों से चुनने के लिए कर रहे हैं।

+1

+1। जहां तक ​​एसओ का सवाल है, यह सही जवाब है। कोई फर्क नहीं पड़ता, और पसंद तुम्हारा है। –

+0

यदि आप तकनीकी प्राप्त करना चाहते हैं, तो 'int * ptr;' का उपयोग करके समकक्ष भी है। जब तक तारांकन प्रकार के नाम और परिवर्तनीय नाम के बीच होता है, तो व्हाइटस्पेस कोई फर्क नहीं पड़ता। – bta

+0

@DanFego: जहां तक ​​संकलक का संबंध है, यह सही जवाब है। एक फॉर्म या दूसरे का उपयोग करने के वैध कारण हैं, और एसओ उन कारणों पर चर्चा करने के लिए एक पूरी तरह से अच्छी जगह है। –

6

यह केवल तभी मायने रखता है जब आप एक ही प्रकार के एक ही प्रकार के एकाधिक चर घोषित करने की योजना बनाते हैं। उदाहरण के लिए, यदि आप कई पूर्णांक संकेत दिए गए हैं, तो आप ऐसा करने की जरूरत:

int *a, *b, *c; 

Stylistically हालांकि, इस जब आप केवल एक ही चर घोषणा कर रहे भ्रमित कर रहा है। बहुत से लोग प्रकार चर नाम और उसके बाद देखना पसंद है, और प्रकार, इंट सूचक नहीं int माना जाता है, इसलिए वे पसंद करते हैं:

int* a; 
int* b; 
int* c; 

यह आप पर निर्भर अंततः है कि क्या आप के ऊपर एक रूप को पसंद करते हैं अन्य। व्यावसायिक रूप से प्रोग्रामिंग सी के 20 वर्षों में, मैंने देखा है कि लगभग 50% लोग एक दूसरे को चुनते हैं।

+0

यह (उपरोक्त दो प्रकार) अजीब तारांकन संघ नियम से निपटने का एक बहुत ही स्पष्ट तरीका है। मैं 'int * ए, बी;', 'int a, * b;', और 'int * a, * b;' लिखने से बचता हूं क्योंकि वे ध्यान-कर रहे हैं, क्योंकि नहीं, क्योंकि मुझे नहीं पता कि उनमें से प्रत्येक का क्या अर्थ है । साथ ही, सभी चेतावनियों को सक्षम करने और कोड चेतावनी-साफ रखने के साथ संकलक के रूप में पूर्णांक के अवांछित उपयोग से बचने में मदद करता है और इसके विपरीत। –

+0

@ user1118321 कुछ ऐसे उत्तरों में से एक पोस्ट करने के लिए धन्यवाद जो वास्तव में इस मुद्दे को संबोधित करते हैं: एक ही पंक्ति पर एक से अधिक चर घोषित करते हैं। मैं * प्रकार के साथ * डालकर सख्ती से हूं क्योंकि यह दिखाता है कि डेवलपर वास्तव में वाक्यविन्यास को समझ नहीं पाता है। अधिकार के लिए अपील के लिए – doug65536

0

आप सही हैं, दोनों का मतलब संकलक के लिए बिल्कुल वही बात है। दोनों कथन (int *) प्रकार के चर का उत्पादन करेंगे।

जिसके लिए सही है: कीड़े का कर सकते हैं! यह आमतौर पर एक बहस विषय है। यदि आप किसी कंपनी या ओएसएस पर काम करते हैं, तो शायद परिभाषित कोडिंग शैली को स्थगित करना सबसे अच्छा है। यदि कोई नहीं है तो मैं आमतौर पर कोड बेस के इस हिस्से में जो भी शैली का उपयोग किया गया है, उससे मिलान करने वाली एलएनटी (कोई निशान नहीं छोड़ती) शैली जाती है।

यह तर्क दिया जा सकता है कि पाठक को समझना आसान है। उदाहरण के लिए int* ptr;*int जो अधिक स्पष्ट रूप से संचार हम एक (int *) प्रकार के बारे में बात कर रहे हैं ...

1

सी में के करीब डालता है, खाली स्थान के जहां यह अलग टोकन के लिए आवश्यक है सिवाय कोई फर्क नहीं पड़ता। आपके दोनों प्रकार सिंटैक्टिक रूप से सही हैं।

संस्करण 1 पॉइंटर ऑपरेटर को प्रकार के साथ जोड़ता है, जो पर्याप्त तार्किक है। मेरे लिए, यह पर्याप्त होगा अगर कारण नहीं था कि संस्करण 2 समझ में आता है।

संस्करण 2 सी घोषणाओं के तरीके के अनुरूप है। सी व्याकरण में, सूचक ऑपरेटर घोषणाकर्ता (यानी, नाम के साथ) में है, प्रकार नहीं। यह वही घोषणा करता है जब एक ही घोषणा में एकाधिक चर घोषित किया जाता है। यहां कई और गूढ़ मामले भी हैं जहां यह महत्वपूर्ण है।

इस प्रकार, मेरे लिए, संस्करण 2 सी के साथ और अधिक सुसंगत है लेकिन या तो संस्करण सफ़ाई है, और दोनों वेरिएंट पारंपरिक हैं।

4

दोनों का मतलब वही है जैसा दूसरों ने कहा है। हालांकि आपके लिए एक जाल इंतज़ार कर रहा है।

int* a, b; 

आपको लगता है कि हो सकता है कि इस int की ओर इशारा करने के लिए की घोषणा की: इस कोड पर विचार करें। नहीं, लेकिन अन्यथा। वास्तव में aint* है लेकिन bint है। यह कई सी * प्रकार के बजाय चर के बगल में डाल करने के लिए पसंद करते हैं प्रोग्रामर के लिए कारणों में से एक है। जब इस तरह लिखा:

int *a, b; 

आप कम क्या a और b हैं के रूप में गुमराह होने की संभावना है।

कहा करने के बाद वह सब, कई कोडन मानकों का कहना है कि आप प्रत्येक पंक्ति में, मैं, ई चर अधिक कोई नहीं से घोषणा करते हैं।

int* a; 
int b; 

यदि आप प्रति पंक्ति नियम के एक चर का पालन करते हैं तो निश्चित रूप से भ्रम के लिए कोई गुंजाइश नहीं है।

4
T *a; 

वरीय सी शैली रास्ता T के सूचक के रूप में घोषित करने के लिए सी के बारे में Kernighan & रिची की किताब में प्रयोग किया जाता

T* a; 

इस्तेमाल किया T करने के लिए एक घोषणा सूचक को प्राथमिकता दी C++ शैली तरीका है के रूप में है सी ++ के बारे में Stroustrup की पुस्तक में।

दोनों अंकन बराबर हैं।

+1

+1 ;-) –

12

कुछ और कोई नहीं उल्लेख किया है कि

int *ptr; 

भाषा व्याकरण के लिए और अधिक बारीकी से मेल खाती है है।

  • int *ptr; एक घोषणा, का होता है:
    • एक घोषणा-विनिर्देशकint, द्वारा
    • एक declarator, *ptr का पालन किया।

(यही कारण है कि वास्तव में पदों की संख्या को छोड़ देता है, लेकिन यह भर में मूल विचार हो जाता है।)

के बाद से घोषणा उपयोग इस प्रकार है, क्या इसका मतलब है कि *ptr प्रकार int की है। यह इस प्रकार से आता है कि ptrint* प्रकार का है।

यह तर्क हो सकता है कि इस बनाता है की तुलना में यह बेहतर

int* ptr; 

एक ही कारण है कि

x = y+z; 

की तुलना में बेहतर

x=y + z; 
बेशक आप लिख सकते हैं

के

है के लिए

int* ptr; 

और इसे पढ़ें ptrint* प्रकार का है "। और प्रोग्रामर के बहुत सारे ठीक वही करते हैं, और ठीक से मिलते हैं (यह सी ++ में पसंदीदा शैली बनता है)। कंपाइलर इस बात पर परवाह नहीं करता कि आप इसे किस तरह से करते हैं, और आपके कोड को पढ़ने वाले किसी भी व्यक्ति को इसे किसी भी तरह समझने में परेशानी नहीं होनी चाहिए।

लेकिन जो भी रिक्ति आप चुनते हैं, आपको यह समझने की क्या int *ptr; वास्तव में इसका मतलब है की जरूरत है, इसलिए जब आप देखते हैं

int *ptr, i; 
किसी और के कोड में

(जैसा कि आप अनिवार्य रूप से), तो आपको तुरंत समझ जाएंगे कि ptr है कि एक सूचक और i एक int है।

और अगर आप एक परियोजना पर अन्य प्रोग्रामर के साथ काम कर रहे हैं, आप का पालन करना चाहिए जो कुछ भी मौजूदा सम्मेलन कोडिंग मानकों में है, या अगर कोई एक, जिस तरह से कोड पहले से ही लिखा है नहीं है। मैं व्यक्तिगत रूप से int *ptr; से int* ptr; पसंद करता हूं, लेकिन दोनों शैलियों का मिश्रण उपयोग करके लगातार एक का उपयोग करने से कहीं भी बदतर है।

2

सी घोषणाएं अभिव्यक्ति के प्रकारों के आसपास आधारित हैं, वस्तुओं नहीं।

आप एक intpi नामित करने के लिए एक सूचक है, और आप पूर्णांक मान है कि यह की ओर इशारा उपयोग करना चाहते हैं, तो आप संकेतक भिन्नता है, के रूप में:

x = *pi; 
printf("%d", *pi); 
*pi = 1 + 2; 

आदिअभिव्यक्ति*pi के प्रकार int है: इसलिए, घोषणा के रूप में

int *pi; 

अब पढ़ना चाहिए मान लें कि आप char की ओर इशारा की एक सरणी था करते हैं; किसी भी चरित्र को पाने के लिए, आप सरणी में पहले सबस्क्रिप्ट की जरूरत है, तो परिणाम भिन्नता:

c = *pc[i]; 
if (*pc[j] == 'a') {...} 

आदि फिर, अभिव्यक्ति*pc[i]char है के प्रकार, इसलिए घोषणा पढ़ता

के रूप में
char *pc[N]; 

*pi और *pc[N] दोनों declarators रूप में जाना जाता है, और प्रकार निर्दिष्टकर्ता द्वारा दिए गए नहीं अतिरिक्त प्रकार की जानकारी को निर्दिष्ट कर रहे हैं। IOW, pc के सरणी-नेस और पॉइंटर-नेस को घोषणाकर्ता के हिस्से के रूप में निर्दिष्ट किया गया है, जबकि char-प्रकार प्रकार विनिर्देशक द्वारा दिया जाता है।

सवाल जिनमें से है शैली उचित है के रूप में ...

न तो एक है "सही" है, लेकिन मैं (और कई अन्य C प्रोग्रामर) के रूप में करने का विरोध किया T* pT *p लिखने के लिए पसंद करते हैं, यह बाद से भाषा व्याकरण को अधिक बारीकी से प्रतिबिंबित करता है (* घोषणाकर्ता का हिस्सा है) और यह एकाधिक वस्तुओं की घोषणा करते समय भ्रम से बचने में मदद करता है। मैंने कोT* a, b; लिखने वाले लोगों के बहुत से उदाहरण देखे हैं और b को पॉइंटर होने की उम्मीद है।

उस आलोचना की सामान्य प्रतिक्रिया "प्रति पंक्ति एक से अधिक आइटम घोषित न करें"। उस प्रतिक्रिया का मेरा जवाब है "अपने घोषणाकर्ताओं को सही ढंग से लिखें और आपको कोई समस्या नहीं होगी"।

कई सी ++ प्रोग्रामर, जो T* p शैली पसंद करते हैं के बीच में सोचा था की एक अलग स्कूल नहीं है, और मैं कुछ मामलों में जहां यह कोड अधिक पठनीय बना सकते हैं (सी ++ तक सीमित) देखते हैं कहना है।

हालांकि, कि केवल T करने के लिए सरल संकेत के लिए काम करता है: प्रतिमान तेजी से टूट जाती है जब आप काम करता है, आदि की ओर इशारा की सरणियों की ओर इशारा की सरणियों, या सरणियों की ओर इशारा, या कार्यों के लिए संकेत दिए गए, या संकेत के साथ काम शुरू मेरा मतलब है,

T* (*(*p)[N])(); // p is a pointer to an array of pointers to functions 
       // returning pointers to T. 

जैसे कुछ लिखना सिर्फ भ्रमित सोच को इंगित करता है।

संपादित

के पुन: प्रयास करें:

हालांकि, अगर आप वास्तव में वास्तव में बहुत लगता है कि आप T* p प्रतिमान का पालन करना होगा, तो आप हमेशा typedefs की एक श्रृंखला बना सकते हैं
typedef T* TPtr;       // pointer to T 
typedef TPtr TPtrFunc();     // function returning pointer to T 
typedef TPtrFunc* TPtrFuncPtr;    // pointer to function returning 
              // pointer to T 
typedef TPtrFuncPtr TPtrFuncPtrArray[N]; // N-element array of pointer to function 
              // returning pointer to T 

TPtrFuncPtrArray* p; 

भगवान के प्यार के लिए, ऐसा मत करो।

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