2009-12-04 12 views
9

मैं इस सी परियोजना के बीच में हूं कि मैं बहुत मेमोरी कुशल बनाना चाहता हूं। कई मामलों में, मैं बिट्स को पकड़ने के लिए लिखे गए गतिशील सरणी संरचना के शून्य * का उपयोग कर रहा हूं। मैं सभी 64 (इस मामले में) बिट्स का उपयोग करना चाहता हूं।एक सी सूचक पर बिट बदलाव?

मुझे जल्द ही एहसास हुआ कि आप वास्तव में किसी सूचक पर कुछ भी छेड़छाड़ नहीं कर सकते हैं। तो मेरी समाधान था निम्नलिखित:

void *p; 
((unsigned long)p) << 4; 
((unsigned long)p) & 3; 

यह काम किया हो जाता है, लेकिन केवल क्योंकि पर अपने कंप्यूटर, देशांतर और संकेत दिए गए आकार में बराबर हैं। क्या यह सभी (या अधिकतर) आर्किटेक्चर में होगा?

और मेरा असली प्रश्न: क्या पॉइंटर पर थोड़ा हेरफेर करने का कोई और सही तरीका है? मैंने सोचा था कि इस दृष्टिकोण को कुछ हद तक (पैकिंग एक शून्य * में बिट्स), लेकिन मैं गलत हो सकता है ...

+0

मैं stdint.h – sambowry

+2

uint64_t से uint64_t का उपयोग करता हूं यदि आपके प्लेटफ़ॉर्म में 64-बिट पॉइंटर्स से कम है तो बहुत बड़ा होगा। उसी शीर्षलेख से intptr_t और uintptr_t का उपयोग करें। – tgamblin

+0

@sambowry - ऐसा लगता है कि आपको थोड़ा सा 'stdint.h' के माध्यम से जाने की आवश्यकता है। –

उत्तर

15

अपने संकलक इसका समर्थन करता है, C99 के <stdint.h> हैडर intptr_t और uintptr_t प्रकार है कि ऐसा करना चाहिए प्रदान करता है सी में आम था अपने सिस्टम पर पॉइंटर रखने के लिए काफी बड़ा हो, लेकिन पूर्णांक हैं, इसलिए आप थोड़ा हेरफेर कर सकते हैं। यह वास्तव में उससे अधिक पोर्टेबल नहीं हो सकता है, अगर आप यही चाहते हैं।

+0

वैसे भी, आपको शायद पूरी तरह पोर्टेबल समाधान की आवश्यकता नहीं है। पॉइंटर्स के निचले बिट्स में झंडे को स्टोर करने का प्रयास करने वाला कोई भी बिट-ट्विडलिंग आवश्यक रूप से प्लेटफॉर्म-विशिष्ट है, क्योंकि यह ऑब्जेक्ट संरेखण के बारे में धारणाओं पर निर्भर करता है। तो प्रश्नकर्ता को किसी भी नए मंच पर पोर्टिंग करते समय शायद कुछ काम (या कम से कम शोध) करना होगा। –

+0

@ स्टेव - अगर वह एक पॉइंटर पर थोड़ा सा झुकाव कर रहा है, तो मुझे उम्मीद है कि वह बाद में इसे अस्वीकार नहीं कर रहा है। यह सिर्फ एक पोर्टेबिलिटी दुःस्वप्न की तरह लगता है।अगर वह ऐसा कर रहा था, तो मुझे संदेह है कि वह अपने परिचालन की पोर्टेबिलिटी के बारे में पूछेगा। –

+1

क्या आप 'intptr_t' और' uintptr_t' के बीच अंतर को समझा सकते हैं? – DRz

2

पॉइंटर और बिटफील्ड का एक संघ घोषित करें।

+1

आपको अभी भी यह जानने की आवश्यकता होगी कि बिटकफील्ड को कितना बड़ा बनाना है, इसलिए आपके अन्य फ़ील्ड को intptr_t होना चाहिए। मुझे यकीन नहीं है कि यह या कास्टिंग अधिक पठनीय होगा या नहीं। – tgamblin

+1

आप बिटकफील्ड को उतना बड़ा बनाते हैं जितना कि इसे आपके अन्य उद्देश्यों के लिए होना चाहिए। संकलक तब सुनिश्चित करेगा कि संरचना काफी बड़ी है ताकि पॉइंटर और बिटफील्ड से बड़ा बड़ा हो। यह स्थिति वास्तव में यूनियनों के लिए क्या है। –

7

आप संकेत पर हेरफेर के इस तरह करने की जरूरत है, तो आप उन्हें intptr_t और uintptr_t, stdint.h में पाया जा सकता जो दोनों के पर कास्ट कर सकते। इन्हें पॉइंटर धारण करने के लिए पर्याप्त बिट्स के साथ प्लेटफॉर्म-विशिष्ट पूर्णांक प्रकार के रूप में परिभाषित करने की गारंटी दी जाती है।

वहां ptrdiff_t भी है, यदि आपको दो पॉइंटर्स के बीच अंतर रखने की आवश्यकता है।

+4

और यदि आपका कंपाइलर stdint.h (* खांसी * माइक्रोसॉफ्ट * खांसी *) का समर्थन नहीं करता है, तो निम्न SO उत्तर और टिप्पणियों के कई लिंक हैं जिनका आप उपयोग करने का निर्णय ले सकते हैं: http://stackoverflow.com/questions/126279/ c99-stdint-h-header-and-ms-visual-studio/126285 # 126285 –

3

मुझे लगता है कि आप गलत समस्या को हल करने का प्रयास कर रहे हैं। वास्तविक समस्या यहीं है:

मैं एक गतिशील सरणी संरचना मैं पकड़ बिट्स करने के लिए लिखा था का उपयोग कर रहा शून्य * रों।

बिट्स रखने के लिए शून्य पॉइंटर्स का उपयोग न करें। पॉइंटर्स को पकड़ने के लिए शून्य पॉइंटर्स का उपयोग करें। बिट्स को पकड़ने के लिए हस्ताक्षरित पूर्णांक का उपयोग करें।

+0

मुझे यकीन नहीं है कि मैं सहमत हूं कि यह एक संपूर्ण डेटा संरचना और इसके सभी संबंधित कार्यों को फिर से लिखने के लिए व्यावहारिक है गैर सूचक मूल्यों को स्टोर करें। फिर फिर, शायद अगर मैंने अपनी डेटा संरचना को और सही तरीके से लिखा था तो मुझे यह समस्या नहीं होती। – MADgood

+0

ठीक है, आप डेटाबेस के बारे में सीखने के अतिरिक्त काम से बचना चाहते हैं, तो आप Excel के रूप में डेटाबेस का उपयोग कर सकते हैं, लेकिन यह लंबे समय तक एक अच्छा विचार होगा? ध्यान रखें कि पॉइंटर-टू-इंट रूपांतरण और पीठ पूरी तरह कार्यान्वित परिभाषित हैं, और यदि आप हैंडलिंग से सावधान नहीं हैं तो आप अनिश्चित व्यवहार में समाप्त हो सकते हैं। आपकी संरचना का उद्देश्य पॉइंटर्स को स्टोर करना था। बिट्टस्टोर डेटास्ट्रक्चर क्यों नहीं लिखते हैं, बिट्स को स्टोर करने के लिए विशेष रूप से अंदर से जुड़े सभी बिट्स के साथ, इसलिए आपको हर कॉल पर इसकी परवाह नहीं है? ओपी को प्रचार के लिए – Secure

+0

-1। लगता है जैसे वह जानता है कि वह क्या चाहता है। –

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