क्या आप प्रोग्रामिंग के C और C++ की शानदार दुनिया में शामिल होने के लिए तैयार हैं? क्या आप C++ की कुछ सरल पंक्तियों के बाद अपने अस्तित्व पर सवाल उठाना चाहते हैं?
यदि आपका उत्तर "हाँ!", "हाँ" या "क्यों नहीं?" है - तो अपने ज्ञान का परीक्षण करने के लिए आपका स्वागत है। आपको C या C++ से संबंधित कई प्रश्न दिए जाएँगे।
कृपया कहानी के अंत में सही उत्तर और स्पष्टीकरण पाएँ। शुभकामनाएँ!
main;
यदि आप इस प्रोग्राम को C कम्पाइलर का उपयोग करके संकलित करने का प्रयास करेंगे तो क्या होगा?
#include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); }
यह प्रोग्राम कितनी लाइनें प्रिंट करेगा?
#include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; }
यह प्रोग्राम क्या प्रिंट करेगा?
#include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; }
इस नियमित अभिव्यक्ति को इस इनपुट स्ट्रिंग से मेल खाने में कितना समय लगेगा?
#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&)
#include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; }
यह प्रोग्राम क्या प्रिंट करेगा?
0
1
0x0
#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 ऑपरेशन के कार्यान्वयन प्रदर्शन को अनुकूलित करने के लिए बफ़र्स का उपयोग करते हैं। जब आप fork
आह्वान करते हैं, तो OS प्रक्रिया मेमोरी की कॉपी-ऑन-राइट डुप्लिकेट बनाएगा, IO-बफ़र्स भी संभवतः डुप्लिकेट होंगे और बफ़र किए गए स्ट्रिंग्स संभवतः 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.
अन्य संभावित विकल्प आश्चर्यजनक रूप से लंबे समय तक चलने वाले या अपेक्षित रूप से काम करने वाले हैं। ऐसा इसलिए है क्योंकि नियमित अभिव्यक्तियों को लागू करने के दो संभावित तरीके हैं।
पहला - नियमित अभिव्यक्तियों को परिमित ऑटोमेटा O(n**2)
(n - पैटर्न की लंबाई) में बदलें, स्ट्रिंग O(m)
(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
नाम के अंतर्गत वर्ग सदस्य इस दायरे में छिपा हुआ है।