मुझे सी में जटिल परियोजनाओं की संरचना कैसे करनी चाहिए? [बन्द है]


79

मेरे पास शुरुआती स्तर के सी कौशल से थोड़ा अधिक है और यह जानना चाहूंगा कि क्या सी में कुछ जटिल अनुप्रयोग की संरचना करने के लिए कोई वास्तविक तथ्य "मानक" हैं।

मैं हमेशा जावा और PHP में OO प्रतिमान का उपयोग करता रहा हूं और अब जब मैं C सीखना चाहता हूं तो मुझे डर है कि मैं अपने अनुप्रयोगों को गलत तरीके से संरचना कर सकता हूं। मैं एक नुकसान पर हूं, जिसमें प्रक्रियात्मक भाषा के साथ प्रतिरूपकता, अवनति और सूखापन का पालन करने के लिए दिशानिर्देश हैं।

क्या आपके पास सुझाव देने के लिए कोई रीडिंग है? मुझे C के लिए कोई एप्लिकेशन फ्रेमवर्क नहीं मिला, भले ही मैं उन फ्रेमवर्क का उपयोग न करता हो जो मैंने हमेशा उनके कोड ब्राउज़ करके अच्छे विचार पाए हैं।


3
यूनिक्स दर्शन बड़ी परियोजनाओं के आयोजन के लिए बहुत उपयोगी है: http://www.faqs.org/docs/artu/ch01s06.html
newDelete

जवाबों:


51

कुंजी प्रतिरूपकता है। यह डिजाइन, कार्यान्वयन, संकलन और रखरखाव आसान है।

  • अपने ऐप में मॉड्यूल की पहचान करें, जैसे OO ऐप में कक्षाएं।
  • प्रत्येक मॉड्यूल के लिए अलग इंटरफ़ेस और कार्यान्वयन, इंटरफ़ेस में रखा गया है जो अन्य मॉड्यूल द्वारा आवश्यक है। याद रखें कि सी में कोई नाम स्थान नहीं है, इसलिए आपको अपने इंटरफेस में सब कुछ अद्वितीय बनाना होगा (जैसे, उपसर्ग के साथ)।
  • कार्यान्वयन में वैश्विक चर को छिपाएं और पढ़ने / लिखने के लिए एक्सेसर फ़ंक्शन का उपयोग करें।
  • वंशानुक्रम के संदर्भ में मत सोचो, लेकिन रचना के संदर्भ में। एक सामान्य नियम के रूप में, C ++ में C ++ की नकल करने की कोशिश न करें, यह पढ़ना और बनाए रखना बहुत मुश्किल होगा।

यदि आपके पास सीखने का समय है, तो इस बात पर एक नज़र डालें कि एक Ada ऐप कैसे संरचित है, इसके अनिवार्य package(मॉड्यूल इंटरफ़ेस) और package body(मॉड्यूल कार्यान्वयन) के साथ।

यह कोडिंग के लिए है।

बनाए रखने के लिए (याद रखें कि आप एक बार कोड करते हैं, लेकिन आप कई बार बनाए रखते हैं) मैं आपके कोड का दस्तावेजीकरण करने का सुझाव देता हूं; मेरे लिए Doxygen एक अच्छा विकल्प है। मेरा सुझाव है कि एक मजबूत प्रतिगमन परीक्षण सूट का निर्माण किया जाए, जो आपको रिफ्लेक्टर करने की अनुमति देता है।


30

यह एक आम गलत धारणा है कि OO तकनीक को C में लागू नहीं किया जा सकता है। अधिकांश - यह सिर्फ इतना है कि वे नौकरी के लिए समर्पित वाक्यविन्यास वाली भाषाओं की तुलना में थोड़ा अधिक अनजान हैं।

मजबूत सिस्टम डिज़ाइन की नींव में से एक इंटरफ़ेस के पीछे कार्यान्वयन का एनकैप्सुलेशन है। FILE*और इसके साथ काम करने वाले कार्य ( fopen(), fread()आदि) एक अच्छा उदाहरण है कि इंटरफेस स्थापित करने के लिए सी में कैसे एनकैप्सुलेशन लागू किया जा सकता है। (बेशक, चूंकि सी में एक्सेस निर्दिष्टताओं का अभाव है, आप इसे लागू नहीं कर सकते हैं कि कोई एक के अंदर झांकता नहीं हैstruct FILE , लेकिन केवल एक मसोचिस्ट ऐसा करेगा।)

यदि आवश्यक हो, तो पॉलीमॉर्फिक व्यवहार फ़ंक्शन पॉइंटर्स की तालिकाओं का उपयोग करके सी में हो सकता है। हाँ, वाक्यविन्यास बदसूरत है, लेकिन प्रभाव आभासी कार्यों के समान है:


11
एक शुद्ध सी कोडर इस कोड को पढ़ने से
चूक जाएगा

15
@ माउवीसील: बकवास! अधिकांश सी कोडर फ़ंक्शन पॉइंटर्स (या कम से कम उन्हें चाहिए) को समझते हैं, और यहां वास्तव में कुछ भी नहीं है। विंडोज पर कम से कम, डिवाइस ड्राइवर और COM ऑब्जेक्ट दोनों इस तरह से अपनी कार्यक्षमता प्रदान करते हैं।
j_random_hacker

8
मेरी बात अक्षमता के बारे में नहीं है, यह अनावश्यक जटिलता के बारे में है। फंक्शन पॉइंटर्स C कोडर (जैसे, कॉलबैक) के लिए सामान्य हैं, इनहेरिटेंस नहीं है। मैं पसंद करता हूं कि C C कोड करने वाला C ++ कोड सीखने के लिए C के बजाय C सीखने के लिए अपने समय का उपयोग करता है। कहा कि, आपका दृष्टिकोण कुछ मामलों में उपयोगी हो सकता है।
मौविसील

3
वास्तव में आप C ++ pimpl मुहावरे का उपयोग करके एक्सेस स्पेसर्स का अनुकरण भी कर सकते हैं । यदि किसी प्रकार के निजी सदस्यों को एक प्रकार में इनकैप्सुलेट किया जाता है जो केवल कार्यान्वयन (उर्फ ".c फ़ाइल") में दिखाई देता है, तो इंटरफ़ेस के उपयोगकर्ताओं को उन्हें बदलने में एक कठिन समय होगा (निश्चित रूप से, वे बकवास लिख सकते हैं। पिंपल पॉइंटर, यदि वे जानबूझकर आपको खराब करना चाहते हैं , लेकिन आप C ++ में भी ऐसा कर सकते हैं)।
बिटमस्क

2
Downvoter: टिप्पणी करने के लिए परवाह है?
j_random_hacker

15

सभी अच्छे जवाब।

मैं केवल "न्यूनतम डेटा संरचना" जोड़ूंगा। यह C में और भी आसान हो सकता है, क्योंकि यदि C ++ "C विथ क्लासेस" है, तो OOP आपको हर संज्ञा / क्रिया को अपने सिर में लेने और इसे क्लास / मेथड में बदलने के लिए प्रोत्साहित करने की कोशिश कर रहा है। जो बहुत बेकार हो सकता है।

उदाहरण के लिए, मान लें कि आपके पास समय पर बिंदुओं पर तापमान रीडिंग की एक सरणी है, और आप उन्हें विंडोज में लाइन-चार्ट के रूप में प्रदर्शित करना चाहते हैं। Windows में एक PAINT संदेश है, और जब आप इसे प्राप्त करते हैं, तो आप लाइन के कार्यों को करने वाले सरणी के माध्यम से लूप कर सकते हैं, डेटा को स्केल कर सकते हैं जैसा कि आप इसे पिक्सेल निर्देशांक में बदलने के लिए जाते हैं।

मैंने जो भी पूरी तरह से कई बार देखा है, चूंकि चार्ट में बिंदु और रेखाएं होती हैं, लोग बिंदु वस्तुओं और रेखा वस्तुओं से मिलकर एक डेटा संरचना का निर्माण करेंगे, जो प्रत्येक ड्रामीफेल के लिए सक्षम हैं, और फिर उस सिद्धांत पर, इसे लगातार बनाए रखें किसी भी तरह से "अधिक कुशल" है, या कि वे शायद, बस हो सकता है, चार्ट के कुछ हिस्सों पर माउस ले जा सकें और डेटा को संख्यात्मक रूप से प्रदर्शित कर सकें, इसलिए वे इससे निपटने के लिए वस्तुओं में तरीके बनाते हैं, और यह कि, निश्चित रूप से, इसमें और भी अधिक ऑब्जेक्ट बनाना और हटाना शामिल है।

तो आप एक बड़ी मात्रा में कोड के साथ समाप्त होते हैं जो ओह-इतना पठनीय है और केवल 90% समय खर्च करने वाली वस्तुओं को खर्च करता है।

यह सब "अच्छा प्रोग्रामिंग अभ्यास" और "दक्षता" के नाम पर किया जाता है।

कम से कम सी में सरल, कुशल तरीका अधिक स्पष्ट होगा, और पिरामिड को कम मजबूत बनाने का प्रलोभन।


1
अपने जवाब से प्यार करें, और यह पूरी तरह सच है। OOP को मरना होगा!
जो तो

@ जोसो: मैं OOP का उपयोग करता हूं, लेकिन न्यूनतम रूप से।
माइक डनलैवी

मेरे लिए "न्यूनतम रूप से" (हालांकि मुझे नहीं पता कि आपके लिए इसका क्या मतलब है) वास्तव में ओओपी के रूप में गिना नहीं जाता है, जो ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग है - डिफ़ॉल्ट रूप से ऑब्जेक्ट।
जो तो

मैं कुछ "ओओपी" का भी उपयोग करता हूं। मुख्य रूप से मेरे C मॉड्यूल के लिए, जिनमें से कई में init () और निकास () रूटीन हैं।
जो तो

11

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


4
हर कोई उन्हें पसंद नहीं करता है, lxr.linux.no/linux+v2.6.29/Documentation/CodingStyle से : "सबसे पहले, मैं GNU कोडिंग मानकों की एक प्रति प्रिंट करने का सुझाव दूंगा , और इसे नहीं पढ़ूंगा । उन्हें जलाएं, यह एक है। महान प्रतीकात्मक इशारा ”। मैंने उन्हें कई वर्षों में नहीं पढ़ा है, लेकिन लिनुस के पास कुछ वैध आपत्तियां हैं।
२१:२५

1
@ क्लोवल्ड: बेशक हर कोई किसी एक विशेष कोडिंग मानक को पसंद नहीं करता है, यही कारण है कि समान उपयोग के मामलों के लिए एक से अधिक मानक हैं। महत्वपूर्ण बात यह है कि आपकी अपनी परियोजनाओं के भीतर सुसंगत, कि कम से कम कुछ मानक का पालन किया जाता है, बजाय वास्तविक तथ्य के असंगतता के।
जेएम बेकर

4

यदि आप जानते हैं कि जावा या सी ++ में अपने कोड को कैसे बनाया जाए, तो आप सी कोड के साथ समान सिद्धांतों का पालन कर सकते हैं। एकमात्र अंतर यह है कि आपके पास संकलक नहीं है और आपको मैन्युअल रूप से अतिरिक्त सब कुछ करने की आवश्यकता है।

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

आपके पास C के साथ कक्षाएं नहीं हो सकती हैं, लेकिन आप "सार डेटा प्रकार" को आसानी से लागू कर सकते हैं। आप प्रत्येक अमूर्त डेटा प्रकार के लिए .C और .H फ़ाइल बनाते हैं। यदि आप चाहें तो आपके पास दो हेडर फाइलें, एक सार्वजनिक और एक निजी हो सकती हैं। यह विचार है कि सभी संरचनाएं, स्थिरांक और फ़ंक्शन जिन्हें निर्यात करने की आवश्यकता है, सार्वजनिक हेडर फ़ाइल पर जाएं।

आपके उपकरण भी बहुत महत्वपूर्ण हैं। सी के लिए एक उपयोगी उपकरण एक प्रकार का वृक्ष है , जो आपके कोड में खराब गंधों को खोजने में मदद कर सकता है। एक और उपकरण जिसका आप उपयोग कर सकते हैं वह है Doxygen, जो आपको दस्तावेज़ बनाने में मदद कर सकता है ।


4

विकास की भाषा की परवाह किए बिना एनकैप्सुलेशन हमेशा एक सफल विकास की कुंजी है।

सी में मैंने "निजी" विधियों को एनकैप्सुलेट करने में मदद करने के लिए एक ट्रिक का उपयोग किया है, जो कि ".h" फ़ाइल में उनके प्रोटोटाइप को शामिल नहीं करता है।


3

मैं आपको किसी भी लोकप्रिय ओपन सोर्स C प्रोजेक्ट के कोड की जांच करने के लिए चीनी देता हूँ, जैसे ... hmm ... Linux कर्नेल, या Git; और देखें कि वे इसे कैसे व्यवस्थित करते हैं।


3

जटिल आवेदन के लिए संख्या नियम: इसे पढ़ना आसान होना चाहिए।

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


2

मैं पहले चरण के रूप में C / C ++ पाठ्यपुस्तक पढ़ने का सुझाव दूंगा। उदाहरण के लिए, सी प्राइमर प्लस एक अच्छा संदर्भ है। उदाहरणों के माध्यम से देखने से आपको पता चलेगा कि आपके जावा OO को और अधिक प्रक्रियात्मक भाषा में कैसे मैप किया जाए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.