सी समारोह में घोषणाकर्ता
सबसे पहले, सी इन सी है, A a()फ़ंक्शन घोषणा है। उदाहरण के लिए, putcharनिम्नलिखित घोषणा है। आम तौर पर, ऐसी घोषणाओं को हेडर फ़ाइलों में संग्रहीत किया जाता है, हालांकि कुछ भी आपको मैन्युअल रूप से लिखने से रोकता है, यदि आप जानते हैं कि फ़ंक्शन की घोषणा कैसे दिखती है। तर्क नाम घोषणाओं में वैकल्पिक हैं, इसलिए मैंने इसे इस उदाहरण में छोड़ दिया।
int putchar(int);
यह आपको इस तरह कोड लिखने की अनुमति देता है।
int puts(const char *);
int main() {
puts("Hello, world!");
}
C आपको उन फ़ंक्शन को परिभाषित करने की अनुमति देता है जो फ़ंक्शन को तर्क के रूप में लेते हैं, अच्छा पठनीय सिंटैक्स के साथ जो फ़ंक्शन कॉल की तरह दिखता है (ठीक है, यह पठनीय है, जब तक आप फ़ंक्शन के लिए एक पॉइंटर वापस नहीं करेंगे)।
#include <stdio.h>
int eighty_four() {
return 84;
}
int output_result(int callback()) {
printf("Returned: %d\n", callback());
return 0;
}
int main() {
return output_result(eighty_four);
}
जैसा कि मैंने उल्लेख किया है, सी हेडर फ़ाइलों में तर्क नामों को छोड़ने की अनुमति देता है, इसलिए output_resultहेडर फ़ाइल में ऐसा दिखेगा।
int output_result(int());
कंस्ट्रक्टर में एक तर्क
क्या आप उस एक को नहीं पहचानते? खैर, आपको याद दिला दूं।
A a(B());
हां, यह बिल्कुल वही फ़ंक्शन घोषणा है। Aहै int, aहै output_resultऔर Bहै int।
आप आसानी से C ++ की नई विशेषताओं के साथ C के संघर्ष को नोटिस कर सकते हैं। सटीक होने के लिए, कन्स्ट्रक्टरों को वर्ग नाम और कोष्ठक के रूप में जाना जाता है, और वैकल्पिक घोषणा सिंटैक्स के ()बजाय =। डिज़ाइन के अनुसार, C ++ C कोड के साथ संगत होने की कोशिश करता है, और इसलिए इसे इस मामले से निपटना पड़ता है - भले ही व्यावहारिक रूप से किसी को परवाह न हो। इसलिए, पुराने C फीचर्स में नए C ++ फीचर्स को प्राथमिकता दी गई है। घोषणाओं के व्याकरण के साथ नए वाक्यविन्यास पर वापस जाने से पहले, नाम को फ़ंक्शन के रूप में मिलान करने की कोशिश करता है() यदि वह विफल हो जाता है।
यदि उन विशेषताओं में से एक मौजूद नहीं होगा, या एक अलग सिंटैक्स था (जैसे {}C ++ 11 में), तो यह समस्या एक तर्क के साथ सिंटैक्स के लिए कभी नहीं हुई होगी।
अब आप पूछ सकते हैं कि A a((B()))काम क्यों करता है। खैर, चलो output_resultबेकार कोष्ठक के साथ घोषणा करते हैं।
int output_result((int()));
यह काम नहीं करेगा। व्याकरण को चर को कोष्ठक में नहीं होने की आवश्यकता होती है।
<stdin>:1:19: error: expected declaration specifiers or ‘...’ before ‘(’ token
हालाँकि, C ++ यहाँ मानक अभिव्यक्ति की उम्मीद करता है। C ++ में, आप निम्न कोड लिख सकते हैं।
int value = int();
और निम्न कोड।
int value = ((((int()))));
C ++ कोष्ठकों के अंदर अभिव्यक्ति की उम्मीद है ... अच्छी तरह से ... अभिव्यक्ति, जैसा कि टाइप सी की उम्मीद है। कोष्ठक यहाँ कुछ भी मतलब नहीं है। हालांकि, बेकार कोष्ठकों को सम्मिलित करके, सी फ़ंक्शन घोषणा से मिलान नहीं किया जाता है, और नए सिंटैक्स को ठीक से मिलान किया जा सकता है (जो कि बस एक अभिव्यक्ति की उम्मीद करता है, जैसे 2 + 2)।
कंस्ट्रक्टर में अधिक तर्क
निश्चित रूप से एक तर्क अच्छा है, लेकिन दो के बारे में क्या? ऐसा नहीं है कि कंस्ट्रक्टरों के पास सिर्फ एक तर्क हो सकता है। अंतर्निहित कक्षाओं में से एक जो दो तर्क लेता हैstd::string
std::string hundred_dots(100, '.');
यह सब ठीक है और ठीक है (तकनीकी रूप से, यह सबसे अधिक डरावनी तोता होगा यदि इसे इस रूप में लिखा जाएगा std::string wat(int(), char()), लेकिन चलो ईमानदार होंगे - जो इसे लिखेंगे? लेकिन मान लें कि इस कोड में एक समस्या है। आप मान लेंगे कि आपको डालनी होगी। कोष्ठक में सब कुछ।
std::string hundred_dots((100, '.'));
ऐसा बिलकुल नहीं है।
<stdin>:2:36: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
In file included from /usr/include/c++/4.8/string:53:0,
from <stdin>:1:
/usr/include/c++/4.8/bits/basic_string.tcc:212:5: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-fpermissive]
basic_string<_CharT, _Traits, _Alloc>::
^
मुझे यकीन नहीं है कि क्यों जी ++ में बदलने की कोशिश करता charहै const char *। किसी भी तरह से, निर्माता को केवल एक प्रकार के मूल्य के साथ बुलाया गया था char। कोई अधिभार नहीं है जिसके पास एक प्रकार का तर्क है char, इसलिए संकलक भ्रमित है। आप पूछ सकते हैं - तर्क टाइप चार का क्यों है?
(100, '.')
हाँ, ,यहाँ एक अल्पविराम ऑपरेटर है। अल्पविराम ऑपरेटर दो तर्क लेता है, और दाईं ओर तर्क देता है। यह वास्तव में उपयोगी नहीं है, लेकिन यह मेरे स्पष्टीकरण के लिए जाना जाने वाला कुछ है।
इसके बजाय, सबसे अधिक डरावने पार्स को हल करने के लिए, निम्न कोड की आवश्यकता है।
std::string hundred_dots((100), ('.'));
तर्क कोष्ठकों में हैं, संपूर्ण अभिव्यक्ति में नहीं। वास्तव में, अभिव्यक्तियों में से केवल एक को कोष्ठक में होना आवश्यक है, क्योंकि सी ++ की सुविधा का उपयोग करने के लिए सी व्याकरण से थोड़ा तोड़ना पर्याप्त है। चीजें हमें शून्य तर्क के बिंदु पर लाती हैं।
कंस्ट्रक्टर में शून्य तर्क
आपने eighty_fourमेरे स्पष्टीकरण में फ़ंक्शन को देखा होगा ।
int eighty_four();
जी हां, यह सबसे ज्यादा डरावने तोते से भी प्रभावित होता है। यह एक मान्य परिभाषा है, और यदि आपने हेडर फ़ाइलें (और आपको चाहिए) बनाई हैं, तो आपको सबसे अधिक संभावना है। कोष्ठक जोड़ना इसे ठीक नहीं करता है।
int eighty_four(());
ऐसा क्यों हैं? खैर, ()एक अभिव्यक्ति नहीं है। सी ++ में, आपको कोष्ठक के बीच एक अभिव्यक्ति डालनी होगी। आप auto value = ()C ++ में नहीं लिख सकते हैं , क्योंकि ()इसका मतलब कुछ भी नहीं है (और अगर किया भी है, जैसे कि खाली ट्यूपल (पायथन देखें), यह एक तर्क होगा, शून्य नहीं)। व्यावहारिक रूप से इसका मतलब है कि आप C ++ 11 के {}सिंटैक्स का उपयोग किए बिना शॉर्टहैंड सिंटैक्स का उपयोग नहीं कर सकते हैं , क्योंकि कोष्ठक में डालने के लिए कोई अभिव्यक्ति नहीं है, और फ़ंक्शन घोषणाओं के लिए सी व्याकरण हमेशा लागू होगा।
(B())बस एक C ++ अभिव्यक्ति है, और कुछ नहीं। यह किसी भी तरह का अपवाद नहीं है। एकमात्र अंतर जो यह बनाता है कि कोई तरीका नहीं है कि इसे संभवतः एक प्रकार के रूप में पार्स किया जा सकता है, और इसलिए यह नहीं है।