सी कोडिंग डिजाइन - समारोह संकेत?


24

मेरे पास एक PIC18F46K22 है और इसे XC8 कंपाइलर के साथ प्रोग्राम करें। अंत में, मेरे पास एक पीसी जैसा सिस्टम होगा stdinऔर stdout। तो मुख्य लूप में एक फ़ंक्शन होगा जो कि नया इनपुट होने पर जाँच कर रहा है। यदि इनपुट है, तो तदनुसार एक फ़ंक्शन कहा जाएगा। उदाहरण के लिए जब मैं इनपुट पर एक ए stdin, पीआईसी की तरह एक समारोह चलेगा function_Aबजाय function_Bजो कहा जाता है जब मैं एक बी इनपुट

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

मैंने यह सोचने के लिए बहुत कुछ किया है कि इसे सी में कैसे प्रोग्राम किया जाए। मैंने कल रात यह सोचा था और जानना चाहूंगा कि क्या यह संभव है और यदि हां, तो कैसे। मुझे क्या करना है:

  • mainसमारोह की तरह एक फ़ंक्शन को कॉलfunction_A
  • function_Afunction_addrफ़ंक्शन के पॉइंटर के वैश्विक चर को बदलता हैin_function_A
  • उस क्षण से, नया इनपुट होने mainपर फ़ंक्शन को कॉल करता function_addrहै।

तो मुझे क्या चाहिए एक mainफ़ंक्शन जो चेक करता है कि function_addrक्या शून्य है। यदि ऐसा है, तो एक 'सामान्य' फ़ंक्शन को बुलाया जाना चाहिए, जैसे function_A। यदि ऐसा नहीं है, तो समारोह को function_addrबुलाया जाना चाहिए। मुझे एक पॉइंटर को function_Aबदलने की भी आवश्यकता function_addrहै in_function_A

नोट: जब फाइल सिस्टम फ़ंक्शन बंद is_function_Aहोना चाहिए , तो बस function_addr0 में बदलना चाहिए ।

तो मूल रूप से मेरा सवाल यह है कि मैं कैसे कर सकता हूं

  • किसी फ़ंक्शन का पता प्राप्त करें (और इसे किसी चर में संग्रहीत करें)
  • एक निर्दिष्ट पते पर एक फ़ंक्शन को कॉल करें

6
विषय से परे। Stackoverflow.com पर विश्वास करता है।
user207421

मेरे लिए, एक राज्य मशीन दृष्टिकोण फ़ंक्शन पॉइंटर्स से निपटने की तुलना में बहुत कम जोखिम भरा है। आपका इनपुट बाइट एक राज्य मशीन संरचना को दिया जाता है (एक स्विच-केस के रूप में सरल हो सकता है) जो राज्य चर या चर के एक समारोह के रूप में कोड के विभिन्न बिट्स के लिए कूदता है। इसके अलावा, आप पूरी तरह से स्पष्ट नहीं हैं कि आपका स्टड कहां से आ रहा है (ऐसा नहीं है कि यह वास्तव में बहुत मायने रखता है, लेकिन मैं उत्सुक हूं)।
एडम लॉरेंस

9
@EJP मैं असहमत हूं। सिर्फ इसलिए कि एक ओवरलैप का मतलब यह नहीं है कि यह एक साइट या दूसरे पर होना है। यह निम्न स्तर के एम्बेडेड सिस्टम के डिजाइन और प्रोग्रामिंग से संबंधित प्रश्न पूछ रहा है, जो विषय पर या तो स्थान पर लगता है।
१५:१५ बजे कोरटुक

राज्य मशीनें फ़ंक्शन अप्रत्यक्ष पर आधारित हो सकती हैं: राज्य संक्रमण फ़ंक्शन के लिए कॉल एक नया राज्य संक्रमण फ़ंक्शन देता है।
काज

1
चलो यह चर्चा यहाँ है

जवाबों:


21

एक समारोह

int f(int x){ .. }

किसी फ़ंक्शन का पता प्राप्त करें (और इसे किसी चर में संग्रहीत करें)

int (*fp)(int) = f;

एक निर्दिष्ट पते पर एक फ़ंक्शन को कॉल करें

int x = (*fp)( 12 );

3
सी और एएसएम दुनिया में +1 स्पष्ट है, लेकिन उन लोगों के लिए स्पष्ट नहीं है जिन्होंने ओओ भाषाओं के साथ शुरुआत की।
अनिंदो घोष

4
Fp कॉल को 'int x = fp (12);' भी लिखा जा सकता है। पठनीयता बढ़ाने के लिए।
Rev1.0

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

@ माइकलकॉर्जलिंग: तो सच है। मैं एम्बेडेड C और C # प्रोग्रामिंग के बीच लगातार स्विच कर रहा हूं (यहां तक ​​कि डिवाइस और पीसी के बीच संचार के लिए समान कोड को लागू करना) और जैसा कि C # हो सकता है, मैं अभी भी C का आनंद लेता हूं।
Rev1.0

2
fp(12)पर पठनीयता में वृद्धि नहीं करता है (*fp)(12)। उनकी अलग पठनीयता है। (*fp)(12)पाठक को याद दिलाता है कि fpएक सूचक है, और की घोषणा के समान है fp। मेरे दिमाग में, यह शैली पुराने स्रोतों से जुड़ी हुई है, जैसे X11 इंटर्नल, और K & R C. एक संभावित कारण यह K & R C से जुड़ा हो सकता है क्योंकि ANSI C में, fpफ़ंक्शन सिंटैक्स का उपयोग करके घोषित करना संभव है , यदि fpकोई पैरामीटर है int func(int fp(double)) {}। K & R C में वह होता int func(fp) int (*fp)(double); { ... }
काज

17

जबकि Wouters का उत्तर बिल्कुल सही है, शायद यह अधिक अनुकूल है और आपके प्रश्न के बारे में बेहतर उदाहरण है।

int (*fp)(int) = NULL;

int FunctionA(int x){ 
    return x + x;
}

int FunctionB(int x){ 
    return x * x;
}

void Example(void) {
    int x = 0;

    fp = FunctionA;
    x = fp(3);  /* after this, x == 6 */

    fp = FunctionB;
    x = fp(3);  /* after this, x == 9 */
}

यदि यह स्पष्ट नहीं है कि फ़ंक्शन पॉइंटर वास्तव में एक लक्षित फ़ंक्शन पता सौंपा गया है, तो यह एक पूर्ण जांच करने के लिए बुद्धिमान है।

if (fp != NULL)
    fp(); /* with parameters, if applicable */

8
नल चेक के लिए +1 करें, लेकिन ध्यान दें कि कंपाइलर गारंटी नहीं दे सकता है कि रैम में मौजूद पते पर जो मूल्य fpकब्जे में होता है वह वास्तव में शुरू में NULL है। मैं int (*fp)(int) = NULL;एक संयुक्त घोषणा के रूप में करूँगा और निश्चित होने के लिए आरंभीकरण - आप कुछ नासमझ मूल्य के कारण कुछ यादृच्छिक स्मृति स्थान पर कूदना नहीं चाहते हैं जो कि बस वहीं हुआ। तो बस fpअपने Example()फ़ंक्शन में असाइन करें ।
बजे एक CVn

1
टिप्पणी के लिए धन्यवाद, मैंने NULL आरंभीकरण जोड़ा।
Rev1.0

4
@ माइकलकॉर्ज़िंग अच्छी बात है, लेकिन अगर fpएक "वैश्विक चर" है (जैसा कि वह ऊपर कोड है), तो इसे NULL(स्पष्ट रूप से ऐसा करने के बिना) आरंभ करने की गारंटी है ।
आलोक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.