Programlamanın C ve C++'ın görkemli dünyasına katılmaya hazır mısınız? Birkaç basit C++ satırından sonra varlığınızı sorgulamak ister misiniz? Cevabınız "Evet!", "Evet" veya "Neden olmasın?" ise - bilginizi test etmeye hoş geldiniz. C veya C++ ile ilgili birden fazla soru sorulacaktır. Doğru cevapları ve açıklamaları hikayenin sonunda bulabilirsiniz. İyi şanslar! 1. En küçük program main; Bu programı C derleyicisini kullanarak derlemeye çalışırsanız ne olur? derlenmeyecek derlenecek, bağlanmayacak derleyecek ve bağlayacak 2. Çatal #include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); } Bu program kaç satır yazdıracak? 1000 1000'den az 1000'den fazla 3. İhtiyacınız olan tek şey endeksler #include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; } Bu program ne yazdıracak? 1 2 3 4 derlenmeyecek tanımlanmamış 4. Düzenli ifadeler #include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; } Bu düzenli ifadenin bu girdi dizesiyle eşleşmesi ne kadar zaman alacak? 1 ms 1 saniye 1 dk 1 saat 1 yıl sonsuza kadar 5. Hareketler ve lambdalar #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; } Bu program tarafından yazdırılacak son satır… Foo() Foo(Foo&&) Foo(const Foo&) 6. X ve çubuk #include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; } Bu program ne yazdıracak? 0 1 0x0 derlenmeyecek Bağlantı olmayacak 7. Yapıcılar #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(); } Bu program tarafından yazdırılacak son satır… Foo(int, int) Foo(const Foo&, int) Foo(int, const Foo&) Foo(int) Sonuç yerine Umarım bu tuhaf parçalardan birini doğada asla bulamazsınız. Cevaplar En küçük program Bu yasal bir C kodudur. Çalıştırmaya çalışırsanız çökecektir. - global değişkendir. Derlenecek ve başarıyla bağlanacaktır. main; C kodunda birçok şeyi atlayabilirsiniz. Örneğin, global bir değişkenin türünü atlayabilirsiniz. Varsayılan olarak derleyici bu türün bir olduğunu varsayacaktır. Ayrıca C'de yoktur (C++'ın aksine), bu yüzden bağlantı yaparken değişken fonksiyon ayırmanın bir yolu yoktur. int isim karıştırma main main Böylece derleyici geçerli kodu derleyecek ve bağlayıcı, programı bağlamak için nesne dosyasında adında bir şey bulacaktır. main Çatal Bu, C veya C++ özelliğinden ziyade daha çok POSIX özelliğidir. IO işlemlerinin uygulamaları performansı optimize etmek için tamponları kullanır. çağırdığınızda, işletim sistemi işlem belleğinin yazma sırasında kopyasını oluşturur, IO tamponları da muhtemelen kopyalanır ve tamponlanmış dizeler . fork muhtemelen 1000'den fazla kez yazdırılır İhtiyacınız olan tek şey endeksler Cevap 3'tür Bu kodu anlamak için C ve C++'da dizinlerin nasıl çalıştığına daha yakından bakalım: , ile aynıdır, ile aynıdır ve ] ile aynıdır. array[index] *(array + index) (index + array) index[array İkinci ipucu ise operatör 'dir. İkili operatörüdür, sol argümanı atar ve sağ argümanı döndürür. , Düzenli ifadeler Ne olacağını ! Davranış uygulamaya bağlıdır. tahmin etmek imkansız Benim çevremde bu program The complexity of an attempted match against a regular expression exceeded a pre-set level. Diğer olası seçenekler şaşırtıcı derecede uzun zaman veya beklendiği gibi çalışmaktır. Bunun nedeni, düzenli ifadeleri uygulamak için iki olası yaklaşım olmasıdır. İlk olarak - düzenli ifadeleri sonlu otomatlara dönüştürün (n - desen uzunluğu), dizeyi eşleştirin (m - dize uzunluğu). Bu yaklaşım O(n**2) O(m) geri izlemeyi desteklemez. İkincisi - açgözlü yaklaşım + DFS, geri izlemeyi destekler ancak belirli desenlerde üstel zaman karmaşıklığına eğilimlidir. Hareketler ve lambdalar Cevap 'dur. Lambdalar varsayılan olarak değişmezdir, lambdaya ile yakalanan tüm değerler örtük olarak . Bu, lambdalar için davranışı açar. Foo(const Foo&) [] const idempotent hareket ettirdiğinizde oluşturursunuz. garip bir türdür, bu nedenle derleyici sadece kopyalar f const Foo&& const Foo&& Foo Bunu düzeltmenin iki yolu vardır: Değişken lambda oluştur auto a = [f = std::move(f)]() mutable { return std::move(f); }; yapıcısını bildirin Foo(const Foo&&) X ve çubuk değerini yazdıracaktır. Program 1 — fonksiyonu bildirmenin garip bir yoludur, ile aynıdır. int bar(int(x)); int bar(int x); Eğer tip dönüşümü ile karıştırdıysanız, - bu bir tip dönüşümüdür. int bar((int(x))); Daha sonra address fonksiyonunu dolaylı olarak türüne dönüştürmeye çalışırız, böyle bir dönüştürmenin sonucu her zaman olur. bool true fonksiyonu hiç kullanılmadı, bu sayede bağlantı sırasında referans alınmayan sembol hatalarından kaçınabiliyoruz. bar() Yapıcılar Son satır şeklindedir. Foo(const Foo&, int) , ile aynı olan değişken bildirimidir. Bu nedenle, adlı sınıf üyesi bu kapsamda gizlidir. Foo(i) Foo i i