सी - संरचना के अंदर कार्य


86

Im एक संरचना के अंदर एक समारोह बनाने की कोशिश कर रहा है, अब तक मेरे पास यह कोड है:

त्रुटि : client.h: 24: 2: त्रुटि: अपेक्षित ':', ',', ';', '' 'या' विशेषता 'से पहले' {'टोकन।

इसे करने का सही तरीका कौन सा है?


12
आप सी में संरचना में कार्य नहीं कर सकते हैं; यद्यपि आप फ़ंक्शन पॉइंटर्स द्वारा मोटे तौर पर अनुकरण करने का प्रयास कर सकते हैं।
फिंगोल्फिन

1
क्या फ़ंक्शन पॉइंटर्स एक स्वीकार्य विकल्प हैं? stackoverflow.com/a/840703/635678
Dan O

जवाबों:


108

यह सीधे नहीं किया जा सकता है, लेकिन आप फ़ंक्शन पॉइंटर्स का उपयोग करके एक ही चीज़ का अनुकरण कर सकते हैं और स्पष्ट रूप से "यह" पैरामीटर पास कर सकते हैं:

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


3
X11 API कुछ इस तरह का काम करता है। XImage देखें ।
हाइड्रानिक्स

1
Windows API के अंतर्गत आने वाला कोड इससे भरा हुआ है। तकनीकी रूप से एक "विंडो क्लास" दो कॉलबैक फंक्शन पॉइंटर्स के साथ और ओपन एंड के साथ एक स्ट्रक्चर है (इसके लिए "विंडो क्लास स्पेसिफिकेशन्स डेटा" जिसे आप रजिस्टर करते हुए सप्लाई कर सकते हैं)
स्विफ्ट - फ्राइडे पाई

1
उन चरणों का पालन किया है, लेकिन जब मैं संरचना करता हूं । नया संकलक करता है संकलक प्रिंट: त्रुटि: अपेक्षित '=', ',', ',', 'असम्' या ' विशेषता ' से पहले। ' टोकन
बोन्फ्रा

यह तब भी उपयोगी होगा जब आप एक सामान्य लक्ष्य (जैसे हार्ड ड्राइव) चाहते थे, जिसमें एक रीड फंक्शन और एक लिखित फ़ंक्शन होता है, लेकिन जो एक प्रकार के हार्ड ड्राइव से भिन्न होता है
मेन्कॉटन

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

24

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

आप जो चाहते हैं, वह वर्चुअल विधि तालिका जैसा कुछ और है।

अब, अधिक संचालन जोड़ने से client_tसंरचना का आकार नहीं बदलता है । अब, इस प्रकार का लचीलापन केवल तभी उपयोगी है जब आपको कई प्रकार के क्लाइंट्स को परिभाषित करने की आवश्यकता होती है, या अपने client_tइंटरफ़ेस के उपयोगकर्ताओं को यह बताना चाहते हैं कि ऑपरेशन कैसे व्यवहार करते हैं।

इस तरह की संरचना वास्तविक कोड में दिखाई देती है। OpenSSL BIO लेयर इससे मिलती जुलती दिखती है, और UNIX डिवाइस ड्राइवर इंटरफेस में भी इस तरह की एक लेयर होती है।


15

यह केवल C ++ में काम करेगा। संरचना में कार्य C की विशेषता नहीं है।

वही आपके क्लाइंट के लिए जाता है ।ddClient (); कॉल ... यह एक सदस्य फ़ंक्शन के लिए एक कॉल है, जो ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग है, अर्थात सी ++।

अपने स्रोत को एक .cpp फ़ाइल में बदलें और सुनिश्चित करें कि आप तदनुसार संकलित कर रहे हैं।

यदि आपको C से चिपके रहने की आवश्यकता है, तो नीचे दिया गया कोड समान (समान) है:


1
यह uni प्रोजेक्ट है और मुझे C. का उपयोग करना है। क्या कोई ऐसा तरीका है जिससे मैं C में जो चाहता हूं, उसे प्राप्त कर सकूं?
xRed

बस उस फ़ंक्शन को संरचना से बाहर ले जाएं और इसे अपने उदाहरण के लिए एक पॉइंटर स्वीकार करें।
user123

मुवक्किल.एक क्लीकेंट () बात बिना कुछ जटिल जादू के संभव नहीं होगा (अन्य उत्तर देखें)।
QSQ

14

इस बारे में कैसा है?


समाधान की तरह एक "थोड़ा सा" JavaScrip
बिटमैन

8

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

सी प्रोग्राम के लिए खरोंच से ऑब्जेक्ट-ओरिएंटेशन को सुदृढ़ करना आवश्यक नहीं है, जो ऑब्जेक्ट ओरिएंटेड भाषा नहीं है।

मैंने इसे पहले देखा है। बड़ी अजीब बात है। कोडर्स, उनमें से कुछ, एक वस्तु को पारित करने के लिए एक विचलन है जिसे वे इसे बदलने के लिए एक फ़ंक्शन में बदलना चाहते हैं, भले ही ऐसा करने का मानक तरीका हो।

मैं सी ++ को दोष देता हूं, क्योंकि यह इस तथ्य को छिपाता है कि सदस्य ऑब्जेक्ट में क्लास ऑब्जेक्ट हमेशा पहला पैरामीटर है, लेकिन यह छिपा हुआ है। तो ऐसा लगता है कि यह फ़ंक्शन में ऑब्जेक्ट को पास नहीं कर रहा है, भले ही यह हो।

C लचीला है और संदर्भ द्वारा चीजों को ले जा सकता है।

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

addClient Client.h या Client.c में होगा


दृष्टिकोण के पक्ष और विपक्ष हैं। सिर्फ इसलिए कि यह हमेशा से किया गया है , दोनों गैर-OO ( do(object, subject)) और OO ( subject.do(object)) कार्यों को व्यवस्थित करने की रणनीतियों का उल्लेख करते हुए , इसका मतलब यह नहीं है कि हमें इसे आज़माना बंद कर देना चाहिए। मुझे पूरी तरह से लगता है कि यह इंगित करने के लिए वैध है कि यह सी लिखा गया ऐतिहासिक तरीका नहीं है, और सी को इस तरह से लिखने की आवश्यकता नहीं है (वही कई भाषाओं के लिए जाता है, प्रक्रियात्मक, कार्यात्मक या तर्क प्रतिमानों से जासूसी करता है), लेकिन मुझे पैटर्न को सक्रिय रूप से हतोत्साहित करने की आवश्यकता नहीं है। यह कुछ लाभों के साथ आता है
hiljusti

0

आप फ़ंक्शन तर्क के रूप में कार्य करने के लिए स्ट्रक्चर पॉइंटर पास कर सकते हैं। इसे पास बाय रेफरेंस कहा जाता है।

यदि आप उस पॉइंटर के अंदर कुछ संशोधित करते हैं, तो अन्य को अपडेट किया जाएगा। इस तरह की कोशिश करें:


संदर्भ से कोई पास नहीं है। आप सूचक की एक प्रति पारित कर रहे हैं, सूचक के संदर्भ समान हैं, लेकिन संकेत स्वयं नहीं।
सार्जेंट कोर्टेज

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