दिलचस्प पोस्ट
कॉलबैक को node.js का उपयोग करते हुए कॉल किए जाने तक फ़ंक्शन का इंतजार कैसे करें 'प्रिन्ट प्रिंट' विंडो% PATH% variable – ';' पर कैसे विभाजित है सीएमडी खोल में मैं .NET में स्ट्रिंग के * पहले उदाहरण * की जगह कैसे करूं? प्रोग्रामिंग को निर्धारित करने के लिए कि क्या कोई विशेष प्रक्रिया 32-बिट या 64-बिट है वीम संपादक से बाहर कैसे निकलते हैं? टीडी के अंदर एक डीआईवी एक बुरा विचार है? आप बैच फ़ाइलों में एक नई लाइन कैसे गूंज सकते हैं? MSI vs nuget संकुल: कौन सी लगातार डिलीवरी के लिए बेहतर है? आयात *** हल नहीं किया जा सकता कैसे सी # में JSON स्ट्रिंग बनाने के लिए मैं कैसे तय कर सकता हूं कि किस निष्पादन योग्य संकलन का मंच है? कैसे "पूरी तरह से" एक dict पर ओवरराइड? सबसे अच्छा सीएसएस फ्रेमवर्क क्या है और क्या वे प्रयास के लायक हैं? नोडजेएस: बेस 64-एन्कोडेड छवि डिस्क पर सहेज रहा है एक्सएमएल में अन्य कॉन्फ़िग फाइल्स की सेटिंग्स को शामिल करने के लिए app.config में शामिल हैं या कॉन्फ़िगर संदर्भ

क्या टाइपिंगफ़िक पॉइंटर के लिए एक अच्छा विचार है?

मैंने कुछ कोड के माध्यम से देखा और देखा कि सम्मेलन को पॉइंटर प्रकार की तरह बदलना था

SomeStruct* 

में

 typedef SomeStruct* pSomeStruct; 

क्या इसमें कोई योग्यता है?

वेब के समाधान से एकत्रित समाधान "क्या टाइपिंगफ़िक पॉइंटर के लिए एक अच्छा विचार है?"

यह तब उपयुक्त हो सकता है जब सूचक को "ब्लैक बॉक्स" के रूप में माना जा सकता है, अर्थात वह डेटा का एक टुकड़ा जिसका आंतरिक प्रतिनिधित्व कोड के लिए अप्रासंगिक होना चाहिए।

मूल रूप से, यदि आपका कोड सूचक को कभी भी डिफरेंस नहीं देगा, और आप इसे एपीआई फ़ंक्शंस (कभी-कभी संदर्भ के द्वारा) के चारों ओर से गुजारें, तो न केवल टाइप टाइप आपके कोड में * s की संख्या को कम करता है, बल्कि प्रोग्रामर को भी सुझाव देता है कि सूचक वास्तव में इसके साथ दखल नहीं होना चाहिए

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

मेरे अनुभव में नहीं ' * ' को छुपाने के लिए कोड को पढ़ना कठिन बना देता है।

एक बार जब मैं टाइपेडफेप के भीतर एक सूचक का उपयोग करता हूं, तो कार्य करने के लिए पॉइंटर्स से निपटना होता है:

 typedef void (*SigCatcher(int, void (*)(int)))(int); 

 typedef void (*SigCatcher)(int); SigCatcher old = signal(SIGINT, SIG_IGN); 

अन्यथा, मुझे मददगार से ज्यादा भ्रामक लगता है।


signal() -आउट घोषणा signal() फ़ंक्शन के संकेतक के लिए सही प्रकार है, संकेत पकड़ने वाला नहीं यह स्पष्ट किया जा सकता है (ऊपर सही SigCatcher प्रकार का उपयोग करके) लिखकर:

  typedef SigCatcher (*SignalFunction)(int, SigCatcher); 

या, signal() घोषित करने के लिए signal() फ़ंक्शन:

  extern SigCatcher signal(int, SigCatcher); 

यही है, SignalFunction फंक्शन एक फ़ंक्शन के लिए एक सूचक है, जो दो तर्क (एक int और एक SigCatcher ) लेता है और एक SigCatcher देता है। और signal() खुद एक फ़ंक्शन है जो दो तर्क (एक int और SigCatcher ) लेता है और एक SigCatcher लौटाता है।

इससे आपको कुछ त्रुटियों से बचने में मदद मिल सकती है। उदाहरण के लिए निम्नलिखित कोड में:

 int* pointer1, pointer2; 

पॉइंटर 2 इंट * नहीं है , यह सरल int है लेकिन typedefs के साथ यह होने वाला नहीं है:

 typedef int* pInt; pInt pointer1, pointer2; 

वे दोनों int * अब कर रहे हैं

यह (इतने सारे उत्तर की तरह) निर्भर करता है

सी में यह बहुत आम है क्योंकि आप छिपाने की कोशिश कर रहे हैं कि वस्तु एक सूचक है आप यह इंगित करने का प्रयास कर रहे हैं कि यह वह वस्तु है जो आपके सभी कार्यों में हेरफेर करती है (हम जानते हैं कि यह नीचे एक सूचक है, लेकिन यह उस ऑब्जेक्ट को दर्शाता है जिसे आप जोड़ रहे हैं)।

 MYDB db = MYDBcreateDB("Plop://djdjdjjdjd"); MYDBDoSomthingWithDB(db,5,6,7); CallLocalFuc(db); // if db is not a pointer things could be complicated. MYDBdestroyDB(db); 

MYDB के नीचे शायद कुछ ऑब्जेक्ट पर एक सूचक है।

सी ++ में यह अब जरूरी नहीं है।
मुख्य रूप से, क्योंकि हम संदर्भ के अनुसार चीजों को पार कर सकते हैं और विधियों को कक्षा घोषणापत्र में शामिल किया गया है।

 MyDB db("Plop://djdjdjjdjd"); db.DoSomthingWithDB(5,6,7); CallLocalFuc(db); // This time we can call be reference. db.destroyDB(); // Or let the destructor handle it. 

यह शैली की बात है आप विंडोज हेडर फाइल में इस प्रकार का कोड बहुत बार देख सकते हैं हालांकि वे सभी ऊपरी केस संस्करण को पसंद करते हैं, जो कि लोअर केस पी के साथ प्रीफ़िक्स करने के बजाय।

निजी तौर पर मैं टाइपिंगफेप के इस प्रयोग से बचने के लिए यह स्पष्ट है कि उपयोगकर्ता को स्पष्ट रूप से कहना है कि उन्हें पीएफू की तुलना में फू * करना है। एसटीएल को पढ़ने योग्य बनाने के लिए टाइपडफे का इन दिनों सबसे उपयुक्त है 🙂

 typedef stl::map<stl::wstring,CAdapt<CComPtr<IFoo>> NameToFooMap; 

टाइप करने के लिए कोड को अधिक पठनीय बनाने के लिए प्रयोग किया जाता है, लेकिन टाइमर के रूप में पॉइंटर बनाने से भ्रम बढ़ेगा। टाइफाइफ पॉइंटर्स से बचने के लिए बेहतर

यदि आप ऐसा करते हैं, तो आप const pSomeStruct के एसटीएल कंटेनरों को बनाने में असमर्थ होंगे क्योंकि संकलक पढ़ता है:

 list<const pSomeStruct> structs; 

जैसा

 list<SomeStruct * const> structs; 

जो एक कानूनी एसटीएल कंटेनर नहीं है क्योंकि तत्व असाइन नहीं हैं।

यह प्रश्न देखें

Win32 API यह लगभग हर संरचना के साथ करता है (यदि सभी नहीं)

 POINT => *LPPOINT WNDCLASSEX => *LPWNDCLASSEX RECT => *LPRECT PRINT_INFO_2 => *LPPRINT_INFO_2 

यह ठीक है कि यह कैसे सुसंगत है, लेकिन मेरी राय में यह कोई सुन्दरता नहीं जोड़ता है

ब्याज की भाषा संभालने वाली चर्चा सी है सी। के लिए सीमेंट्स को माना नहीं गया है।

एक untagged संरचना के लिए एक सूचक typedef का उपयोग करना

सवाल के रूप में परिभाषित किया गया संरचना का आकार जो सूचक के रूप में परिभाषित किया गया है (संरचना) पॉइंटर के लिए typedef का उपयोग करने पर एक रोचक ओर-प्रकाश उठाता है

टैग रहित ठोस (अपारदर्शी) संरचना प्रकार की परिभाषा पर विचार करें:

 typedef struct { int field1; double field2; } *Information; 

सदस्यों का विवरण इस चर्चा के लिए पूरी तरह से स्पर्शरेखा है; सभी मामलों यह है कि यह typedef struct tag *tag; जैसी एक अपारदर्शी प्रकार नहीं है typedef struct tag *tag; (और आप बिना किसी typedef किए गए टाइप अप के जरिए ऐसे अपारदर्शी प्रकार को परिभाषित नहीं कर सकते हैं)।

उठाया सवाल है कि 'आप उस संरचना का आकार कैसे पा सकते हैं'?

संक्षिप्त उत्तर 'केवल एक प्रकार के चर के माध्यम से' है sizeof(struct tag) साथ उपयोग करने के लिए कोई टैग नहीं है उदाहरण के लिए, आप sizeof(*Information) उपयोगी नहीं लिख सकते हैं, और sizeof(Information *) सूचक सूचक प्रकार का आकार है, संरचना प्रकार का आकार नहीं।

वास्तव में, यदि आप ऐसी संरचना को आवंटित करना चाहते हैं, तो आप डायनामिक आवंटन (या गतिशील आवंटन की नकल रखने वाली तकनीकों को छोड़कर) को छोड़कर एक नहीं बना सकते हैं। संरचना प्रकार के पॉइंटर्स को स्थानीय वैरिएबल बनाने का कोई रास्ता नहीं है, जिनके पॉइंटर्स को Information कहा जाता है, न ही संरचना प्रकार की एक फ़ाइल स्कोप (वैश्विक या static ) वैरिएबल बनाने का एक तरीका है, और न ही ऐसी संरचना को एम्बेड करने का एक तरीका है (एक ऐसी संरचना के लिए एक सूचक के विपरीत) एक और संरचना या संघ के प्रकार में।

आप कर सकते हैं – लिखना चाहिए:

 Information info = malloc(sizeof(*info)); 

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

क्या यह हानिकारक है?

यह आपके लक्ष्यों पर निर्भर करता है

यह एक अपारदर्शी प्रकार नहीं है – संरचना का ब्योरा परिभाषित किया जाना चाहिए, जब सूचक प्रकार typedef डी होता है

यह एक ऐसा प्रकार है जिसका उपयोग केवल गतिशील स्मृति आवंटन के साथ किया जा सकता है।

यह एक प्रकार है जो अज्ञात है। संरचना प्रकार के सूचक का नाम है, लेकिन संरचना का प्रकार स्वयं नहीं है।

यदि आप गतिशील आवंटन को लागू करना चाहते हैं, तो ऐसा करने का एक तरीका लगता है।

पूरे पर, हालांकि, ज्ञान की तुलना में भ्रम और परेशान होने की संभावना अधिक है।

सारांश

सामान्य तौर पर, एक टैग रहित स्टैक्चर प्रकार के लिए पॉइंटर को परिभाषित करने के लिए typedef का उपयोग करने के लिए एक खराब विचार है।

मेरा जवाब एक स्पष्ट "नहीं" है

क्यूं कर?

ठीक है, सबसे पहले, आप केवल एक एकल वर्ण का एक्सचेंज कर सकते हैं * यह शून्य लाभ है यह अकेले आपको इसे करने से रोकना चाहिए क्योंकि यह हमेशा अतिरिक्त सामान करने के लिए बुरा होता है जो व्यर्थ है।

दूसरा, और यही महत्वपूर्ण कारण है, * मतलब यह है कि छिपाना अच्छा नहीं है अगर मैं इस तरह से किसी समारोह में कुछ पास करता हूँ

 void foo(SomeType bar); void baz() { SomeType myBar = getSomeType(); foo(myBar); } 

मुझे यह उम्मीद नहीं है कि इसे foo() से गुजरने के लिए myBar को बदलना होगा। सब के बाद, मैं मूल्य से गुजर रहा हूँ, तो foo() केवल कभी ही myBar की एक प्रति देखता है? जब कुछ प्रकार के संकेतक किसी प्रकार का सूचक होने का मतलब नहीं है!

यह सी पॉइंटर्स और सी ++ स्मार्ट पॉइंटर्स दोनों पर लागू होता है: यदि आप इस तथ्य को छिपाते हैं कि वे आपके उपयोगकर्ताओं के लिए संकेत हैं, तो आप भ्रम पैदा कर देंगे जो पूरी तरह अनावश्यक है। तो, कृपया, अपने पॉइंटर्स को उपनाम न दें

(मेरा मानना ​​है कि टाइप टाइप किए गए पॉइंटर प्रकार की आदत सिर्फ एक प्रोग्रामर के रूप में कितने सितारों को छुपाने का एक गुमराह करने का प्रयास है http://wiki.c2.com/?ThreeStarProgrammer ।)

कुछ समय पहले, मैंने इस सवाल का उत्तर "नहीं" दिया होगा। अब, स्मार्ट पॉइंटर्स के उदय के साथ, पॉइंटर्स हमेशा स्टार '*' से परिभाषित नहीं होते हैं इसलिए एक प्रकार के बारे में कुछ भी स्पष्ट नहीं है, एक सूचक है या नहीं

तो अब मैं कह सकता हूं: यह टाइप टाइप एप सूचकों के लिए ठीक है, जब तक कि यह बहुत स्पष्ट किया जाता है कि यह एक "सूचक प्रकार" है। इसका मतलब है कि आपको इसके लिए एक उपसर्ग / प्रत्यय का उपयोग करना होगा नहीं, "p" एक पर्याप्त उपसर्ग नहीं है, उदाहरण के लिए। मुझे शायद "पीटीआर" के साथ जाना होगा

टाइपफीफ के साथ उद्देश्य कार्यान्वयन के विवरण छिपाने के लिए है, लेकिन पॉइंटर गुण typedef- बहुत अधिक छुपाता है और कोड पढ़ने / समझने के लिए कठिन बना देता है तो कृपया ऐसा मत करो


यदि आप कार्यान्वयन विवरण छिपाना चाहते हैं (जो अक्सर करने के लिए एक अच्छी बात है), तो सूचक हिस्से को छिपाएं नहीं। उदाहरण के लिए मानक FILE इंटरफ़ेस के लिए प्रोटोटाइप पर जाएं:

 FILE *fopen(const char *filename, const char *mode); char *fgets(char *s, int size, FILE *stream); 

यहाँ Fopen कुछ संरचना FILE (जो आपको कार्यान्वयन विवरण नहीं पता है) के लिए एक सूचक देता है। हो सकता है कि FILE ऐसा कोई अच्छा उदाहरण नहीं है क्योंकि इस मामले में यह कुछ पीएफआईफ़ाइल प्रकार के साथ काम कर सकता था, जिसने तथ्य को छुपा दिया था कि यह एक संकेतक है।

 pFILE fopen(const char *filename, const char *mode); char *fgets(char *s, int size, pFILE stream); 

हालांकि, यह केवल इसलिए काम करेगा क्योंकि आप सीधे उस सामग्री के साथ कभी गड़बड़ नहीं करते हैं जो सीधे इशारा है। जिस समय आपने कुछ संकेतक टाइप किए थे, जो कुछ जगहों को संशोधित करते हैं, मेरे अनुभव में यह पढ़ना बहुत मुश्किल हो जाता है।