zestaw2
Transkrypt
zestaw2
IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi
EGZAMIN „PIERWSZY” (25 CZERWCA 2013) – JĘZYK C++
poprawiam ocenę
pozytywną z egzaminu „0”
(zakreśl poniżej x)
1. Wśród poniższych wskaż poprawną formę definicji programu w C++
a) main( ) -> int { }
b) auto [] () -> int { }
c) auto main( ) { }
d) auto main( ) -> int { } // tylko to jest poprawne
e) void main( ) { return 0; }
2. Po wykonaniu fragmentu poniższego kodu, jaka będzie wartość pierwszego elementu w tablicy tab:
int tab[] { 1, 2, 3, 4 };
for (auto i : tab) i = i+1;
Taka sama jak po inicjalizacji, czyli 1 (pętla for pobiera wartość – kopię, więc niczego nie zmienia).
3. Zakładając, że jesteśmy w przestrzeni globalnej, które z poniższych nie jest deklaracją (tzn. jest też
być może również definicją):
a) enum struct Ksztalt;
b) static long n; // definicja
c) extern double d = 0; // definicja, bo inicjalizacja
d) namespace { } // definicja nienazwanej przestrzeni nazw
e) class Foo;
f) extern const int i;
4. Wymień dwa sposoby, na jakie można ograniczyć zasięg (widzialność) danej nazwy do pojedynczej
jednostki translacji.
1) poprzez static (w przestrzeni globalnej)
2) poprzez zamknięcie w nienazwanej przestrzeni nazw
5. Co się stanie w efekcie kompilacji / wykonania poniższego kodu?
void fun(int){ cout << "1" << endl; }
void fun(int*){ cout << "2" << endl; }
void fun(int*&){ cout << "3" << endl; }
void fun(int**){ cout << "4" << endl; }
int main( ) { fun(nullptr); }
Błąd kompilacji z powodu niejednoznaczności wywołania przeciążonych wersji funkcji (2 i 4).
6. Proszę podać jakiego typu jest zmienna a oraz jakiego typu jest zmienna b:
auto a = * new auto ( 0 ); // typu int
decltype( new auto ( 0 ) ) b; // typu int*
1
7. Jaka jest wartość zmiennej a po takich operacjach:
int a = 4;
a ^= a;
Wartość końcowa a wynosi 0 (gdyż ^ to XOR a na samym sobie daje zero, ^= to XOR z
przypisaniem).
8. Uzupełnij miejsca ... w dowolny poprawny sposób:
class Foo { };
class Bar : public Foo { };
// w programie:
Bar b;
auto p = dynamic_cast< Foo& > ( b ) ; // zamiast auto można jawnie napisać Foo&
9. Jak należy zapisać argument funkcji tak, żeby dopuszczalna była tylko 5-elementowa tablica char
void fun( char (&tab) [5] ); // nazwa tab nie jest konieczna w deklaracji
10. Które z poniższych deklaracji funkcji globalnych są niepoprawne:
a) void fun( int, char = 'a', void* = 0 );
b) void fun( int* p = nullptr, int ); // niepoprawne
c) void fun( int a, int b, int = 4 );
d) void fun( void ) const; // niepoprawne, bo w przestrzeni globalnej nie ma funkcji const
e) void fun( auto n = 5 ); // niepoprawne
11. Jaką wartość będzie miała składowa i po utworzeniu obiektu w programie (jak poniżej):
class Foo { public:
int i = 10;
Foo( int i ) : i ( i ) { }
};
// w programie
Foo i(5);
a) 5 // tą wartość
b) 10
c) niezdefiniowaną bo nie wiadomo które i jest wartością inicjalizującą
d) program się nie skompiluje
e) 0
12. Zdefiniowano konstruktor w części prywatnej klasy. Jak wykorzystać go do definicji innych
konstruktorów:
class Foo {
Foo ( int, int, double );
public:
// na przykład:
Foo( ) : Foo ( 0, 0, 0.0 ) { }
Foo( int a ) : Foo ( a, a, 0.0 ) { }
};
2
13. W poniższej klasie zdefiniuj niejawny operator konwersji do typu std::string
class Foo {
const char * ptr;
public:
explicit operator string( ) { return ptr; }
};
14. Wśród poniższych wskaż wszystkie fałszywe twierdzenia:
a) jeśli zdefiniuję konstruktor kopiujący, to nie wygeneruje się automatycznie konstruktor
przenoszący
b) jeśli zdefiniuję konstruktor kopiujący, to nie wygeneruje się automatyczny konstruktor domyślny
c) jeśli zdefiniuję destruktor, to nie wygeneruje się automatyczny konstruktor kopiujący
d) jeśli zdefiniuję konstruktor konwersji, to nie wygeneruje się domyślny konstruktor
e) jeśli zdefiniuję konstruktor konwersji, to nie wygeneruje się automatyczny konstruktor kopiujący
// fałszywe jest e, bo wygeneruje się
15. Dla dowolnego typu T napisz deklarację globalnego operatora przedrostkowego i przyrostkowego
inkrementacji.
przedrostkowy: const T& operator++ ( T& );
przyrostkowy: const T operator++( T&, int );
16. Proszę zdefiniować wskaźnik na składową int poniższej klasy Foo i ustawić na składową a
class Foo {
int a;
};
int Foo::*ptr = &Foo::a;
17. Wskaż wśród poniższych wszystkie fałszywe twierdzenia:
a) operator [] jest operatorem tylko o jednym argumencie
b) operator wyłuskania * musi być metodą składową klasy // fałsz
c) operator odniesienia się na składową -> musi być metodą składową klasy
d) nie można przeciążyć operatora ->* // fałsz
e) operator przecinkowy , można przeciążyć tylko w postaci funkcji globalnej // fałsz
18. W jakiej kolejności uruchamiane będą konstruktory klas w poniższym kodzie (definicje pomijami dla
czytelności, konstruktory są domyślne):
class A;
class B : virtual A;
static A a;
int main( ) {
B b;
A *ptr;
}
Kolejno: A A B (proszę zwrócić uwagę, że A *ptr; niczego nie uruchamia… to tylko wskaźnik).
3
19. Co zostanie wypisane na ekran:
struct Foo { virtual Foo* fun() { cout << "F" << endl; return this; } };
struct Bar : public Foo {
Bar* fun() { cout << "B" << endl; return this; }
int main( ) {
Foo* ptr = new Bar;
ptr->fun(); // B
(*ptr).fun(); // B
}
};
20. Napisz jak utworzyć:
20-elementową tablicę typu char na stercie
char *p = new char[20];
20-elementową tablicę typu void* na stosie
void* tab[20];
21. Zaznacz (kółkiem lub dopisz jeśli czegoś brak)
class Foo {
virtual void fun( ) = 0;
public:
explicit Foo( int );
virtual ~Foo ( int=0 ); // d-tor nie może mieć argumentu
} ; // brak średnika
22. Jest funkcja w postaci:
void fun( initializer_list<int> n );
W jaki sposób należy wywołać taką funkcję, napisz jakiś przykład:
fun ( { 1, 2, 3 } );
23. Co się stanie w poniższym kodzie?
class Foo { public: explicit Foo(int) {} };
class Bar : public Foo { public: using Foo::Foo; };
int main( ) {
Bar b = 7;
}
Błąd kompilacji ze wzgl. na to że konstruktor Foo jest explicit i taka własność jest odziedziczona.
24. Napisz przykład definicji i inicjalizacji kontenera vector dla typu double. Następnie pętlę "po cały
zakresie" (wg nowej składni) wypisującą kolejne elementy na ekran.
vector<double> v { 0., 1.5, 2.8 };
for (auto d : v ) cout << d << endl;
25. Jeśli utworzyliśmy dopiero co kontener map< string, int > to co spowoduje taki zapis:
map["alfa"];
Tak zapis spowoduje utworzenie pary i wstawienie jej do mapy (klucz ”alfa” wartość 0).
4
26. Napisz dla klasy Foo takie deklaracje, które zablokują operacje kopiowania (proszę użyć składni w
tym pomagającej z języka C++11)
class Foo { public:
Foo( const Foo& ) = delete; // blokada konstruktora kopiującego
Foo& operator= (const Foo& ) = delete; // blokada operatora= kopiującego
};
27. Mamy klasę Lambda z przeciążonym operatorem funkcyjnym, napisz dla niej jak wyglądałoby
ekwiwalentne jej wyrażenie Lambda:
class Lambda {
T& t;
public:
Lambda( T& t1 ) : t( t1 ) {}
void operator( )( ) { fun( t ); }
};
[ &t ]() { fun(t); }
28. Napisz deklarację przyjaźni dla operatora >> wyjmowania ze strumienia, dla poniższej klasy
class Foo {
friend std::istream& operator>>( std::istream& s, Foo& f );
};
29. Zdefiniuj i zainicjalizuj dowolną poprawną wartością a
class Foo {
static char a;
};
char Foo::a = 0; // w sumie 0 to domyślna wartość inicjalizacji pola statycznego
30. Klasa Bar dziedziczy prywatnie z klasy Foo. W klasie Foo w części publicznej jest metoda void fun()
const; Co należy napisać i w której części klasy Bar, żeby ta metoda nadal była publiczna.
W części publicznej klasy Bar należy napisać:
using Foo::fun;
31. Dla klasy Foo przeciąż operator new (wystarczy napisanie odpowiedniej deklaracji).
class Foo { public:
void* operator new (size_t s);
};
32. Wymień wszystkie operatory, które można przeciążyć i muszą być składowymi klasy.
operator=
operator()
operator[]
operator->
5
33. Funkcja fun przyjmuje argument przez referencję i zwraca przez referencję. Napisz poprawną
instrukcję zwrotu wewnątrz funkcji, zwracającą to co weszło do niej przez argument
int& fun( int& n ) {
return n;
};
34. Czym w języku c++ różni się klasa od struktury (pod względem pól dostępu, dziedziczenia)?
Różni się tym, że domyślnym polem dostępu w klasie jest private, a w sktrukturze public. Podobnie
domyślnym sposobem dziedziczenia w klasie jest private, a w strukturze public. Domyślnym, tzn.
takim jakie jest gdy się go nie napisze jawnie.
35. Napisz jak wygląda deklaracja main jeżeli chcemy przyjąć jakieś argumenty podczas wywołania
programu.
// oba zapisy są tożsame
int main( int argc, char** argt );
int main( int argc, char* argt[] );
6