Imię
i nazwisko: 10
czerwca 2006
Uwaga: W poniższym teście w
każdym punkcie ilość poprawnych odpowiedzi wynosi od 0 do 4. Każdą z nich
należy oznaczyć słowem „TAK”, a odpowiedź błędną – słowem „NIE”.
1. Zaleca się, by używać asercji do:
a) Wyłapywania błędów w implementacji algorytmów.
b) Wyłapywania błędów składniowych.
c) Obsługi nieprawidłowego formatu danych wprowadzanych przez użytkowników programu.
d) Wyłapywania
błędów w dynamicznej alokacji pamięci.
2. Zaleca się, by używać wyjątków do:
a) Wyłapywania błędów w implementacji algorytmów.
b) Wyłapywania błędów składniowych.
c) Obsługi nieprawidłowego formatu danych wprowadzanych przez użytkowników programu.
d) Wyłapywania
błędów w dynamicznej alokacji pamięci.
3. Koszt użycia asercji związany ze zwiększeniem czasu wykonywania programu
a) Można zredukować do zera, definiując opcję kompilatora –DNDEBUG
b) Można zredukować do zera, definiując opcję kompilatora –DEBUG
c) Można znacząco zredukować, ale nigdy do zera.
d) Jest
zawsze tak mały, że w praktyce można go pomijać.
4.
Po wykonaniu programu kompilowanego kompilatorem
gcc na konsoli pojawił się następujący komunikat:
/usr/local/include/c++/4.1.1/debug/list:227:
error: attempt to access an element in an
empty container.
Objects
involved in the operation:
sequence
"this" @ 0x0x22ee90 {
type =
N15__gnu_debug_def4listIiSaIiEEE;
}
Aborted (core
dumped)
Oczywiście napis N15__gnu_debug_def4listIiSaIiEEE
reprezentuje „udekorowaną” nazwę pewnego typu użytego w programie. Aby się
zorientować, co to za typ, można posłużyć się programem lub programami:
a) make
b) ar
c) nm
d)
preprocesorem (gcc –E)
5.
Załóżmy, że definicja klasy X wygląda następująco
(wydruk pomija definicję konstruktora X):
class X : public Y
{
public:
std::vector<int> _v;
int _x;
X () : _x(10),
_v(_x) { /* ... jakiś kod ... */ }
};
a) Składowa _x jest zawsze inicjowana przed _v.
b) O tym, czy _x jest inicjowane przed _v decyduje definicja konstruktora X.
c) Składowe _x i _v klasy X są inicjowane przed składowymi klasy bazowej Y.
d) Definiując
treść dowolnego konstruktora X można przyjąć,
że klasa bazowa Y jest już w pełni zainicjowana.
6. Wartość wyrażenia (1&2) + (1|2) + (1^2) + (1%2) + 0x12
a) wynosi 25
b) wynosi 26
c) wynosi 27
d) jest większa niż 27
7. Koszt użycia funkcji wirtualnych związany ze zwiększeniem czasu wykonywania programu
a) Można zredukować do zera, definiując opcję kompilatora –DFASTVIRTUAL
b) Można znacząco zredukować, definiując wszystkie składowe wirtualne jako inline
c) Jest zawsze tak mały, że w praktyce można go pomijać.
d) Może
być znaczący w wypadku funkcji krótkich i bardzo często wywoływanych.
8.
Tablicę tab, zdefiniowaną
instrukcją
int tab[100];
można użyć jako argumentu następujących
funkcji:
a) int fa(int t[100]);
b) void fb(void * t);
c) int & fc(int * t);
d)
const int & fd(const int t[]);
9. O funkcji int f(int x) wiadomo, że wyrażenie f(x) == f(x) ma zawsze wartość false. Efekt ten można osiągnąć:
a) przy pomocy zmiennych globalnych.
b) przy pomocy zmiennych statycznych lokalnych w f.
c) przy pomocy zmiennych automatycznych lokalnych w f.
d) przy pomocy modyfikacji argumentu funkcji, czyli x.
10. W poniższych instrukcjach mamy gwarancję, że funkcja g nie będzie wywołana przed f:
a)
int x = f(x) + g(x);
b)
if ( f(x) && g(x) ) continue;
c)
if ( f(x) > g(x) ) continue;
d) bool b = f(x) || g(x);
11. Rozpatrzmy
funkcję o następującej sygnaturze:
std::vector::resize(unsigned n) const;
Użyte w niej słówko const
a) modyfikuje typ wyniku funkcji;
b) modyfikuje typ wskaźnika this (w definicji tej funkcji);
c) modyfikuje typ argumentu funkcji (n);
d) jest oczywistym błędem składniowym.
12. Podczas testowania poprawności programu kompilowanego kompilatorem g++ warto przedsięwziąć następujące kroki:
a) skompilować program z opcją -g
e) skompilować program z opcją -DNDEBUG
f) skompilować program z opcją -D_GLIBCXX_DEBUG
g) skompilować
program z opcją -lm
13.
Z
deklaracji
template<typename
_InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
a) wynika, że ostatni argument przekazywany jest przez wartość;
b) wynika, że ostatni parametr musi być funkcją.
c) wynika, że ostatni parametr może być funktorem
d) wynika, że for_each jest szablonem klasy.
14. Żeby wyłapać dowolny wyjątek wyprowadzony przez dziedziczenie z klasy std::exception i móc później z pożytkiem wywołać jego stałą metodę virtual const char *what() const należy za blokiem try umieścić instrukcję (poprawnych jest kilka odpowiedzi):
a)
catch (std::exception) { /*stosowny kod*/ }
b)
catch (std::exception e) {
/*stosowny kod*/ }
c)
catch (std::exception const& e) {
/*stosowny kod*/ }
d)
catch (std::exception & e) {
/*stosowny kod*/ }
15. Następująca instrukcja sortuje 100 pierwszych elementów tablicy int tab[1000]:
a) std::sort( &tab[0], &tab[100] );
b) std::sort( tab, tab + 100 );
c) std::sort( tab[0], tab[100] );
d)
std::sort( tab.begin(), tab.begin() + 100 );
16. Rozpatrzmy funkcję f
int f(int x, unsigned int n)
{
int y = (n % 2) ? x : 1;
while
(n >>= 1)
{
x *=
x;
if (n
% 2)
y
*= x;
}
return
y;
}
wartością f(2, 3) jest
a) 1
a) 6
b) 8
c) liczba większa od 10 i mniejsza od 16
1.
W ramach deklaracji
char
bufor[100];
char *p =
0,
long int strtol (const
char *string, char **tailptr, int base);
poprawna (pod względem składniowym) jest następująca instrukcja:
a)
long int n = strol(bufor, *p, 10);
b)
long int n = strol(bufor, p, 0);
c)
long int n = strol(bufor, &p, 16);
d)
long int n = strol(&bufor[0], &p, 10);
2.
Rozpatrzmy
następujący kod,
class
Foo
{
public:
const Foo* This() const { return this;
}
/* ... */
} foo;
Instrukcja
std::cout << (&foo – foo.This()) << ’\n’;
wyświetli
a) 0
b) wartość przypadkową, bo this ma wartość przypadkową.
c) wartość przypadkową, bo &foo ma wartość nieokreśloną.
d) nic nie wyświetli, bo instrukcja (&foo – foo.This()) zawiera błąd składniowy.
3. Wiadomo, że pewien program kompilowany kompilatorem gcc wymaga użycia biblioteki znajdującej się w pliku libm.a w standardowym katalogu bibliotecznym kompilatora. W tym celu:
a) Do konsolidatora należy przekazać opcję –lm
b) Do konsolidatora należy przekazać opcję –libm
c) Do konsolidatora należy przekazać opcję –L lm
d) Do konsolidatora należy przekazać opcję –L libm
4. Aby przyspieszyć wykonanie programu kompilowanego kompilatorem gcc, można
a) podczas kompilacji zastosować opcję –O2, -Os lub –O3
b) podczas uruchamiania programu zastosować opcję –O2, -Os lub –O3
c) podczas kompilacji zastosować opcję –DNDEBUG
d) podczas uruchamiania programu zastosować opcję –DNDEBUG
Rozwiązania proszę najpierw napisać na brudno i po sprawdzeniu przenieść na podpisaną kartkę z wersją „finalną”. Proszę zwrócić uwagę na sposób definiowania argumentów i wartości funkcji.
#include
<iostream>
int main()
{
int v[10];
for (int i = 0; i
<= 10; ++i)
v[i]
= 0;
}