क्या आप प्रोग्रामिंग के C और C++ की शानदार दुनिया में शामिल होने के लिए तैयार हैं? क्या आप C++ की कुछ सरल पंक्तियों के बाद अपने अस्तित्व पर सवाल उठाना चाहते हैं? यदि आपका उत्तर "हाँ!", "हाँ" या "क्यों नहीं?" है - तो अपने ज्ञान का परीक्षण करने के लिए आपका स्वागत है। आपको C या C++ से संबंधित कई प्रश्न दिए जाएँगे। कृपया कहानी के अंत में सही उत्तर और स्पष्टीकरण पाएँ। शुभकामनाएँ! 1. सबसे छोटा कार्यक्रम main; यदि आप इस प्रोग्राम को C कम्पाइलर का उपयोग करके संकलित करने का प्रयास करेंगे तो क्या होगा? संकलित नहीं होगा संकलित होगा, लिंक नहीं होगा संकलित करेगा और लिंक करेगा 2. कांटा #include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); } यह प्रोग्राम कितनी लाइनें प्रिंट करेगा? 1000 1000 से कम 1000 से अधिक 3. आपको बस सूचकांक की जरूरत है #include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; } यह प्रोग्राम क्या प्रिंट करेगा? 1 2 3 4 संकलित नहीं होगा अपरिभाषित 4. नियमित अभिव्यक्ति #include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; } इस नियमित अभिव्यक्ति को इस इनपुट स्ट्रिंग से मेल खाने में कितना समय लगेगा? 1 मि.से. 1 सेकंड 1 मिनट 1 घंटा 1 वर्ष हमेशा के लिए 5. चालें और लैम्ब्डा #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(Foo&&) { std::cout << "Foo(Foo&&)\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } }; int main() { Foo f; auto a = [f = std::move(f)]() { return std::move(f); }; Foo f2(a()); return 0; } इस प्रोग्राम द्वारा मुद्रित की जाने वाली अंतिम पंक्ति है... Foo() Foo(Foo&&) Foo(const Foo&) 6. एक्स और बार #include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; } यह प्रोग्राम क्या प्रिंट करेगा? 0 1 0x0 संकलित नहीं होगा लिंक नहीं होगा 7. कंस्ट्रक्टर्स #include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } Foo(int) { std::cout << "Foo(int)\n"; } Foo(int, int) { std::cout << "Foo(int, int)\n"; } Foo(const Foo&, int) { std::cout << "Foo(const Foo&, int)\n"; } Foo(int, const Foo&) { std::cout << "Foo(int, const Foo&)\n"; } }; void f(Foo) {} struct Bar { int i, j; Bar() { f(Foo(i, j)); f(Foo(i)); Foo(i, j); Foo(i); Foo(i, j); } }; int main() { Bar(); } इस प्रोग्राम द्वारा मुद्रित की जाने वाली अंतिम पंक्ति है... Foo(int, int) Foo(const Foo&, int) Foo(int, const Foo&) Foo(int) निष्कर्ष के बजाय मुझे आशा है कि आपको जंगल में इस तरह का कोई विचित्र टुकड़ा कभी नहीं मिलेगा। जवाब सबसे छोटा कार्यक्रम यह वैध C कोड है। यदि आप इसे चलाने का प्रयास करेंगे तो यह क्रैश हो जाएगा। - वैश्विक चर है। यह सफलतापूर्वक संकलित और लिंक होगा। main; सी कोड में आप बहुत सी चीजों को छोड़ सकते हैं। उदाहरण के लिए आप किसी ग्लोबल वैरिएबल के प्रकार को छोड़ सकते हैं। डिफ़ॉल्ट रूप से कंपाइलर यह मान लेगा कि यह प्रकार है। साथ ही सी में कोई नहीं है (सी++ के विपरीत), इसलिए लिंक करते समय वैरिएबल फ़ंक्शन से अलग करने का कोई तरीका नहीं है। int नाम मैन्गलिंग main main इस प्रकार कंपाइलर वैध कोड संकलित करेगा, और लिंकर प्रोग्राम को लिंक करने के लिए ऑब्जेक्ट फ़ाइल में नाम की कोई चीज़ ढूंढेगा। main कांटा यह C या C++ फीचर की बजाय POSIX फीचर है। IO ऑपरेशन के कार्यान्वयन प्रदर्शन को अनुकूलित करने के लिए बफ़र्स का उपयोग करते हैं। जब आप आह्वान करते हैं, तो OS प्रक्रिया मेमोरी की कॉपी-ऑन-राइट डुप्लिकेट बनाएगा, IO-बफ़र्स भी संभवतः डुप्लिकेट होंगे और बफ़र किए गए स्ट्रिंग्स । fork संभवतः 1000 से अधिक बार प्रिंट किए जाएंगे आपको बस सूचकांक की जरूरत है उत्तर 3 है इस कोड को समझने के लिए आइए देखें कि C और C++ में इंडेक्स कैसे काम करते हैं: , के समान है, के समान है और . array[index] *(array + index) (index + array) index[array दूसरा सुराग ऑपरेटर है इसका बाइनरी ऑपरेटर, यह बाएं तर्क को त्याग देता है और दाएं तर्क को वापस करता है। , नियमित अभिव्यक्ति यह है कि क्या होगा! व्यवहार कार्यान्वयन पर निर्भर है। भविष्यवाणी करना असंभव मेरे परिवेश में यह प्रोग्राम अपवाद उत्पन्न करता है The complexity of an attempted match against a regular expression exceeded a pre-set level. अन्य संभावित विकल्प आश्चर्यजनक रूप से लंबे समय तक चलने वाले या अपेक्षित रूप से काम करने वाले हैं। ऐसा इसलिए है क्योंकि नियमित अभिव्यक्तियों को लागू करने के दो संभावित तरीके हैं। पहला - नियमित अभिव्यक्तियों को परिमित ऑटोमेटा (n - पैटर्न की लंबाई) में बदलें, स्ट्रिंग (m - स्ट्रिंग की लंबाई) से मिलान करें। यह दृष्टिकोण O(n**2) O(m) बैकट्रैकिंग का समर्थन नहीं करता है। दूसरा - लालची दृष्टिकोण + DFS, बैकट्रैकिंग का समर्थन करता है लेकिन कुछ पैटर्न पर घातीय समय जटिलता के लिए प्रवण है। चालें और लैम्ब्डा उत्तर है । लैम्ब्डा डिफ़ॉल्ट रूप से अपरिवर्तनीय होते हैं, के साथ लैम्ब्डा में कैप्चर किए गए सभी मान अंतर्निहित रूप से होते हैं। यह लैम्ब्डा के लिए व्यवहार को अनलॉक करता है। Foo(const Foo&) [] const idempotent जब आप स्थानांतरित करते हैं तो आप बनाते हैं। एक अजीब प्रकार है, इसलिए कंपाइलर बस प्रतिलिपि बनाता है f const Foo&& const Foo&& Foo इसे ठीक करने के दो तरीके हैं: परिवर्तनीय लैम्ब्डा बनाएं auto a = [f = std::move(f)]() mutable { return std::move(f); }; कन्स्ट्रक्टर घोषित करें Foo(const Foo&&) एक्स और बार प्रिंट करेगा. प्रोग्राम 1 — फ़ंक्शन घोषित करने का अजीब तरीका है, यह के बराबर है। int bar(int(x)); int bar(int x); यदि आप टाइप कास्ट से भ्रमित हैं, - यह टाइप कास्ट है। int bar((int(x))); फिर हम फ़ंक्शन पते को में निहित रूप से डालने का प्रयास करते हैं, ऐसे डालने का परिणाम हमेशा है। bool true फ़ंक्शन कभी भी उपयोग नहीं किया गया है, जो हमें लिंक करते समय अप्रतिबंधित प्रतीक त्रुटि से बचने की अनुमति देता है। bar() कंस्ट्रक्टर्स अंतिम पंक्ति है। Foo(const Foo&, int) एक चर घोषणा है, जो के समान है। इस प्रकार नाम के अंतर्गत वर्ग सदस्य इस दायरे में छिपा हुआ है। Foo(i) Foo i i