Příloha A. Řešení cvičení

A.1. Cvičení z kapitoly 2

Úkol k textu

Zadání 1)

Napište program, který převádí metry na centimetry. Program bude opakovat tento proces, dokud uživatel nezadá nulu.

cvi/cvi2_1.cpp
Řešení
#include <iostream.h>

int main()
{
  double centimetry;

  do {
     cout << "Zadej pocet metru (0 = konec): ";
     cin >> centimetry;
     
     cout << centimetry * 100 << " centimetru\n";
  } while (centimetry != 0.0);

  return 0;
}

Úkol k textu

Zadání 2)

Převeďte tento program napsaný v jazyce C tak, aby používat I/O styly z C++.

#include <stdio.h>

int main(void)
{
  int a, b, d, min;

  printf("Zadej dve cisla: ");
  scanf("%d%d", &a, &b);
  min = a > b ? b : a;
  for(d = 2; d<=min; d++)
    if(((a%d)==0) && ((b%d)==0)) break;
  if((d-1)==min) {
    printf("Zadny spolecny delitel\n");
    return 0;
  }
  printf("Nejmensi spolecny delitel je %d\n", d);
  return 0;
}


cvi/cvi2_2.cpp
Řešení
#include <iostream.h>

int main()
{
  int a, b, d, min;

  cout << "Zadej dve cisla: ";
  cin >> a >> b;

  min = a > b ? b : a;

  for(d = 2; d<=min; d++)
	 if(((a%d)==0) && ((b%d)==0)) break;
  if((d-1)==min) {
    cout << "Zadny spolecny delitel\n";
    return 0;
  }
  cout << "Nejmensi spolecny delitel je " << d << ".\n";

  return 0;
}

Úkol k textu

Zadání 3)

Vytvořte funkci min(), která vrací menší ze dvou zadaných numerických argumentů, použitých ve volání funkce. Přeložte min() tak, aby jako své argumenty příjímala znaky, integer a double.

cvi/cvi2_3.cpp
Řešení
#include <iostream.h>
#include <ctype.h>

char min(char a, char b);
int min(int a, int b);
double min(double a, double b);

int main()
{
  cout << "Min is: " << min('x', 'a') << "\n";
  cout << "Min is: " << min(10, 20) << "\n";
  cout << "Min is: " << min(0.2234, 99.2) << "\n";

  return 0;
}

// min() for chars
char min(char a, char b)
{
  return tolower(a)<tolower(b) ? a : b;
}

// min() for ints
int min(int a, int b)
{
  return a<b ? a : b;
}

// min() for doubles
double min(double a, double b)
{
  return a<b ? a : b;
}

Úkol k textu

Zadání 4)

Mějme program napsaný podle konvencí C++. Předveďte jak je změnit do formy pro jazyk C.

#include <iostream.h>

int f(int a);

int main()
{
  cout << f(10);

  return 0;
}

int f(int a)
{
  return a * 3.1416;
}


cvi/cvi2_4.c
Řešení
#include <stdio.h>


int f(int a);

int main()
{
  printf("%d",f(10));

  return 0;
}

int f(int a)
{
  return a * 3.1416;
}


A.2. Cvičení z kapitoly 3

Úkol k textu

Zadání 1)

Co je špatného na konstruktoru v následujícím fragmentu?
class priklad {
   double a, b, c;
public:
   double priklad();   //chyba, proc?
};


Řešení
Řešení

Konstruktor nemůže mít návratový typ.

Úkol k textu

Zadání 2)

Vytvořte třídu t_and_d, která předává aktuální systémový čas a datum, jako argument svému konstruktoru, když je vytvářena. Ať třída obsahuje členskou funkci, která zobrazí čas a datum na obrazovce (Rada: Pro nalezení a zobrazení data a času použijte standardní funkce ze standardní knihovny)

cvi/cvi3_2.cpp
Řešení
#include <iostream.h>
#include <time.h>

class t_and_d {
  time_t systime;
public:
  t_and_d(time_t t);
  void show();
};

t_and_d::t_and_d(time_t t)
{
  systime = t;
}

void t_and_d::show()
{
  cout << ctime(&systime);
}

int main()
{
  time_t x;

  x = time(NULL);

  t_and_d ob(x);

  ob.show();

  return 0;
}


Úkol k textu

Zadání 3)

Je dána následující třída. Vytvořte dvě odvozené třídy rectangle a isosceles. Ať každá třída obsahuje funkci pojmenovanou area() která dle zadání vrací plochu čtyřúhelníku nebo rovnoramenného trojúhelníku. Pro inicializaci height a width použijte konstruktor s argumenty.
class area_c1 {
public:
   double height;
   double width;
};

cvi/cvi3_3.cpp
Řešení
#include <iostream.h>

class area_cl {
public:
  double height;
  double width;
};

class rectangle : public area_cl {
public:
  rectangle(double h, double w);
  double area();
};

class isosceles : public area_cl {
public:
  isosceles(double h, double w);
  double area();
};

rectangle::rectangle(double h, double w)
{
  height = h;
  width = w;
}

isosceles::isosceles(double h, double w)
{
  height = h;
  width = w;
}

double rectangle::area()
{
  return width * height;
}
 
double isosceles::area()
{
  return 0.5 * width * height;
}

int main()
{
  rectangle b(10.0, 5.0);
  isosceles i(4.0, 6.0);

  cout << "Ctyruhelnik: " << b.area() << "\n";
  cout << "Trojuhelnik: " << i.area() << "\n";

  return 0;
}



Úkol k textu

Zadání 4)

Co zobrazí tento program?

#include <iostream.h>

int main()
{
  int i = 10;
  long l = 1000000;
  double d = -0.0009;

  cout << i << ' ' << l << ' ' << d;
  cout << "\n";

  return 0;
}


Řešení
Řešení

10 1000000 -0.0009

A.3. Cvičení z kapitoly 4

Úkol k textu

Zadání 1)

Co je špatného v následujícím fragmentu?
#include <iostream.h>

class cl1 {
  int i, j;
public:
  cl1(int a, int b) { i = a; j = b; }
  // ...
};

class cl2 {
  int i, j;
public:
  cl2(int a, int b) { i = a; j = b; }
  // ...
};

int main()
{
  cl1 x(10, 20);
  cl2 y(0, 0);
  x = y;

  // ...
}


Řešení
Řešení

Přiřazovací příkaz x = y je chybný, protože cl1 a cl2 jsou dva různé typy tříd a objekty různých typů tříd nemohou být přiřazeny.

Úkol k textu

Zadání 2)

Když je funkci předáván objekt, je vytvářena jeho kopie. Při návratu této funkce je volán destruktor kopie. Co je potom špatné v následujícím příkladu?
#include <iostream.h>
#include <stdlib.h>

class dyna {
  int *p;
public:
  dyna(int i);
  ~dyna() { free(p); cout << "Uvolnuji \n"; }
  int get() { return *p; }
};

dyna::dyna(int i)
{
  p = (int *) malloc(sizeof(int));
  if(!p) {
    cout << "Allocation failure\n";
    exit(1);
  }

  *p = i;
}

// vraceni zaporne hodnoty
int neg(dyna ob)
{
  return -ob.get();
}

int main()
{
  dyna o(-10);

  cout << o.get() << "\n";
  cout << neg(o) << "\n";

  dyna o2(20);
  cout << o2.get() << "\n";
  cout << neg(o2) << "\n";

  cout << o.get() << "\n";
  cout << neg(o) << "\n";

  return 0;
}


Řešení
Řešení

Paměť použitá pro uložení integer a odkazovaná přes p v objektu o, který je použit pro volání neg() je uvolněna při zrušení kopie o, když končí neg(), bez ohledu na to, zda ji ještě o potřebuje v main().

Úkol k textu

Zadání 3)

Vytvořte třídu who. Nechť její konstruktor přebírá jednoznakový argument, který bude použit pro identifikaci objektu. Ať konstruktor při vytváření objektu vypisuje:
Vytvarim who #x


Kde x je identifikační znak každého objektu. Když je objekt rušen, ať se zobrazuje zpráva:
Rusim who #x


Nakonec vytvořte funkci make_who(), která vrací objekt who. Každému objektu přiřaďte unikátní jméno.

cvi/cvi4_3.cpp
Řešení
#include <iostream.h>

class who {
  char name;
public:
  who(char c) { 
     name = c;
     cout << "Vytvarim who #";
     cout << name << "\n";
  }
  ~who() { cout << "Rusim who #" << name << "\n"; }
};

who makewho()
{
  who temp('B');
  return temp;
}

int main()
{
  who ob('A');

  makewho();

  return 0;
}

Úkol k textu

Zadání 4)

Může být adresa objektu využita funkcí jako argument?

Řešení
Řešení
Ano

Úkol k textu

Zadání 5)

Co jsou to spřátelené funkce?

Řešení
Řešení

Spřátelené funkce nejsou členské funkce, ale mají zajištěný přístup k privátním členům třídy s níž jsou spřáteleny.

A.4. Cvičení z kapitoly 5

Úkol k textu

Zadání 1)

S využitím deklarované třídy vytvořte desetiprvkové pole a inicializujte prvek ch hodnotami AJ. Následně toto pole vytiskněte.
#include <iostream.h>

class letters {
  char ch;
public:
  letters(char c) { ch = c; }
  char get_ch() { return ch; }
};


cvi/cvi5_1.cpp
Řešení
#include <iostream.h>

class letters {
  char ch;
public:
  letters(char c) { ch = c; }
  char get_ch() { return ch; }
};

int main()
{
  letters ob[10] = { 'a', 'b', 'c','d', 'e', 'f', 
                     'g', 'h', 'i', 'j' };

  int i;

  for(i=0; i<10; i++) 
    cout << ob[i].get_ch() << ' ';

  cout << "\n";

  return 0;
}



Úkol k textu

Zadání 2)

Přepište v následujícím programu všechny příslušné odkazy na explicitní ukazatel this.
#include <iostream.h>

class myclass {
  int a, b;
public:
  myclass(int n, int m) { a = n; b = m; }
  int add() { return a+b; }
  void show();
};

void myclass::show()
{
  int t;

  t = add();
  cout << t << "\n";
}

int main()
{
  myclass ob(10, 14);

  ob.show();

  return 0;
}


cvi/cvi5_2.cpp
Řešení
#include <iostream.h>

class myclass {
  int a, b;
public: 
  myclass(int n, int m) { this->a = n; this->b = m; }
  int add() { return this->a + this->b; }
  void show();
};

void myclass::show()
{
  int t;

  t = this->add(); 
  cout << t << "\n";
}

int main()
{
  myclass ob(10, 14);

  ob.show();

  return 0;
}



Úkol k textu

Zadání 3)

Napište program, který bude při použití new dynamicky alokovat float, double a char. Zadejte do těchto dynamických proměnných hodnoty a zobrazte je. Nakonec uvolněte celou dynamicky přidělenou paměť pomocí delete.

cvi/cvi5_3.cpp
Řešení
#include <iostream.h>

int main()
{
  float *f;
  long *l;
  char *c;

  f = new float;
  l = new long;
  c = new char;

  if(!f || !l || !c) {
    cout << "Chyba pri alokaci.";
    return 1;
  }

  *f = 10.102;
  *l = 100000;
  *c = 'A';

  cout << *f << ' ' << *l << ' ' << *c;
  cout << '\n';
 
  delete f; 
  delete l; 
  delete c;

  return 0;
}




Úkol k textu

Zadání 4)

Převeďte následující kód na jeho ekvivalent, který používá new.
char *p;

p = (char *) malloc(100);
// ...
strcpy(p, "Test");


Řešení
Řešení
char *p;

p = new char [100];
// ...
strcpy(p, "Test");


Úkol k textu

Zadání 5)

Co je v následujícím programu chybné?
#include <iostream.h>

void triple(double &num);

int main()
{
  double d = 7.0;

  triple(&d);

  cout << d;

  return 0;
}

void triple(double &num)
{
  num = 3 * num;
}


Řešení
Řešení

Když je voláno tripple(), získává se explicitně adresa d operátorem &, což není povolené. Když je použit argument odkazu, není před argument vloženo &.

Úkol k textu

Zadání 6)

Co je to ukazatel this?

Řešení
Řešení

Ukazatel this je ukazatel, který je automaticky předáván členské funkci a který ukazuje na objekt, který generoval volání.

Úkol k textu

Zadání 7)

Co je odkaz? Jaká je výhoda použití argumentu odkazu?

Řešení
Řešení

Odkaz je v podstatě implicitní konstantní ukazatel, který má odlišné jméno než jiná proměnná nebo argument. Výhodou použití odkazu je, že nevzniká kopie argumentu.

A.5. Cvičení z kapitoly 6

Úkol k textu

Zadání 1)

Udejte dva důvody, proč můžeme chtít přetížit konstruktor třídy.

Řešení
Řešení

Například proto, abychom mohli v konstruktoru v závislosti na konkrétním volání provést danou inicializaci, nebo také proto, aby se v programu mohly objevit jak samostatné objekty tak i pole objektů.

Úkol k textu

Zadání 2)

Co je v následujícím fragmentu špatně?
class samp {
  int a;
public:
  samp(int i) { a = i; }
  // ...
}:

// ...

int main()
{
  samp x, y(10);

  // ...
}


Řešení
Řešení

Třída samp definuje pouze jediný konstruktor a tento konstruktor požaduje hodnotu pro inicializaci. Je nesprávné deklarovat objekt typu samp bez něj.

Úkol k textu

Zadání 3)

Stručně popište standardní argument.

Řešení
Řešení

Standardní argument je hodnota, která se přidělí argumentu funkce, když se při volání funkce neobjeví požadovaný počet argumentů.

Úkol k textu

Zadání 4)

Co je v tomto prototypu funkce špatně?
char *f(char *p, int x = 0, char *q);


Řešení
Řešení

Všechny programy, které přebírají standardní argumenty se musí objevit napravo od toho, který nepřebírá. Jakmile totiž začneme předávat standardní argumenty, všechny následující argumenty musí být také standardní. q zde není standardní.

Úkol k textu

Zadání 5)

Co je špatně v tomto prototypu, který používá standardní argument?
int f(int pocet, int max = pocet);


Řešení
Řešení

Standardní argument nemůže být další argument nebo lokální proměnná.

Úkol k textu

Zadání 6)

Mějme tyto dvě přetěžované funkce. Ukažte jak získat adresu každé z nich.
int dif(int a, int b)
{
  return a-b;
}

float dif(float a, float b)
{
  return a-b;
}


cvi/cvi6_6.cpp
Řešení
#include <iostream.h>

int dif(int a, int b)
{
  return a-b;
}

float dif(float a, float b)
{
  return a-b;
}

int main()
{
  int (*p1)(int, int);
  float (*p2)(float, float);

  p1 = dif; // adresa dif(int, int)
  p2 = dif; // adresa dif(float, float);

  cout << p1(10, 5) << ' ';
  cout << p2(10.5, 8.9) << '\n';

  return 0;
}



A.6. Cvičení z kapitoly 7

Úkol k textu

Zadání 1)

Mějme definován tento kód.
#include <iostream>

class mybase {
  int a, b;
public:
  int c;
  void setab(int i, int j) { a = i; b = j; }
  void getab(int &i, int &j) { i = a; j = b; }
};

class derived1 : public mybase {
// ...
};

class derived2 : private mybase {
// ...
};

int main()
{
  derived1 o1;
  derived2 o2;
  int i, j;

  // ...
}


Které z následujících příkazů jsou v rámci funkce main() platné?
o1getab(i, j);
o2getab(i, j);
o1.c = 10;
o2.c = 10;


Řešení
Řešení

Platné příkazy jsou tyto:
o1getab(i, j);
o1.c = 10;


Úkol k textu

Zadání 2)

Mějme základní třídu Base a odvozenou třídu Derived. Napište program, který ukáže v jakém pořadí jsou spouštěny konstruktory a destruktory v případě, že Derived dědí třídu Base.

cvi/cvi7_2.cpp
Řešení
#include <iostream.h>

class base {
public:
  base() { cout << "Konstruktor tridy Base\n"; }
  ~base() { cout << "Destruktor tridy Base\n"; }
};

class derived : public base {
public:
  derived() { cout << "Konstruktor tridy Derived\n"; } 
  ~derived() { cout << "Destruktor tridy Derived\n"; }
};

int main()
{
  derived o;

  return 0;
}


Úkol k textu

Zadání 3)

Co zobrazí následující program?
#include <iostream.h>

class A {
public:
  A() { cout << "Constructing A\n"; }
  ~A() { cout << "Destructing A\n"; }
};

class B {
public:
  B() { cout << "Constructing B\n"; }
  ~B() { cout << "Destructing B\n"; }
};

class C : public A, public B {
public:
  C() { cout << "Constructing C\n"; }
  ~C() { cout << "Destructing C\n"; }
};

int main()
{
  C ob;

  return 0;
}


Řešení
Řešení

Constructing A
Constructing B
Constructing C
Destructing C
Destructing B
Destructing A

A.7. Cvičení z kapitoly 8

Úkol k textu

Zadání 1)

Napište program, který zkopíruje textový soubor. Ať program spočítá kopírované znaky a výsledek zobrazí.

cvi/cvi8_1.cpp
Řešení
#include <iostream.h>
#include <fstream.h>

int main(int argc, char *argv[])
{
  if(argc!=3) {
    cout << "Zadejte: cvi8_1 vstup vystup\n";
    return 1;
  }

  ifstream fin(argv[1]); // otevirani vstupniho souboru
  ofstream fout(argv[2]);  // vytvareni vystupniho souboru

  if(!fin) {
    cout << "Nelze otevrit vstupni soubor\n";
    return 1;
  }

  if(!fout) {
    cout << "Nelze vytvorit vystupni soubor\n";
    return 1;
  }

  char ch;
  unsigned count=0;

  fin.unsetf(ios::skipws); 
  while(!fin.eof()) {
    fin >> ch;
    if(!fin.eof()) {
      fout << ch;
      count++;
    }
  }

  cout << "Pocet zkopirovanych znaku: " << count << '\n';

  fin.close();
  fout.close();

  return 0;
}


Úkol k textu

Zadání 2)

Napište program, který zobrazí textový soubor pozpátku.

cvi/cvi8_2.cpp
Řešení
#include <iostream.h>
#include <fstream.h>

int main(int argc, char *argv[])
{
  if(argc!=2) {
    cout << "Zadejte: cvi8_2 nazev souboru\n";
    return 1;
  }

  ifstream in(argv[1], ios::in | ios::binary);

  if(!in) {
    cout << "Nelze otevrit vstupni soubor\n";
    return 1;
  }

  char ch;
  long i;

  in.seekg(0, ios::end);
  i = (long) in.tellg(); 
  i -= 2; 

  for( ;i>=0; i--) {
    in.seekg(i, ios::beg);
    in.get(ch);
    cout << ch;
  }

  in.close();

  return 0;
}



Úkol k textu

Zadání 3)

Napište program, který čte textový soubor a hlásí, kolikrát se v něm které písmeno vyskytlo.

cvi/cvi8_3.cpp
Řešení
#include <iostream.h>
#include <fstream.h>
#include <ctype.h>

int alpha[26];

int main(int argc, char *argv[])
{
  char ch;

  if(argc!=2) {
    cout << "Zadejte: cvi8_3 nazev souboru\n";
    return 1;
  }

  ifstream in(argv[1]);

  if(!in) {
    cout << "Nelze otevrit vstupni soubor\n";
    return 1;
  }

  // init alpha[]
  int i;
  for(i=0; i<26; i++) alpha[i] = 0;

  while(!in.eof()) {
    ch = in.get();
    if(isalpha(ch)) { // pokud bylo nalezeno pismono
      ch = toupper(ch); // normalizace
      alpha[ch-'A']++; // 'A'-'A' == 0, 'B'-'A' == 1, ...
    }
  };

  for(i=0; i<26; i++) {
    cout << (char) ('A'+ i) << ": " << alpha[i] << '\n';
  }

  in.close();

  return 0;
}



Úkol k textu

Zadání 4)

Napište program, který kopíruje textový soubor a obrací velká písmena na malá a naopak.

cvi/cvi8_4.cpp
Řešení
#include <iostream.h>
#include <fstream.h>
#include <ctype.h>

int main(int argc, char *argv[])
{
  char ch;

  if(argc!=3) {
    cout << "Zadejte: cvi8_4 zdroj cil\n";
    return 1;
  }

  ifstream in(argv[1]);

  if(!in) {
    cout << "Nelze otevrit vstupni soubor\n";
    return 1;
  }

  ofstream out(argv[2]);

  if(!out) {
    cout << "Nelze otevrit vystupni soubor\n";
    return 1;
  }

  while(!in.eof()) {
    ch = in.get();
    if(!in.eof()) {
      if(islower(ch)) ch = toupper(ch);
      else ch = tolower(ch);
      out.put(ch);
    }
  };

  in.close();
  out.close();

  return 0;
}




A.8. Cvičení z kapitoly 9

Úkol k textu

Zadání 1)

Vytvořte program, který bude obsahovat základní třídu num, která bude obsahovat virtuální funkci shownum(). Vytvořte dvě derivované třídy fhex a foct, které dědí num. Ať odvozené třídy přehodnotí funkci shownum() a zobrazí číslo v šestnáctkové a osmičkové soustavě.

cvi/cvi9_1.cpp
Řešení
#include <iostream.h>

class num {
public:
  int i;
  num(int x) { i = x; }
  virtual void shownum() { cout << i << '\n'; }
};

class fhex : public num {
public:
  fhex(int n) : num(n) {}
  void shownum() { cout << hex << i << '\n'; }
};

class foct : public num {
public:
  foct(int n) : num(n) {}
  void shownum() { cout << oct << i << '\n'; }
};

int main()
{
  foct o(10);
  fhex h(20);

  o.shownum();
  h.shownum();

  return 0;
}

Úkol k textu

Zadání 2)

Proč nemůže být pomocí abstraktní funkce vytvořen objekt?

Řešení
Řešení

Abstraktní třída obsahuje alespoň jednu čistě virtuální funkci. To znamená, že vzhledem k této třídě nemá funkce žádné tělo. Neexistuje žádný způsob, jak by mohl být vytvořen objekt, poněvadž definice třídy není úplná.

Úkol k textu

Zadání 3)

Je tento fragment správný?
class base {
public:
  virtual int f(int a) = 0;
  // ...
};

class derived : public base {
public:
  int f(int a, int b) { return a*b; }
  // ...
};


Řešení
Řešení

Fragment není správný, protože definice virtuální funkce musí mít stejný návratový typ a počet argumentů jako původní funkce. V tomto případě se liší počet argumentů.

Úkol k textu

Zadání 4)

Jsou virtuální vlastnosti dědičné?

Řešení
Řešení
Ano

A.9. Cvičení z kapitoly 10

Úkol k textu

Zadání 1)

Vytvořte generickou funkci min(), která vrací menší ze dvou argumentů. Předveďte její funkci v programu.

cvi/cvi10_1.cpp
Řešení
#include <iostream.h>

template <class X> X min(X a, X b)
{
  if(a<=b) 
    return a;
  else 
    return b;
}

int main()
{
  cout << min(0.2, 2.0);
  cout << "\n";
  cout << min(3, 4);
  cout << "\n";
  cout << min('c', 'a');
  return 0;
}






Úkol k textu

Zadání 2)

Co je v tomto fragmentu programu špatně?
int main()
{
 throw 12.23;
 .
 .
 .
}


Řešení
Řešení

Throw je voláno ještě před průchodem bloku try.

Úkol k textu

Zadání 3)

Co je v tomto fragmentu programu špatně?
try {
 // ....
 throw 'a';
 // ...
}
catch(char *) {
 // ...
}


Řešení
Řešení

Znaková vyjímka je odmítnuta, ale příkaz catch obslouží pouze znakový ukazatel - neexistuje odpovídající příkaz catch, který by obsloužil znakovou vyjímku.

Úkol k textu

Zadání 4)

Co je v tomto fragmentu programu špatně?
try {
 // ...
 throw 10;
}
catch(int *p) {
 // ...
}


Řešení
Řešení

Pro throw neexistuje odpovídající catch.

Úkol k textu

Zadání 5)

Ukažte nějaký způsob jak opravit chyby v předchozím fragmentu programu.

Řešení
Řešení

Je nutné vytvořit catch zachytávající int - catch(int) a nebo je možné zachytávat všechny vyjímky - catch(...)

Úkol k textu

Zadání 6)

Vytvořte generický bubble sort.

cvi/cvi10_6.cpp
Řešení
#include <iostream.h>

template <class X> void bubble(X *data, int size)
{
  register int a, b;
  X t;

  for(a=1; a < size; a++)
    for(b=size-1; b >= a; b--)
      if(data[b-1] > data[b]) {
        t = data[b-1];
        data[b-1] = data[b];
        data[b] = t;
      }
}

int main()
{
  int i[] = {3, 2, 5, 6, 1, 8, 9, 3, 6, 9};
  double d[] = {1.2, 5.5, 2.2, 3.3};
  int j;

  bubble(i, 10); // setridene int
  bubble(d, 4);  // setridene double

  for(j=0; j<10; j++) cout << i[j] << ' ';
  cout << endl;

  for(j=0; j<4; j++) cout << d[j] << ' ';
  cout << endl;

  return 0;
}