2010-07-08 18 views
6

मैं सी (सी ++ नहीं) का उपयोग कर रहा हूं और मुझे यकीन है कि वैश्विक चर का उपयोग करने से कैसे बचें।सी - प्रोग्राम संरचना (वैश्विक चर से बचने, आदि शामिल हैं)

मेरे पास सी, इसकी वाक्यविन्यास, और मूल अनुप्रयोग कैसे लिखना है, पर एक सुंदर सभ्य समझ है, लेकिन मुझे प्रोग्राम की संरचना करने का उचित तरीका सुनिश्चित नहीं है।

वैश्विक चर के उपयोग से वास्तव में बड़े एप्लिकेशन कैसे बचते हैं? मुझे पूरा यकीन है कि कम से कम कुछ होने की आवश्यकता होगी, लेकिन बड़े गेम और सी में लिखे गए अन्य अनुप्रयोगों के लिए, इसे करने का सबसे अच्छा तरीका क्या है?

क्या कोई अच्छा, ओपन-सोर्स सॉफ़्टवेयर सी में सख्ती से लिखा गया है जिसे मैं देख सकता हूं? मैं अपने सिर के ऊपर से किसी के बारे में नहीं सोच सकता, उनमें से ज्यादातर सी ++ में प्रतीत होते हैं।

धन्यवाद।

संपादित

यहाँ है जहाँ मैं एक सरल एपीआई hooking आवेदन है, जो किसी अन्य प्रक्रिया के अंदर सिर्फ एक DLL है में एक वैश्विक चर का प्रयोग करेंगे का एक उदाहरण है।

यह एप्लिकेशन, विशेष रूप से, अन्य अनुप्रयोगों में उपयोग किए जाने वाले एपीआई कार्यों को हुक करता है। यह कॉल को मूल पर ओवरराइट करने के लिए WriteProcessMemory का उपयोग करके करता है, और इसके बजाय इसे मेरे डीएलएल पर कॉल करता है।

हालांकि, un एपीआई फ़ंक्शन को हुक करने के लिए, मुझे मूल मेमोरी/मशीन कोड वापस लिखना होगा।

तो, मुझे उस मशीन कोड के लिए एक सरल बाइट सरणी बनाए रखने की आवश्यकता है, प्रत्येक एपीआई फ़ंक्शन के लिए एक है जो हुक किया गया है, और बहुत कुछ है।

// Global variable to store original assembly code (6 bytes) 
BYTE g_MessageBoxA[6]; 

// Hook the API function 
HookAPIFunction ("user32.dll", "MessageBoxA", MyNewFunction, g_MessageBoxA); 

// Later on, unhook the function 
UnHookAPIFunction ("user32.dll", "MessageBoxA", g_MessageBoxA); 

क्षमा करें अगर यह भ्रमित है।

+1

आप एक विशिष्ट उदाहरण दे सकता है? आपको क्या लगता है कि आपको वैश्विक चर की आवश्यकता हो सकती है? 99% समय, यह वैश्विक होने के लिए _need_ नहीं है। –

उत्तर

7

"वास्तव में बड़े अनुप्रयोग वैश्विक चर के उपयोग से कैसे बचते हैं?"

  1. उपयोग स्थैतिक चर। यदि किसी फ़ंक्शन को कॉल के बीच कुछ याद रखने की आवश्यकता है, तो इस बनाम वैश्विक चर का उपयोग करें।उदाहरण:

    मानकों के माध्यम से
    int running_total (int num) { 
        static int sum = 0; 
        sum    += num; 
        return sum; 
    } 
    
  2. पास डेटा, ताकि मूल्य एक ही स्थान पर, हो सकता है main() परिभाषित किया और आवश्यक होने पर ही करने के लिए पारित कर दिया है।

  3. यदि अन्य सभी विफल हो जाते हैं, तो आगे बढ़ें और वैश्विक उपयोग करें लेकिन संभावित समस्याओं को कम करने और कम करने का प्रयास करें।

    1. कम से कम, संभावित विवादों को कम करने के लिए नामकरण सम्मेलनों का उपयोग करें। ईजी: Gbl_MyApp_DeveloperName। तो सभी वैश्विक चर Gbl_MyApp_ भाग से शुरू होंगे - जहां "MyApp" आपके ऐप का कुछ वर्णनात्मक था।
    2. उद्देश्य से कार्यों को समूहबद्ध करने का प्रयास करें, ताकि किसी दिए गए वैश्विक की आवश्यकता वाले सभी चीज़ एक ही फ़ाइल (कारण के भीतर) में हों। फिर ग्लोबल्स को उस फ़ाइल में परिभाषित और प्रतिबंधित किया जा सकता है (extern कीवर्ड से सावधान रहें)।
+2

ऐसा लगता है कि अलग-अलग फ़ाइलों में स्थित स्थैतिक चर एक ग्लोबल वैरिएबल की तुलना में ट्रैक रखने के लिए बहुत कठिन हो सकते हैं, कुछ ग्लोबल्स एच फाइल में कुछ के साथ प्रीफिक्स्ड। –

+0

एक विधि जिसका उपयोग मैं प्रत्येक मॉड्यूल के लिए एक संरचना है जो आपके मुख्य() फ़ंक्शन में घोषित हो जाता है। फिर इस संरचना के लिए एक सूचक मॉड्यूल 'Init() फ़ंक्शन और किसी अन्य मॉड्यूल फ़ंक्शन को पास किया जाता है। इस संरचना में मॉड्यूल में उपयोग किए जाने वाले सभी चर शामिल हैं। यह एक दृष्टिकोण है और इसके लिए पेशेवर और विपक्ष हैं। एक समर्थक यह है कि यह मॉड्यूल को कई तरीकों से आसानी से उपयोग करने की अनुमति देता है। उदाहरण के लिए, इस तरह से एकाधिक नियंत्रण लूप को नियंत्रित करने के लिए एक नियंत्रण लूप मॉड्यूल का उपयोग किया जा सकता है। – Seidleroni

1

मेरे कॉलेज में सी सीखने के लिए सबसे अच्छा अनुशंसित ओपन-सोर्स सॉफ्टवेयर लिनक्स था इसलिए आप उनके स्रोत से उदाहरण प्राप्त कर सकते हैं।

2

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

0

वैश्विक चर लगभग अपरिहार्य हैं। हालांकि, वे अक्सर overused हैं। वे उचित पैरामीटर पारित करने और सही डेटा संरचनाओं को डिजाइन करने के लिए एक विकल्प नहीं हैं।

हर बार जब आप वैश्विक चर चाहते हैं, तो सोचें: क्या होगा यदि मुझे इस तरह एक और चाहिए?

+1

क्या आपके पास "अपरिहार्य" वैश्विक चर के लिए एक ठोस उदाहरण है? – Secure

2

यह आसान है - बस उनका उपयोग न करें। अपने मुख्य() फ़ंक्शन में वैश्विक चर को बेन बनाने के लिए, और उसके बाद उन कार्यों के पैरामीटर के रूप में उन्हें वहां से पास करें।

+1

मेरा मतलब "कैवेलियर" होना था - यदि ऐसा करना मुश्किल है, तो डेटा लगभग निश्चित रूप से वैश्विक नहीं होना चाहिए। –

0

मुझे लगता है कि एक ही, वैश्विक खराब हैं, पठनीयता कम कर देता है और त्रुटि संभावना और अन्य समस्याओं बढ़ जाती है।

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

यह वैश्विक चर का केवल तरह है कि मुझे बुरा लग रहा है नहीं है ;-)

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