2009-06-07 16 views
27

मुझे पहले कहना है कि मुझे सी और सी ++ दोनों में उचित अनुभव मिला है। हालांकि, मैं सी में एक नई परियोजना शुरू कर रहा हूं और मैं ऑब्जेक्ट उन्मुख भाषाओं में इतनी देर (सी # और सी ++) में काम कर रहा हूं कि मुझे प्रक्रियात्मक भाषा में कार्यक्षमता को समाहित करने के प्रभावी तरीके से आने में परेशानी हो रही है। मेरा पहला विचार से ये सिर्फ मेरी OO ज्ञान पर वापस आते हैं और यह की तरह कुछ की संरचना करने गया था:प्रभावी ढंग से एक सी प्रोग्राम को कैसे व्यवस्थित करें

struct Foo 
{ 
    int x; 
    char *y; 
}; 

struct Foo *new_Foo() 
{ 
    return (struct Foo *)malloc(sizeof(struct Foo)); 
} 

void Foo_member_function(struct Foo *foo, int z) 
{ 
    foo->x = z;  
} 

लेकिन वह सिर्फ ऐसा नहीं है कि यह एक गरीब आदमी की OO है उल्लेख करने के लिए कठिन और सी की भावना के विपरीत लगता है।

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

प्रासंगिक लेखों और पुस्तकों के पॉइंटर्स भी स्वीकार्य हैं।

+0

मुझे केवल एक जवाब चुनने से नफरत है क्योंकि उनके पास उपयोगी टिड्बिट हैं, लेकिन ओपेक पॉइंटर संदर्भ शायद सबसे उपयोगी चीज थी जिसे मुझे पता नहीं था। धन्यवाद! – HVS

उत्तर

15

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

Opaque pointer देखें।

+1

मुझे एचडब्ल्यूएनडी की याद दिलाता है, और मूल Win32 सी api – bobobobo

11

आप जो सुझाव दे रहे हैं वह है जिस तरह से मैंने हमेशा सी प्रोग्राम को उन दिनों में लिखा था जब मैंने ऐसा कुछ किया था। मुझे नहीं लगता कि यह "गरीब मनुष्य ओओ" है, मुझे लगता है कि यह समझदार प्रक्रियात्मक प्रोग्रामिंग अभ्यास है।

मैं अपनी सी कोड के बारे में बातें की एक जोड़ी का पालन होगा: struct परिभाषा के साथ

  • उपयोग typedefs ताकि आप कोड के दौरान 'struct' कीवर्ड को तितर बितर करने के लिए की जरूरत नहीं है
  • केवल उपयोग डाले जब वे वास्तव में जरूरत है - malloc() से वापसी मान पर डाली अनावश्यक है
+0

अच्छी टिप्स। "गरीब मनुष्य ओओ" का मेरा मतलब यह था कि यह बहुत ही सीमित ओओ था (यानी कोई बहुलकता नहीं, कोई encapsulation, आदि)। – HVS

+1

लेकिन इस बात से अवगत रहें कि लिपिफिन को कुछ लोगों के लिए बुरी आदत माना जाता है, जिसमें लिनक्स कर्नल क्रू – temp2290

1

सी एक कम स्तर की भाषा में किया गया है और मामले में यह बहुत अपने कोड के अनुसार अपने डेटा संरचनाओं को व्यवस्थित करने के लिए उपयोगी होगा कार्य और मॉड्यूल।

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

3

हमम ... हम नामकरण सम्मेलनों का उपयोग करते थे ... Ergo: str * क्या सामान्य डेटास्ट्रक्चर के साथ सामान करता है? तो शायद सी # वाक्यविन्यास और s /./_/ जी ले लो?

  • foo_constructor
  • foo_destructor
  • foo_someMethod
  • foo_someMethod2 // एएनएसआई सी
  • foo_otherMethod

में कोई अधिक भार नहीं है ... और कोई विरासत नहीं है। ..

  • foo2_constructor
  • foo2_destructor
  • foo2_someMethod // और वहाँ कोई बहुरूपता

लेकिन उज्ज्वल पक्ष पर नहीं लग रही है ... आप सूचक-टू-सूचक-हैं- उपयोग कर सकते हैं सूचक करने वाली समारोह-लौट-ए-सूचक-टू-सूचक-पूर्णांक! ओह खुशी!

मेरी सबसे अच्छी सलाह जावा (और अनुमान सी # द्वारा) के पाठों को सीखना है और अपने पुस्तकालयों को साइड इफेक्ट्स नहीं होने के लिए संरचना है ... अधिक typdefs == कम सिरदर्द ... और यदि आपका काम-बाहर कैसे करें इस ऋषि सलाह का पालन करें कृपया मुझे बताएं ;-)

चीयर्स। कीथ।

+0

"साइड इफेक्ट्स" द्वारा, मुझे लगता है कि आप स्थिर चर, ग्लोबल्स इत्यादि का मतलब रखते हैं? स्पष्ट रूप से पुस्तकालयों को उनके द्वारा संशोधित "ऑब्जेक्ट्स" पर दुष्प्रभाव होंगे। – HVS

+0

आम तौर पर, आप कुछ राज्य को अपडेट करने के लिए मौजूदा एक को म्यूट करने के बजाय नए राज्य को वापस कर सकते हैं, यह कार्यात्मक प्रोग्रामिंग के अनुरूप है और डेटा प्रवाह निर्भरताओं को अधिक स्पष्ट और अनुसरण करने में आसान बना देगा। – none

2

यह एक सी प्रोग्राम लिखने का एक बहुत ही उचित तरीका है। वहां एक और बड़ा एप्लीकेशन है, जो कि वही सामान करता है - जिसे लिनक्स कर्नेल कहा जाता है। वैसे ही जैसे अपने उदाहरण में आधार structs को

  • संकेत गरीब आदमी का विरासत के रूप में

    • structs और कैप्सूलीकरण के लिए structs पर कार्रवाई - आप का भार मिल जाएगा: कुछ लगभग OO-सुविधाओं वहाँ में इस्तेमाल किया संदर्भ वहाँ
    • मैक्रो में kobject struct करने के लिए टेम्पलेट प्रोग्रामिंग
  • 1

    मैं उपरोक्त सुझावों से सहमत के लिए एक स्थानापन्न के रूप में कार्य उत्पन्न करने के लिए। आप इसे सबसे अच्छा तरीका कर रहे हैं .. यदि आप सी

    में प्रोग्राम करना चाहते हैं बेशक, आप इन घोषणाओं और चीजों को स्वचालित रूप से उत्पन्न करने के लिए प्री-प्रोसेसर लिख सकते हैं .. शायद "कक्षा" घोषणा का उपयोग करें। .. उन कार्यों को रखें जिन्हें आप वर्ग के अंदर सदस्य कार्य करना चाहते हैं .. आदि

    लेकिन जो हमने यहां प्राप्त किया है वह सी संकलक सी सरल है। सी ++ में प्रोग्राम क्यों नहीं, वास्तविक सी ++ कंपाइलर का उपयोग करें, स्वच्छ इंटरफेस का उपयोग करें, और सी कोड के साथ सी ++ कोड को लिंक करें? सी बनाम सी ++ में किसी भी तरह से कोड करने की आवश्यकता क्या है? या यदि आपको कंपाइलर से सी कोड उत्पन्न करना है और आउटपुट सी कोड को किसी और चीज के साथ संकलित करना है।

    +1

    मैं वास्तव में सी ++ का प्रशंसक नहीं हूं, भले ही पिछले कुछ वर्षों में यह काफी सुधार हुआ है (बूस्ट एक महान पुस्तकालय है)। इसके अलावा, इस परियोजना का हिस्सा काफी निम्न स्तर है जो सी चुनने के कारणों में से एक है। दूसरा यह है कि यह खुला स्रोत होगा और इसे यथासंभव लचीला रखना चाहता है। मैं * सी ++ में किया जा सकता था, लेकिन इससे अधिक समस्याएं पैदा होती हैं जो मुझे लगता है कि यह लायक है। – HVS

    +1

    आपको सभी सुविधाओं का उपयोग करने की आवश्यकता नहीं है - बस एक बहुत ही सरल सबसेट - यानी कक्षाएं, विधियों, रचनाकारों, विनाशकों के साथ चिपके रहें - बाकी को मानक सी में रखें। ओपन सोर्स रिलीज के लिए, आप सी ++ से सी कंपाइलर चला सकते हैं और सी कोड वितरित कर सकते हैं। –

    +0

    सी हम निम्न स्तर के बीच क्या करते हैं, सी ++ के पास लिनक्स इको-सिस्टम के लिए लगभग कोई मूल्य नहीं है। आप या तो इसे सही करते हैं, इसे सी के साथ वास्तव में धीमा कर लेते हैं, या आप एक आधुनिक भाषा का उपयोग करते हैं जैसे गोलांग उन सामानों के लिए जिन्हें आप अभी भी पूरी तरह से संकलित करना चाहते हैं। सी ++ कोड पर डेवलपर्स है, और यह आचारों के प्रति विरोधी है, लिनस इसे सही मिला। – TechZilla

    0

    मैं थोड़ी देर के लिए एक परियोजना पर काम कर रहा हूं जहां लाइब्रेरी को सी में होना चाहिए, लेकिन मैं ओओ कार्यक्षमता का कुछ रूप लेना चाहता हूं। मैं थोड़ा और विस्तार के साथ ऐसा कुछ कर रहा हूं।

    struct klass { 
        char * value; 
    
        void (*set_value) (struct klass *, const char *); 
        void (*destroy) (struct klass *); 
    }; 
    
    static void 
    klass_method_set_value (struct klass * k, const char * value) { 
        if (k->value == NULL) { 
        } 
    } 
    
    static void 
    klass_object_desetroy (struct klass * k) { 
        free (k); 
        k = NULL; 
    } 
    
    static void 
    klass_method_destroy (struct klass * k) { 
        klass_object_destroy (k); 
    } 
    
    static struct klass * 
    klass_object_init (void) { 
        struct klass * obj = (struct klass *) malloc (sizeof (struct klass*)); 
    
        /* members */ 
        obj->value = NULL; 
    
        /* methods */ 
        obj->set_value = klass_method_set_value; 
        obj->destroy = klass_method_destroy; 
        return obj; 
    } 
    
    struct klass * 
    klass_new (void) { 
        return klass_object_init(); 
    } 
    

    अगर कुछ गलत है तो मुझे माफ़ कर दो; इसे थोड़ा जल्दी लिखा था।

    +0

    हाँ, यह वही है जो मैं टालना चाहता था। मैंने सुना है कि मूल रूप से स्ट्रॉस्ट्रप ने पहले सी ++ कंपाइलर को कोड करने के लिए कोड किया था, हालांकि। – HVS

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