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!
main;
Bu programı C derleyicisini kullanarak derlemeye çalışırsanız ne olur?
#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?
#include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; }
Bu program ne yazdıracak?
#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?
#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&)
#include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; }
Bu program ne yazdıracak?
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(); }
Bu program tarafından yazdırılacak son satır…
Foo(int, int)
Foo(const Foo&, int)
Foo(int, const Foo&)
Foo(int)
Umarım bu tuhaf parçalardan birini doğada asla bulamazsınız.
En küçük program
Bu yasal bir C kodudur. Derlenecek ve başarıyla bağlanacaktır. Çalıştırmaya çalışırsanız çökecektir. main;
- global değişkendir.
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 int
olduğunu varsayacaktır. Ayrıca C'de isim karıştırma yoktur (C++'ın aksine), bu yüzden bağlantı yaparken değişken main
fonksiyon main
ayırmanın bir yolu yoktur.
Böylece derleyici geçerli kodu derleyecek ve bağlayıcı, programı bağlamak için nesne dosyasında main
adında bir şey bulacaktır.
Ç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. fork
ç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 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: array[index]
, *(array + index)
ile aynıdır, (index + array)
ile aynıdır ve index[array
] ile aynıdır.
İ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ı tahmin etmek imkansız ! Davranış uygulamaya bağlıdır.
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 O(n**2)
(n - desen uzunluğu), dizeyi eşleştirin O(m)
(m - dize uzunluğu). Bu yaklaşı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 Foo(const Foo&)
'dur. Lambdalar varsayılan olarak değişmezdir, lambdaya []
ile yakalanan tüm değerler örtük olarak const
. Bu, lambdalar için idempotent davranışı açar.
f
hareket ettirdiğinizde const Foo&&
oluşturursunuz. const Foo&&
garip bir türdür, bu nedenle derleyici sadece Foo
kopyalar
Bunu düzeltmenin iki yolu vardır:
Değişken lambda oluştur
auto a = [f = std::move(f)]() mutable { return std::move(f); };
Foo(const Foo&&)
yapıcısını bildirin
X ve çubuk
Program 1
değerini yazdıracaktır.
int bar(int(x));
— fonksiyonu bildirmenin garip bir yoludur, int bar(int x);
ile aynıdır.
Eğer tip dönüşümü ile karıştırdıysanız, int bar((int(x)));
- bu bir tip dönüşümüdür.
Daha sonra address fonksiyonunu dolaylı olarak bool
türüne dönüştürmeye çalışırız, böyle bir dönüştürmenin sonucu her zaman true
olur.
bar()
fonksiyonu hiç kullanılmadı, bu sayede bağlantı sırasında referans alınmayan sembol hatalarından kaçınabiliyoruz.
Yapıcılar
Son satır Foo(const Foo&, int)
şeklindedir.
Foo(i)
, Foo i
ile aynı olan değişken bildirimidir. Bu nedenle, i
adlı sınıf üyesi bu kapsamda gizlidir.