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.