एक आवश्यकता में मुझे "जेनेरिक" पॉइंटर के मूल्य को संग्रहीत करने की आवश्यकता को देखते हुए और पॉइंट-इन मेमोरी में कोई दिलचस्पी नहीं है, मुझे इसे की तुलना में intptr_t
के रूप में स्टोर करने के लिए अधिक अर्थपूर्ण रूप से सही लगता है। सवाल यह है कि uintptr_t
बेहतर अनुकूल है या नहीं, और जब किसी को आम तौर पर दूसरे पर प्राथमिकता दी जाती है?intptr_t पर uintptr_t को कब पसंद किया जाता है?
उत्तर
यह ज्यादातर स्टाइलिस्ट तर्क है (एक अनुकूलन संकलक शायद समान, या बहुत समान कोड उत्पन्न करेगा)। हालांकि, सूचक तुलना एक मुश्किल मुद्दा हो सकता है।
शुद्ध रूप से मानक सी पॉइंटर तुलना की तुलना में याद रखें केवल समान कुल डेटा के पॉइंटर्स के लिए लगभग सार्थक है। आपको शायद malloc
से दो परिणामों की तुलना करने की अनुमति नहीं है, उदा। पॉइंटर्स की एक क्रमबद्ध सरणी रखने के लिए।
मैं उन्हें void*
, या अन्य uintptr_t
के रूप में रखूंगा। हस्ताक्षर किए गए intptr_t
में नकारात्मक और सकारात्मक संख्याओं को सीग्रेग करने की असुविधा होती है, और जहां वे महत्वपूर्ण एप्लिकेशन पॉइंटर्स से आ रहे हैं, शायद इसका स्वागत नहीं है।
सूचना है कि एक void*
dereferenced नहीं किया जा सकता: एक uintptr_t
के रूप में, आप यह कुछ डेटा पते से बताया के साथ उपयोगी करने के लिए कास्ट करने के लिए है; हालांकि void*
पॉइंटर्स memset
पीएस जैसे दिनचर्या को पारित किया जा सकता है। मैं एक साधारण वर्चुअल एड्रेस स्पेस के साथ एक सामान्य प्रोसेसर (उदा। कुछ x86, पावरपीसी, एआरएम, ...) मान रहा हूं। आप मिल सकता है विदेशी प्रोसेसर -कुछ DSPs बहुत महत्वपूर्ण अंतर के साथ perhaps- (और शायद जिस पर intptr_t
हमेशा सार्थक है, जो 1990 के दशक Cray Y-MP सुपर कंप्यूटर sizeof(long*) != sizeof(char*)
पर याद; उस समय C99 मौजूद नहीं था, और मुझे यकीन है कि नहीं कर रहा हूँ अपने <stdint.h>
सकता है ऐसी मशीनों पर सार्थक हो)
मैंने यूनिकोस चलाने वाले क्रे T90 पर काम किया।'लंबा *' और 'char *' एक ही आकार (64 बिट्स) थे, लेकिन 'char *' ने बाइट ऑफ़सेट स्टोर करने के लिए उच्च-आदेश 3 बिट्स का उपयोग किया, क्योंकि मशीन पते 64-बिट शब्दों की ओर इशारा करते थे (यह सब प्रबंधित था सॉफ्टवेयर में)। क्या पुराना वाई-एमपी अलग था? –
मैं विवरण भूल गया, लेकिन कास्टिंग (मैं किस दिशा में भूल गया) '(char *)' से/('* * 'से एक मुद्दा था ... –
टी 0 9 पर, पूर्णांक और सूचक रूपांतरणों ने बस बिट्स की प्रतिलिपि बनाई। यदि 'char *' पॉइंटर में गैर-शून्य ऑफसेट होता है, तो इसे 'लम्बा *' में परिवर्तित करने से एक अमान्य सूचक मिलेगा, क्योंकि 3 उच्च-आदेश बिट्स पते का हिस्सा होंगे (और वास्तविक पता स्थान लगभग नहीं था वह बड़ा)। मैंने एक बार कुछ कोड देखा जो दो पॉइंटर्स के बीच अंतर को पहले पूर्णांक में परिवर्तित करके गणना करता था; मैंने इंगित किया कि प्रत्यक्ष सूचक घटाव सरल है और वास्तव में काम करने का गुण है। –
यह बहुत अजीब लगता है, क्योंकि इसे केस्टों की आवश्यकता होगी। सी में void *
का बड़ा लाभ है कि यह बिना किसी बगैर अन्य ऑब्जेक्ट पॉइंटर प्रकारों में/से परिवर्तित होता है, जो कि रास्ता साफ है।
कहा गया है कि uintptr_t
यह समझ सकता है कि क्या आप पॉइंटर के बिट्स को चीजें करना चाहते हैं, जो आप एक हस्ताक्षरित पूर्णांक (उदाहरण के लिए, दाईं ओर स्थानांतरित करने के साथ) के रूप में समझदारी से नहीं कर सकते हैं।
_ "यह बहुत अजीब लगता है, क्योंकि इसे casts की आवश्यकता होगी" _ - ठीक है, हाँ। मैं नहीं चाहता कि इस स्ट्रक्चर के क्लाइंट कभी भी सोचें कि _pointee_ मान किसी भी ब्याज का है, और फ़ील्ड को 'intptr_t' या' uintptr_t' बनाकर मैं यह स्पष्ट करना चाहता हूं कि यह _pointer_ value है जो दिलचस्प है । कृपया मुझे बताएं कि क्या मैं गलत पेड़ को तर्क में डाल रहा हूं :-) –
@ जोहान गेलल निश्चित रूप से निश्चित होना मुश्किल है। लेकिन चूंकि 'शून्य *' का पूरा बिंदु यह है कि इसे संदर्भित नहीं किया जा सकता है क्योंकि पॉइंट के बारे में कोई जानकारी नहीं है, मैं कहूंगा कि यह वही है जो पहले से ही संचार करता है। – unwind
आपको [x86_64 कैनोलिक पतों पर हस्ताक्षरित एक्सटेंशन] प्राप्त करने के लिए 'intptr_t' का उपयोग करने की आवश्यकता हो सकती है (http://stackoverflow.com/q/16198700/995714) –
यदि आप अंकगणितीय रूप से मान को जोड़ना चाहते हैं (उदा।, इसे एन्क्रिप्ट करने के लिए), तो आपके पास एक हस्ताक्षरित प्रकार (जहां अंकगणित ओवरफ्लो अपरिभाषित व्यवहार देता है) के साथ एक हस्ताक्षरित प्रकार (जहां अंकगणित लपेटें) के साथ अधिक लचीलापन है।
- 1. एफ # बनाम आयरनपीथन: दूसरे को कब पसंद किया जाता है?
- 2. पॉइंटर्स के कार्यों के लिए uintptr_t/intptr_t के समतुल्य?
- 3. `row.names`` rownames` पर क्यों पसंद किया जाता है?
- 4. tinyalSA libasound पर क्यों पसंद किया जाता है?
- 5. एक वेक्टर कॉपी कब किया जाता है, एक संदर्भ कब पास किया जाता है?
- 6. क्यों बिल्कुल पसंद किया जाता है MaxLayoutWidth की आवश्यकता है?
- 7. Angular2 ngAfterViewInit कब कॉल किया जाता है?
- 8. स्थानीय शब्दकोश कब सेट किया जाता है?
- 9. परम जीन कब एकत्र किया जाता है?
- 10. एक रैल्यू मूल्यांकन कब किया जाता है?
- 11. कब किया जाता है ReceiveMemoryWarning वास्तव में
- 12. LINQ (ऑब्जेक्ट्स) पर कब उपयोग किया जाता है?
- 13. नोड.जेएस में, ढेर पर डेटा कब संग्रहीत किया जाता है?
- 14. स्ट्रिंगियो का उपयोग कब किया जाता है?
- 15. .pyc फ़ाइलों को ताज़ा कब किया जाता है?
- 16. स्थिर चर को सी # में प्रारंभ कब किया जाता है?
- 17. ताना शाब्दिक वाक्यविन्यास को श्रोताओं के कन्स्ट्रक्टर पर क्यों पसंद किया जाता है?
- 18. @JsonProperty प्रॉपर्टी का उपयोग कब किया जाता है और इसके लिए क्या उपयोग किया जाता है?
- 19. क्या uintptr_t और size_t समान हैं?
- 20. कोणीय 4 में रेंडरर 2 क्या है? jquery पर इसे क्यों पसंद किया जाता है?
- 21. प्रत्येक सॉर्टिंग एल्गोरिदम का उपयोग कब किया जाता है?
- 22. जेएमएस AUTO_ACKNOWLEDGE कब इसे स्वीकार किया जाता है?
- 23. स्ट्रीम के प्रमुख का मूल्यांकन कब किया जाता है?
- 24. .NET में पी/Invoke पर COM इंटरऑप क्यों पसंद किया जाता है?
- 25. PyEval_InitThreads कब कहा जाता है?
- 26. सत्रस्टॉरेज वास्तव में कब साफ़ किया जाता है?
- 27. एक वादा का शरीर कब निष्पादित किया जाता है?
- 28. विम में विज़ुअल मोड कब उपयोग किया जाता है?
- 29. जब परीक्षण किया जाता है - क्या मुझे "कब" चाहिए?
- 30. Grails संस्करणों का समर्थन कब तक किया जाता है?
उम्म .. क्या यह शून्य नहीं है? – mjs
मैं नहीं चाहता कि इस संरचना के क्लाइंट कभी भी सोचें कि _pointee_ मान किसी भी ब्याज का है, और फ़ील्ड को 'intptr_t' या' uintptr_t' बनाकर मैं यह स्पष्ट करने की आशा करता हूं कि यह _pointer_ value है दिलचस्प। कृपया मुझे बताएं कि क्या मैं गलत पेड़ को तर्क में डाल रहा हूं :-) –
यह आपकी व्याख्या है: अन्य शायद यह भी नहीं जानते कि 'intptr_t' क्या है। मैं केवल 'शून्य *' और एक * टिप्पणी * का उपयोग करता हूं, यह इंगित करने के लिए कि आप केवल स्मृति पते की परवाह करते हैं। कुछ ऐसा: 'शून्य * पता;/* हम सिर्फ स्मृति पते */'के बारे में परवाह करते हैं। – edmz