Egzamin z programowania obiektowego, wrzesień 2006
1.
[10] Dana jest
funkcja foo:
double foo(const double* p1, const double* q1,
const double* p2, double x)
{
for ( ; p1 != q1; ++p1, ++p2)
x += *p1 * *p2;
return x;
}
oraz tablice t i s zadeklarowane
jako
double t[] = {1,2,3};
double s[]
= {3,2,1};
a.
[1] Oblicz foo(s, &s[0], t, 0)
b.
[2] Oblicz foo(s, s+1, t, 0)
c.
[2] Oblicz foo(s, s+1, t, 1)
d.
[2] Dlaczego
wywołanie funkcji foo(s, t, s, 0) będzie miało
opłakane skutki, mimo że z formalnego punktu widzenia jest poprawne (tzn.
kompilator nie zgłosi żadnego błędu ani choćby ostrzeżenia)?
e.
[2] Dlaczego
wywołanie funkcji foo(s, s+3, 0, 0) spowoduje
błąd podczas uruchomienia programu, mimo że z formalnego punktu widzenia jest
poprawne (tzn. kompilator nie zgłosi żadnego błędu ani choćby ostrzeżenia)?
f.
[1] Funkcja foo
realizuje pewien standardowy algorytm (i możesz ją znaleźć w bibliotece
standardowej języka C++ w pliku stl_numeric.h). Czy domyślasz się, co to za algorytm?
(wskazówka: do wyboru masz: accumulate, inner_product, partial_sum, i adjacent_difference)
2. [10] W skład pewnego większego projektu wchodzą 2 pliki
zawierające definicję generatora liczb pseudolosowych:
Plik random.h:
#ifndef RANDOM_H__
#define RANDOM_H__
#include <assert.h>
#include "gsl/gsl_rng.h"
class Random
{
public:
Random(unsigned int n) {
assert (counter == 0);
r = gsl_rng_alloc
(gsl_rng_mt19937);
gsl_rng_set
(r, n);
counter++;
}
~Random() {
gsl_rng_free(r);
counter--;
}
int
operator() (int n) { return gsl_rng_uniform_int
(r, n); }
private:
gsl_rng
* r;
static int
counter;
};
extern Random rng;
#endif
Plik random.cpp:
#include <time.h>
#include "random.h"
int Random::counter = 0;
Random rng(time(0));
a.
[2] W jakim celu
zawartość pliku random.h
umieszczono wewnątrz bloku instrukcji preprocesora
(#ifndef ... #endif)?
b.
[2] W jakim celu
w pliku random.h
deklarację zmiennej rng poprzedzono
słowem extern?
c.
[2] W
jakim celu w pliku random.cpp
umieszczono instrukcję int Random::counter = 0;?
d.
[2] Jaką rolę w
powyższym kodzie pełni statyczna składowa couter?
e.
[2] Jaką rolę
pełni asercja w tym konstruktorze? Jaki jest kontrakt dla tej klasy?
3.
[10] Zdefiniuj
funkcję suma, która będzie pobierać trzy argumenty:
Funkcja suma
ma zwracać sumę wszystkich f(i) dla i = n0,...,n1.
Przykład użycia takiej funkcji:
...
int kwadrat(int n)
{
return n*n;
}
...
cout << "suma kwadratów liczb naturalnych od 1 do 10 wynosi "
<< suma(kwadrat, 1, 10) << "\n";
4. [10] Załóżmy, że masz tablicę tab typu std::vector<int>. Uporządkuj ją algorytmem std::sort tak, by liczby o mniejszej wartości bezwzględnej poprzedzały te o większej:
5.
[10] Napisz
definicję funkcji posortowana, która przyjmuje jako jedyny argument tablicę typu std::vector<double> i która zwraca true
wtedy i tylko wtedy, gdy wartości elementów jej argumentu są posortowane w
kierunku od najmniejszej do największej; jeżeli nie są posortowane, funkcja ma
zwracać false.