क्या शून्य * फ़ंक्शन () एक सूचक कार्य करने के लिए है या एक फ़ंक्शन एक शून्य * लौटा रहा है?


26

मैं के अर्थ के बारे में उलझन में हूँ void *function()
क्या यह कार्य करने के लिए एक संकेतक है या कोई फ़ंक्शन लौट रहा है void*? मैंने हमेशा डेटा संरचनाओं पर एक पुनरावर्ती फ़ंक्शन को पॉइंटर वापस करने के रूप में उपयोग किया है, लेकिन जब मैंने मल्टीथ्रेडिंग ( pthread) में एक कोड देखा तो वही फ़ंक्शन घोषणा है। अब मैं उलझन में हूँ कि उनके बीच क्या अंतर है।


5
@goodvibration C को प्रारूप-मुक्त (और C ++ "विरासत में मिला है")। यहां तक void*function();कि वाक्यात्मक रूप से सही है। उदाहरण के लिए पायथन के लिए उन्होंने एक अलग निर्णय लिया - प्रारूप वाक्यविन्यास का हिस्सा है। IMHO, दोनों तरह से इसके समर्थक और चोर हैं।
शेफ

3
@goodvibration जितना अधिक आप प्रोग्रामर को वह करने से बचाने की कोशिश करते हैं, जितना वे चाहते हैं कि आपको कुछ वैसा ही मिले जैसे कि आपको जावा;)
idclev 463035818

2
@ घटाव कम विकल्प, कम लचीलापन। और, कृपया, ध्यान रखें कि यह दशकों पहले है जब उन्होंने ऐसा किया था। बाद में शिकायत करना आसान है ... ;-)
शेफ़

2
सी भाषा में, void *function()एक ऐसा कार्य है जो एक मनमानी संख्या में तर्क देता है और एक मान लौटाता है, जब कि डीएफ़रेड, टाइप प्रकार का होता है । C ++ में, void* function()बिना किसी तर्क के एक फ़ंक्शन होता है और पॉइंटर-टू-शून्य का मान लौटाता है । आपको अपना दिमाग बनाना चाहिए कि आप किस भाषा के बारे में पूछ रहे हैं।
स्टीफन एम। वेब

1
@ StephenM.Webb आप किसी और को नहीं कर सकतेvoid * । आखिरकार, अगर आप भी कर सकते हैं, तो आप क्या करेंगे void?
फैबियो का कहना है कि

जवाबों:


38

फ़ंक्शन का रिटर्न प्रकार है void *

void *function();

इसलिए मैं हमेशा इस तरह के मामलों में पसंद करता हूं कि प्रतीक *को फ़ंक्शन नाम से अलग किया जाए

void * function();

और जैसा Jarod42कि एक टिप्पणी में कहा गया है, आप अनुगामी रिटर्न प्रकार का उपयोग करके C ++ में फ़ंक्शन घोषणा को फिर से लिख सकते हैं

auto function() -> void *;

यदि आप कार्य करने के लिए पॉइंटर घोषित करना चाहते हैं तो आपको लिखना चाहिए

void ( *function )();

या

void * ( *function )();

या कार्य करने के लिए एक सूचक जो कार्य करने के लिए सूचक लौटाता है

void * ( *( *function )() )();

2
इसीलिए, मैं लिखना पसंद करता हूं void* function();। यह मोहक नहीं है ... ;-) (यह लिखते समय संपादन संपादित हुआ।)
Scheff

कोड में मैं घोषणा void * reader();पर तो pthread_create(&thread1,null,reader,reader_arg)बजायpthread_create(&thread1,null,&reader,reader_arg)
user9515151

1
@ शेफ: या यहां तक ​​कि auto function() -> void*(सी ++)। :)
Jarod42

3
या एक सूचक कार्य करने के लिए जो सूचक को कार्य करने के लिए लौटाताtypedef है, जो कि ...;;
एंड्रयू हेनले

1
@AndrewHenle के साथ हमें कोई समस्या नहीं है। एक समस्या तब उत्पन्न होती है जब घोषणाओं को बिना टाइपराइफ या अन्य उपनाम के उपयोग के लिए उपयोग किया जाता है। :)
मॉस्को

7

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

उदाहरण के लिए, मैं आपके उदाहरण का इनपुट करता हूं void *foo()और यह वापस आ गया

शून्य को इंगित सूचक के रूप में शून्य घोषित करें

यह देखने के लिए कि अन्य सिंटैक्स कैसा दिखेगा, मैंने इनपुट किया declare foo as pointer to function returning voidऔर यह वापस आ गया

शून्य (* फू) ()

यह तब विशेष रूप से उपयोगी हो जाता है जब आपके पास एकल अभिव्यक्ति में टाइपकास्ट, सितारे या कोष्ठक के कई स्तर होते हैं।


2

यह एक ऐसा पॉइंटर है जो पॉइंटर को लौटाता है void

इस तरह से अपनी घोषणा के बारे में सोचो:

void *(function());

यह एक लौटाने वाला कार्य होगा void(या कुछ भी नहीं):

void (*function2)();

उपरोक्त घोषणा इस तरह से सोचें:

void ((*function2)());

इनका उपयोग करने के लिए लिखने का एक बहुत आसान तरीका है typedef:

typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();

function_returning_void_pointer function;
function_returning_nothing *function2;

यह आम तौर पर फंक्शन पॉइंटर्स के आस-पास के भ्रम को खत्म करता है और पढ़ने में बहुत आसान है।


0

C / C ++ में घोषणाएं ऑपरेटर की पूर्ववर्ती स्थिति के बाद पहचानकर्ता से पढ़ी जाती हैं ।

विकिपीडिया में C / C ++ ऑपरेटर पूर्वता तालिका पर एक त्वरित नज़र से पता चलता है कि फ़ंक्शन कॉल ऑपरेटर ()में अप्रत्यक्ष ऑपरेटर की तुलना में अधिक पूर्वता है *। तो, आपके फ़ंक्शन की घोषणाएं इस तरह से पढ़ती हैं:

  • पहचानकर्ता पर शुरू करें: functionहै

  • function() एक फ़ंक्शन जो कोई तर्क नहीं लेता है

  • void* function()और वापस आता है void*

यह सामान्य सिद्धांत भी सरणी घोषणाओं ( दोनों की []तुलना में उच्च पूर्वता है *) और दोनों के संयोजन के साथ है। इसलिए

int *(*arr[42])();

के रूप में पढ़ा जाता है

  • arr है
  • arr[42] 42 तत्वों की एक सरणी जो हैं
  • *arr[42] की ओर इशारा करता है
  • (*arr[42])() ऐसे कार्य जो कोई तर्क नहीं लेते हैं और
  • int *(*arr[42])()वापस आ जाओ int*

इसका उपयोग करने में थोड़ा सा समय लगता है, लेकिन एक बार जब आप सिद्धांत को समझ जाते हैं, तो उन घोषणाओं को स्पष्ट रूप से पढ़ना आसान होता है।

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