• Nie Znaleziono Wyników

Pytania i odpowiedzi (kolor czerwony) wraz z krótką motywacją. EGZAMIN PROGRAMOWANIE II (10 września 2010)

N/A
N/A
Protected

Academic year: 2022

Share "Pytania i odpowiedzi (kolor czerwony) wraz z krótką motywacją. EGZAMIN PROGRAMOWANIE II (10 września 2010)"

Copied!
8
0
0

Pełen tekst

(1)

Pytania i odpowiedzi (kolor czerwony) wraz z krótką motywacją.

EGZAMIN PROGRAMOWANIE II (10 września 2010)

1. Funkcji programu int main(); w zasadzie nie trzeba deklarować. W jakim przypadku taka deklaracja poprzedzająca jej definicję musiałaby jednak wystąpić? Krótko opisz.

Odpowiedź:

W przypadku gdybyśmy chcieli w jakiejś klasie zadeklarować przyjaźń z funkcją main(), to jeśli definicja klasy poprzedzałaby definicję programu, konieczna by była deklaracja.

2. Jakie warunki musi spełniać funkcja, żeby jej wywołanie dawało tzw. lewą-wartość (ang. l-value):

Odpowiedź: Funkcja musi zwracać referencję.

3. Co się stanie dla poniższego kawałka kodu (interesujący fragment):

int val = int() = 5;

std::cout << val << std::endl;

a. wypisze się wartość 5 b. wypisze się wartość 0

c. nie skompiluje się ♦ int() tworzy obiekt tymczasowy, a te są „prawymi-wartościami” czyli nie można do nich nic przypisać

d. wynik jest niezdefiniowany 4. Mamy następujący kawałek kodu:

struct A { }; struct B { }; // typy A i B niezwiązane ze sobą int main() { A *ptr = new A;

B *b1 = ptr; // linia 1

B *b2 = static_cast< B* > ( ptr ); // linia 2 B *b3 = dynamic_cast< B* > ( ptr ); // linia 3 B *b3 = reinterpret_cast< B* > ( ptr ); // linia 4 B *b4 = const_cast< B* > ( ptr ); // linia 5 }

Proszę wypisać linie (numeracja w komentarzach kodu), które nie mogą się skompilować.

Odpowiedź: Tylko reinterpret_cast pozwala na przekształcanie niezwiązanych ze sobą typów obiektów, czyli nie skompilują się linie: 1, 2, 3 i 5.

5. Dodatkowo oprócz operatora const_cast, który z operatorów można jeszcze użyć aby pozbyć się w rzutowaniu przydomka const :

a. static_cast b. dynamic_cast c. reinterpret_cast

d. żaden z powyższych ♦ tylko const_cast (lub ewentualnie rzutowanie „w stylu C”) może być użyte do pozbawienia przydomka const

6. Co należy wpisać w pustym (wykropkowanym) polu, aby poniższy kod był poprawny?

int M = 2;

class M { };

int main() {

.... class ... M var;

}

Komentarz: należy wpisać słowo kluczowe class. Można mieć równocześnie zmienną i klasę o tej samej nazwie, ale nazwa klasy jest ukryta, aby jej użyć jako typu wymagane jest właśnie jawne podanie class (to pytanie można uznać za trudne, ale czasem wypada zapytać o coś nietrywialnego...).

(2)

7. Skoro mamy strukturę: struct A { static int a; };

to jaki kod należy jeszcze napisać, aby zdefiniować zmienną a ?

Odpowiedź: należy oczywiście napisać: int A::a; gdyż deklaracja składowej statycznej nie jest jej definicją – ta musi mieć miejsce poza ciałem klasy.

8. Oprócz rzutowania „w stylu C”, który z poniżej podanych sposobów umożliwi rzutowanie obiektu typu int na typ enum (wyliczeniowy):

a. static_cast ♦ tylko static_cast umożliwia takie rzutowanie b. dynamic_cast

c. reinterpret_cast

d. static_cast lub reinterpret_cast e. żaden z powyższych

9. Czy zmienna x jest dostępna w bloku else poniższego wyrażenia? Proszę o krótką motywację odpowiedzi.

if ( argc > 2 ) { // fragment jakiegoś kodu int x = 4;

} else { }

Odpowiedź:

Zmienna x nie jest dostępna w bloku else, gdyż jest zmienną utworzoną lokalnie w innym bloku.

10. W dodatku do rzutowania „w stylu C”, jak jeszcze można rzutować int na wskaźnik lub wskaźnik na int:

a. static_cast b. dynamic_cast

c. reinterpret_cast ♦ tylko reinterpret_cast d. żadne z powyższych

11. Które z linii poniższego kodu (numeracja linii w komentarzach kodu) spowoduje niezdefiniowane zachowanie się programu?

class A { public: virtual ~A() {} };

struct B : A { };

int main() {

A *ptr = new B;

delete ptr; // linia 1 ptr = 0;

delete ptr; // linia 2 A *ptr2 = new B[7];

delete [] ptr2; // linia 3 ptr2 = 0;

delete ptr2; // linia 4 }

a. żadna z linii b. linia 1 c. linia 2

d. linia 3 ♦ usuwanie tablicy obiektów za pomocą wskaźnika do typu bazowego daje niezdefiniowane zachowanie. delete na zerowym wskaźniku (linie 1, 3) nie ma żadnego efektu, zaś usuwanie (linia 2) wskaźnika typu bazowego, pokazującego na typ pochodny jest poprawne, o ile w typie bazowym zdefiniowano wirtualny destruktor

e. linia 4

(3)

12. Począwszy od linii zaznaczonej komentarzem / *** / w poniższym kodzie, które etykiety są osiągalne za pomocą wyrażenia goto ?

void fun( int x ) { labelA:

/ *** od tego miejsca patrząc ***/

labelB:

labelC:

}

int main() { fun ( 5 );

labelD:

}

a. labelA, labelB, labelC, labelD

b. labelA, labelB, labelC ♦ etykiety mają zakres całej funkcji, są osiągalne z dowolnego jej miejsca ale tylko wewnątrz danej funkcji, nie są osiągalne etykiety zdefiniowane wewnątrz innej funkcji c. labelB, labelC

d. labelB, labelC, labelD

13. Co robi taka linijka kodu: extern int a = 5;

Odpowiedź: w przypadku deklaracji extern oraz inicjalizacji zmiennej, oznacza to także definicję zmiennej (która będzie łączona zewnętrznie).

14. Jaka jest ewentualnie wartość lokalnej zmiennej val na koniec programu?

int val = 7;

int main() { int val = val; } a. 0

b. 7

c. niezdefiniowana ♦ lokalna zmienna val wewnątrz main() zasłania globalną zmienną val zanim nastąpi (lokalna) inicjalizacja tej zmiennej. Tym samym, inicjalizuje się ona samą sobą, zatem wartością przypadkową.

d. takie przypisanie jest niedozwolone, program się nie skompiluje

15. Jaka jest wartość zmiennej y na końcu programu (można przyjąć, że wielkość int to 4) const int x = 4;

int main() { int x [ x ];

int y = sizeof ( x ) / sizeof ( int );

}

a. 0

b. 4 ♦ lokalna zmienna x nie zasłania globalnej aż do końca deklaracji. Po zakończeniu deklaracji (ale jeszcze przed inicjalizacją) lokalna zmienna zasłania globalną o tej samej nazwie. Tu mamy deklarację (definicję zarazem) tablicy, czteroelementowej, int-ów, czyli jej rozmiar 16 podzielony przez rozmiar int 4, daje 4.

c. 16

d. niezdefiniowana

16. Czy w przestrzeni nazw Abrakadabra funkcja fun() ma dostęp do zmiennej x, również zdeklarowanej w tej samej przestrzeni? Odpowiedź krótko umotywuj.

namespace Abrakadabra { void fun() { x++; } int x;

}

Odpowiedź: nie, ponieważ nazwy używane w przestrzeni nazw muszą być zadeklarowane przed ich użyciem.

(4)

17. Które z poniższych zmiennych są dostępne w bloku obsługi wyjątku (czyli catch) poniższej funkcji ? void fun( int a ) try {

int b = 3;

throw 1;

} catch ( int c ) { /* co jest dostępne tutaj? */ } a. a, b, c

b. a, c ♦ parametry funkcji są dostępne, ale jej lokalne zmienne nie są (odwikłanie stosu przed przejściem do obsługi wyjatku)

c. b, c d. c

18. W jakim zakresie linii (numeracja pomocnicza po lewej stronie kodu), dostępna jest zmienna x ? 1 int main( int argc, char** argv )

2 {

3 if ( argc > 10 ) 4 {

5 }

6 else if ( int x = argc – 1 ) 7 {

8 } 9 else 10 { 11 }

12 return 0;

13 }

a. linie 3 – 11 b. linie 3 – 12 c. linie 6 – 8

d. linie 6 – 11 ♦ zmienne zdeklarowane wewnątrz wyrażeń warunkowych if, else-if, są dostępne od miejsca definicji do końca danej składni if... else-if...else, zarówno w części warunku jak i wewnątrz bloków

e. linie 6 – 12

19. Jaką wartość wydrukuje metoda print() ? Poniżej fragment kodu:

const int SIZE = 2;

class Foo { public:

void print() { cout << SIZE << endl; } enum { SIZE = 3 };

};

int main() { Foo obj;

obj.print();

} a. 2

b. 3 ♦ nazwy zdefiniowane wewnątrz klasy mają zasięg całej klasy, także wewnątrz jej składowych metod, zatem nazwa SIZE z nienazwanego typu wyliczeniowego jest dostępna w metodzie print() i przesłania globalną zmienną SIZE

c. niezdefiniowaną

d. program się nie skompiluje ze względu na kolizję nazw

(5)

20. Jaką wartość zmiennej x zobaczymy wewnątrz programu?

int x;

int main() { int y;

cout << x << endl;

cout << y << endl;

}

Odpowiedź: 0, ponieważ zmienne o czasie życia pamięci statycznej są inicjalizowane zerem. Tu jest to zmienna globalna. Notabene, y będzie miało wartość losową (ale nie o tym jest pytanie).

21. Które z poniższych linii fragmentu programu, nie skompilują się (numeracja podana w komentarzu kodu):

int a[54] = { 0 }; // linia 1 int b[12] = { }; // linia 2 int *x = a; // linia 3 int * const y = a; // linia 4 b = x; // linia 5 b = y; // linia 6 Odpowiedź:

Linia 5 i 6, gdyż nie istnieje domyślna (niejawna) konwersja wskaźników na tablice.

22. Czy w poniższym kawałku kodu zobaczymy wydruk ”Hello” na ekranie?

int tablica[33];

if ( &tablica[3] < &tablica[13] ) { cout << ”Hello” << endl;

}

a. tak ♦ ponieważ porównanie wskaźników za pomocą operatorów „mniejszy niż”, „większy niż” itd. jest wewnątrz tej samej tablicy zdefiniowane

b. nie

c. zależne od implementacji w kompilatorze d. niezdefiniowane

23. Proszę wymienić dwie najsilniejsze w języku C++ relacje wiążące typy ze sobą.

Odpowiedź:

Najsilniejszy związek to przyjaźń, następnie dziedziczenie.

24. Co się stanie w przypadku poniższego kodu:

class A {}; class B {};

int main() {

A *ptr1 = new A;

B *ptr2 = new B;

if ( ptr1 < ptr2 ) cout << ”MNIEJSZE” << endl;

else cout << ”WIĘKSZE” << endl;

}

a. wydrukuje się słowo MNIEJSZE b. wydrukuje się słowo WIĘKSZE

c. nie da się z góry określić, zależy gdzie w pamięci ulokowane zostaną obiekty A i B

d. program się nie skompiluje♦ ponieważ nie można badać relacji pomiędzy osobnymi wskaźnikami różnych typów (operatory porównania takich wskaźników nie istnieją).

(6)

25. Jaka wartość będzie wydrukowana na ekranie?

int x = 0;

int y = 0;

if ( x++ && y++ ) { y += 2;

}

cout << x + y << endl;

a. 1 ♦ w przypadku stwierdzenia wartości 0 w pierwszym argumencie operatora koniunkcji && drugi argument w ogóle nie jest sprawdzany (tym samym, nie jest obliczany). Ponieważ x jest inicjalizowane zerem, więc oczywiście warunek if nie jest spełniony. Na końcu mamy więc x powiększone o 1

(postinkrementacja) i y o wartości z inicjalizacji czyli 0, co w sumie daje 1.

b. 2 c. 3 d. 4

e. niezdefiniowane

26. Jaka wartość zostanie wydrukowana w poniższym programie?

struct Alpha { int x;

operator int() { return 5; } };

int main() { Alpha m;

m.x = 6;

cout << ( 0 ? 4 : 5 - m ) << endl;

}

a. 0 ♦ musi zajść konwersja dostosowująca zmienną do typu wyrażenia arytmetycznego, w tym przypadku do typu int i dzieje się to za pomocą operatora konwersji. Wynik to rezultat 5 – m czyli po konwersji 5 – 5 = 0

b. 4 c. 5 d. 6 e. –1

27. Jaka wartość się wydrukuje?

int main() { int x;

x = 3, 2, 1;

cout << x << endl;

} a. 1 b. 2

c. 3 ♦ ponieważ operator = ma wyższy priorytet niż operator przecinkowy , (który ma tak nawiasem mówiąc, najniższy priorytet ze wszystkich operatorów). Czyli wyrażenie x = 3, 2, 1; jest obliczane w ten sposób, że najpierw następuje przypisanie x = 3, a następnie ewaluacja wyrażeń z operatorem przecinkowym (co już nie ma znaczenia dla wartości x) – wartość wyrażenia x, 2, 1 to 1.

d. 6

e. niezdefiniowane

(7)

28. Ile razy wydrukuje się w poniższym kodzie ”OK” ? class Base { public:

Base() { cout << ”OK” << endl; } int skladnik;

};

struct A : virtual public Base {};

struct B : virtual Base {};

struct C : public Base {};

struct D : Base {};

struct Finali : A, B, C, D {};

int main() { Finali f;

} a. 1 b. 2

c. 3 ♦ raz dla wirtualnego wystąpienia Base (obiekty A i B mają wspólną klasę bazową) i po jednym razie dla C i D, każde z nich ma klasę bazową Base

d. 4

e. to się nie skompiluje 29. Co się wydrukuje?

struct Shape { void print() {cout<<”SHAPE”<<endl;} };

struct Circle : Shape { private: void print() {cout<<”CIRCLE”<<endl;} };

int main() {

Shape *ptr = new Circle;

ptr->print();

}

a. SHAPE ♦ bo metoda print() nie jest wirtualna. Natomiast o dostępności decyduje jej położenie w typie (klasie), jakim jest wskaźnik. Wskaźnik ptr jest do typu Shape, a w strukturze Shape metoda print() jest publicznie dostępna.

b. CIRCLE

c. nie skompiluje się, bo w Circle metoda print() jest prywatna d. nie skompiluje się, bo Circle dziedziczy prywatnie z Shape

30. Jaka jest maksymalna liczba niejawnie zdefiniowanych konstruktorów, jakie poniższa klasa może mieć?

class A { public:

A ( A & src ) { } A ( double d ) { } int val;

};

a. 0 ♦ bo zdefiniowano konstruktor kopiujący. W takim wypadku język nie dopuszcza tworzenia żadnego konstruktora domyślnego.

b. 1 c. 2

d. nieskończenie wiele e. niezdefiniowane

(8)

31. Co zostanie wydrukowane?

class A { public:

A() : val( 0 ) {}

A( int v ) : val ( v ) {}

A( A& a ) : val(a.val) {}

int val;

};

int main() { const A a1;

const A a2( 5 );

const A a3 = a2;

cout << a1.val + a2.val + a3.val << endl;

}

a. 0 b. 5 c. 10

d. program się nie skompiluje ♦ bo w trzeciej linii programu ( const A a3 = a2 ) następuje próba inicjalizacji a3 za pomocą zmiennej a2, ale zdefiniowany w klasie konstruktor kopiujący nie ma argumentu do referencji z przydomkiem const, przez co pogwałcona by była stałość obiektu a2

32. Która linia kodu (numeracja w komentarzu) się nie skompiluje?

class A { public:

A( int x ) : n( x ) {}

int n;

};

int main() {

A a1; // linia 1 A a2( 2 ); // linia 2 A a3( a2 ); // linia 3 }

a. linia 1 ♦ bo brak konstruktora domyślnego (tzn. nie wymagającego podania parametru). Konstruktory kopiujące też nie są zdefiniowane (linia 2 i 3), ale zostaną domyślnie wygenerowane.

b. linia 2 c. linia 3 d. linia 1 i 3

e. wszystko jest ok, skompiluje się

Cytaty

Powiązane dokumenty

Niezależnie od tego, czy dopuszcza się przyjęcie per- spektywy krytycznej wobec praktyk zarządczych i wewnątrzorga- nizacyjnych relacji społecznych, czy też preferowane jest

While shaping the architecture of a single-family detached house, the students were to underscore the aspects as- sociated with aesthetics and spatial composition, as well

Rozwiązanie zadania do końca lecz z usterka, które jednak nie przekreślają poprawności rozwiązania ...

Metoda przedłużania włosów Hair Talk Extensions to zupełna nowość na polskim rynku fryzjerskim.. Dzięki jej innowacyjności zaoszczędzimy czas

lista składowych klasy - deklaruje składowe klasy, czyli dane i.. b) Deklaracja składowych wewnątrz klasy. C) Definicja składowych na zewnątrz klasy – kod metod występuje w jednym

tworzenie jednego pliku, definiowanie nazw z plików nagłówkowych..

Zadanie dla uczniów, którzy nie mają opinii/orzeczenia (oczywiście, mogą je wykonać wszyscy chętni):.. Zmodyfikowane zadanie 10 –

Odbiło się to jednak fatalnie na naszych stosunkach i naszem życiu potocznem.. W ten sposób spędzają one w iększą część dnia, przygotow ując się do