सरल जवाब है, यह मानते हुए कि अनियमितता और विभिन्न प्लेटफार्मों के बीच प्रारूप में बदलाव से परहेज नहीं करते, मानक %p
अंकन है।
C99 मानक (आईएसओ/आईईसी 9899: 1999) का कहना है §7.19.6.1 में ¶8:
p
तर्क void
के लिए सूचक होगा। पॉइंटर का मान कार्यान्वयन-परिभाषित तरीके से प्रिंटिंग वर्णों के अनुक्रम में परिवर्तित किया गया है।
(सी 11 में - आईएसओ/आईईसी 9899: 2011 - जानकारी §7.21.6.1 ¶8 में है।)
कुछ प्लेटफार्मों पर, कि एक प्रमुख 0x
और दूसरों पर ऐसा नहीं होगा शामिल होंगे , और पत्र निचले मामले या ऊपरी मामले में हो सकते हैं, और सी मानक यह भी परिभाषित नहीं करता है कि यह हेक्साडेसिमल आउटपुट होगा हालांकि मुझे पता नहीं है कि यह कोई कार्यान्वयन नहीं है।
यह बहस करने के लिए कुछ हद तक खुला है कि आपको पॉइंटर्स को (void *)
कलाकार के साथ स्पष्ट रूप से रूपांतरित करना चाहिए या नहीं।यह स्पष्ट है, जो आमतौर पर अच्छा होता है (इसलिए मैं यही करता हूं), और मानक कहता है 'तर्क void
' के लिए एक सूचक होगा। अधिकांश मशीनों पर, आप एक स्पष्ट कलाकार को छोड़कर दूर हो जाएंगे। हालांकि, यह किसी मशीन पर महत्वपूर्ण होगा जहां दिए गए मेमोरी लोकेशन के लिए char *
पता का थोड़ा सा प्रतिनिधित्व उसी स्मृति स्थान के लिए 'और कुछ पॉइंटर' पता से अलग है। बाइट-एड्रेस, मशीन के बजाए यह एक शब्द-संबोधित होगा। इस तरह की मशीनें इन दिनों आम नहीं हैं (शायद उपलब्ध नहीं हैं), लेकिन विश्वविद्यालय के बाद मैंने पहली मशीन पर काम किया था (आईसीएल पेर्क)।
आप %p
के कार्यान्वयन से परिभाषित व्यवहार से खुश नहीं हैं, तो C99 <inttypes.h>
और uintptr_t
बजाय का उपयोग करें:
printf("0x%" PRIXPTR "\n", (uintptr_t)your_pointer);
यह आप फ़ाइन-ट्यून करने के लिए अपने आप को सूट करने के लिए प्रतिनिधित्व अनुमति देता है। मैंने ऊपरी मामले में हेक्स अंकों को चुना है ताकि संख्या समान रूप से एक ही ऊंचाई हो और 0xA1B2CDEF
की शुरुआत में विशेषता डुबकी इस प्रकार दिखाई दे, 0xa1b2cdef
जो संख्या के साथ ऊपर और नीचे डुबकी नहीं है। आपकी पसंद हालांकि, बहुत व्यापक सीमाओं के भीतर। (uintptr_t)
कास्ट जीसीसी द्वारा अनजाने में अनुशंसित किया जाता है जब यह संकलन समय पर प्रारूप स्ट्रिंग को पढ़ सकता है। मुझे लगता है कि कलाकारों का अनुरोध करना सही है, हालांकि मुझे यकीन है कि कुछ ऐसे हैं जो चेतावनी को अनदेखा करते हैं और अधिकांश समय से दूर हो जाते हैं।
Kerrek टिप्पणी में पूछते हैं:
मैं थोड़ा मानक प्रचार और variadic तर्क के बारे में उलझन में हूँ। क्या सभी पॉइंटर्स मानक * को शून्य से प्रचारित करते हैं? अन्यथा, अगर int*
कहें, दो बाइट्स, और void*
4 बाइट थे, तो यह तर्क से चार बाइट पढ़ने के लिए स्पष्ट रूप से एक त्रुटि होगी, न?
मैं भ्रम के तहत किया गया है कि सी मानक कहना है कि सभी वस्तु संकेत दिए गए, एक ही आकार होना चाहिए, ताकि void *
और int *
विभिन्न आकारों नहीं हो सकता। हालांकि, मुझे लगता है कि C99 मानक के प्रासंगिक अनुभाग है नहीं तो जोरदार (हालांकि मैं एक कार्यान्वयन जहां मैं क्या सुझाव दिया सच है की नहीं जानता है वास्तव में गलत) है:
§6.2.5 प्रकार
¶26 शून्य के लिए एक सूचक के पास एक चरित्र प्रकार के सूचक के रूप में समान प्रतिनिधित्व और संरेखण आवश्यकताएं होंगी। 39) इसी तरह, संगत प्रकार के योग्य या अयोग्य संस्करणों के पॉइंटर्स के समान प्रतिनिधित्व और संरेखण आवश्यकताएं होंगी। संरचना प्रकारों के सभी पॉइंटर्स में एक दूसरे के समान प्रतिनिधित्व और संरेखण आवश्यकताएं होंगी। यूनियन प्रकारों के सभी पॉइंटर्स के पास एक-दूसरे के समान प्रतिनिधित्व और संरेखण आवश्यकताएं होंगी। अन्य प्रकार के पॉइंटर्स को समान प्रतिनिधित्व या संरेखण आवश्यकताओं की आवश्यकता नहीं होती है।
39) समान प्रतिनिधित्व और संरेखण आवश्यकताओं का मतलब है कि कार्यों के तर्क के रूप में, कार्यों से मूल्यों को वापस करने, और संघों के सदस्यों के रूप में अंतरणशीलता को इंगित करने के लिए।
(सी 11 अनुभाग §6.2.5, ¶28, और फुटनोट 48 में बिल्कुल वही कहता है।)
तो, सभी पॉइंटर्स संरचनाओं को एक दूसरे के समान आकार होना चाहिए, और उसी संरेखण आवश्यकताओं को साझा करना होगा, भले ही पॉइंटर्स बिंदुओं की संरचनाओं में अलग-अलग संरेखण आवश्यकता हो। इसी तरह संघों के लिए। कैरेक्टर पॉइंटर्स और शून्य पॉइंटर्स के पास समान आकार और संरेखण आवश्यकताएं होनी चाहिए। int
(unsigned int
और signed int
पर भिन्नता के लिए पॉइंटर्स) एक दूसरे के समान आकार और संरेखण आवश्यकताएं होनी चाहिए; इसी प्रकार अन्य प्रकार के लिए। लेकिन सी मानक औपचारिक रूप से नहीं कहता है कि sizeof(int *) == sizeof(void *)
। ओह ठीक है, आपको अपनी धारणाओं का निरीक्षण करने के लिए अच्छा है।
सी मानक निश्चित रूप से फ़ंक्शन पॉइंटर्स को ऑब्जेक्ट पॉइंटर्स के समान आकार की आवश्यकता नहीं है। यह आवश्यक था कि डॉस-जैसी प्रणालियों पर विभिन्न मेमोरी मॉडल को तोड़ना न पड़े। वहां आपके पास 16-बिट डेटा पॉइंटर्स हो सकते हैं लेकिन 32-बिट फ़ंक्शन पॉइंटर्स, या इसके विपरीत। यही कारण है कि सी मानक यह जरूरी नहीं है कि फ़ंक्शन पॉइंटर्स को ऑब्जेक्ट पॉइंटर्स में परिवर्तित किया जा सके और इसके विपरीत।
सौभाग्य से (इसे POSIX लक्ष्यीकरण प्रोग्रामर के लिए), POSIX उल्लंघन में कदम और जनादेश है कि समारोह संकेत और डेटा संकेत दिए गए एक ही आकार के होते हैं:
§2.12.3 Pointer Types
सभी समारोह सूचक प्रकार टाइप पॉइंटर को रद्द करने के समान ही प्रतिनिधित्व होगा। फ़ंक्शन पॉइंटर का रूपांतरण void *
पर रूपांतरण प्रस्तुत नहीं करेगा। इस तरह के रूपांतरण से उत्पन्न void *
मूल्य को जानकारी के नुकसान के बिना, एक स्पष्ट कलाकार का उपयोग करके मूल फ़ंक्शन पॉइंटर प्रकार में वापस परिवर्तित किया जा सकता है।
नोट: आईएसओ सी मानक की आवश्यकता नहीं है, लेकिन यह POSIX अनुरूपता के लिए आवश्यक है।
इसलिए, यह है कि void *
को स्पष्ट डाले कोड में अधिकतम विश्वसनीयता के लिए दृढ़ता से सलाह दी जाती हैं प्रतीत होता है जब इस तरह के printf()
के रूप में एक variadic कार्य करने के लिए एक सूचक गुजर। POSIX सिस्टम पर, प्रिंटिंग के लिए एक शून्य सूचक को फ़ंक्शन पॉइंटर डालना सुरक्षित है। अन्य प्रणालियों पर, ऐसा करने के लिए जरूरी नहीं है, और न ही किसी भी कलाकार के बिना void *
के अलावा पॉइंटर्स को पास करना सुरक्षित है।
मैं मानक प्रचार और विविध तर्कों के बारे में थोड़ा उलझन में हूं। क्या सभी पॉइंटर्स को 'शून्य *' के लिए मानक-प्रचारित किया जाता है? अन्यथा, यदि 'int *' कहें, तो दो बाइट्स, और 'शून्य * '4 बाइट थे, तो यह तर्क से चार बाइट पढ़ने के लिए स्पष्ट रूप से एक त्रुटि होगी, न? –
ध्यान दें कि POSIX (POSIX 2013) के लिए एक अद्यतन ने खंड 2.12.3 को हटा दिया है, जो अधिकांश आवश्यकताओं को ['dlsym()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlsym) में ले जा रहा है .html) इसके बजाए कार्य करें। एक दिन मैं परिवर्तन लिखूंगा ... लेकिन 'एक दिन' 'आज' नहीं है। –
क्या यह उत्तर पॉइंटर्स पर फ़ंक्शंस पर भी लागू होता है? क्या उन्हें 'शून्य *' में परिवर्तित किया जा सकता है? हम्म मैं आपकी टिप्पणी देखता हूं [यहां] (http://stackoverflow.com/questions/9053658/correct-format-specifier-to-print-pointer-address#comment11360489_9053677)। चूंकि केवल एक-वाट रूपांतरण की आवश्यकता है ('शून्य *' पर फ़ंक्शन पॉइंटर), तो यह तब काम करता है? – chux