background image

S t r o n a

 | 1                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Laboratorium 6.  Struktury  

Przed zajęciami laboratoryjnymi zapoznaj się z następującymi pozycjami literatury: 

1. Wykład z przedmiotu „Podstawy programowania” 

Przygotowując  się  do  laboratorium  przeanalizuj  podane  poniżej  przykłady,  odpowiedz  na  pytania,  rozwiąż 

testy  i napisz  odpowiednie  programy.  Po  zajęciach  zrób  zadania  podane  w  ostatnim  punkcie  tego 

opracowania.

 

Przykłady  

 

1.

 

Proste struktury 

 

Przykład L6_F0_P1 

Punkt przestrzeni 

2

 reprezentowany jest jako struktura punkt o dwóch polach rzeczywistych:  wspx i wspy

Przeanalizuj program zawierający: 

 

funkcję  cwiartka,  która  dla  danego  punktu  p,  sprawdza  w  której  ćwiartce  układu  współrzędnych 

rzeczywistych znajduje się p, 

 

funkcję  wyznacz_prosta,  która  wyznacza  współczynniki  a  oraz  b  prostej  o równaniu  y = ax b 

przechodzącej przez dwa dane punkty p

1

p

2

, których współrzędne x są różne. 

Zwróć  uwagę  na  sposób  przesyłania  parametrów  będących  strukturami  oraz  na  typ  rezultatu  funkcji 

wyznaczającej prostą. 

 

#include

<iostream>

 

#include

<iomanip>

 

using namespace std; 

   

struct

 punkt{ 

       

double

 wspx; 

       

double

 wspy; 

}; 
  

struct

 prosta{ 

       

double

 a; 

       

double

 b;      

}; 
 
 

int

 cwiartka( punkt p )       

// --- wyznaczenie 

ć

wiartki układu współrz

ę

dnych,

  

{                             

//     do której nale

ż

y punkt p(x,y)

 

  

if

( p.wspy >= 0 )  

      

if

( p.wspx >= 0 ) 

return

 1; 

      

else

 

return

 2;  

  

else 

      

if

( p.wspx >= 0 ) 

return

 4; 

      

else

 

return

 3; 


 

 
 
 
 
 
 

background image

S t r o n a

 | 2                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

 

 
prosta wyznacz_prosta( punkt p1, punkt p2) 

//

 

--- wyznaczenie równania prostej przechodz

ą

cej przez

 

{                                          

//     dwa punkty p1, p2 takie, 

ż

e  p1.wspx!=p2.wspx

 

   prosta  pr; 
     
   pr.a = (p1.wspy - p2.wspy) / (p1.wspx - p2.wspx); 
   pr.b = p1.wspy - pr.a * p1.wspx; 
      
   

return

 pr;   

}  
   

int

 main() 


  punkt p1, p2; 
  
  cout << 

"Punkt 1"

 << endl; 

  cout << 

"Podaj wspolrzedna x: "

  cin >> p1.wspx; 
  cout << 

"Podaj wspolrzedna y: "

  cin >> p1.wspy; 
  cout << 

"Punkt ( "

 << p1.wspx << 

", "

 << p1.wspy << 

" )"

 

       << 

" nalezy do "

 << cwiartka(p1) << 

" cwiartki ukladu wspolrzednych."

 << endl;  

 
  cout << 

"Punkt 2"

 << endl; 

  cout << 

"Podaj wspolrzedna x: "

  cin >> p2.wspx; 
  cout << 

"Podaj wspolrzedna y: "

  cin >> p2.wspy; 
 
  prosta pr = wyznacz_prosta(p1,p2); 
   
  cout << 

"Prosta przechodzaca przez podane punkty ma rownanie "

  cout << 

"y = "

 << pr.a << 

"x + "

 << pr.b << endl; 

   
  system(

"pause"

);    

  

return

 0; 

Pytania 

1.

 

Jak zmieni się działanie funkcji cwiartka, jeżeli w jej nagłówek zapiszemy następująco 

int cwiartka ( const punkt &p ) 

2.

 

Jak należałoby zapisać nagłówek funkcji wyznacz_prosta, gdyby miała być to funkcja typu void

Odpowiedzi 

1.

 

Zmieni się sposób przesłania parametru p, ale nie wpłynie to na wynik zwracany przez funkcję. 

2.

 

Nagłówek można zapisać na kilka sposobów, np.: 

 

void wyznacz_prosta ( const punkt& p1, const punkt& p2, prosta &pr ); 

 

void wyznacz_prosta ( punkt p1, punkt p2, prosta &pr ); 

2.

 

Tablice struktur 

 

Przykład L6_F0_P2    

W  tablicy  jednowymiarowej  P,  której  elementami  są  struktury  typu  punkt_materialny  o  trzech  polach 

rzeczywistych wspxwspy i masa, zapisano wygenerowany losowo zbiór punktów przestrzeni 

2

. Przeanalizuj 

program zawierający funkcje:   

a)

 

losowo generującą zbiór punktów materialnych,   

b)

 

wyznaczającą środek masy zbioru punktów materialnych. 

... 

struct

 punkt{ 

       

double

 wspx; 

       

double

 wspy; 

 

 

double

 masa; 

}; 

 
 

background image

S t r o n a

 | 3                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

 

// --- generowanie pseudolosowej liczby rzeczywistej z przedziału [a,b] 

 

double

 randR( 

double

 a, 

double

 b)         


    

double

 w = 

static_cast

<

double

>(rand()) / RAND_MAX;  

// w jest liczb

ą

 rzeczywist

ą

 w [0,1]

 

    

return

  w * (b - a) + a;                            

// skalowanie do przedziału [a,b]

 


 
 

// --- generowanie zbioru punktów materialnych 

 

void

 gen_pkt( punkt P[], 

int

 n, 

int

 zw, 

int

 zm ) 


   

for

int

 i = 0; i < n; i++ ){ 

      P[i].wspx = randR(-zw,zw); 
      P[i].wspy = randR(-zw,zw); 
      P[i].masa = randR(0,zm); 
   } 

 
 

// -- wyznaczenie punktu b

ę

d

ą

cego 

ś

rodkiem masy zbioru punktów materialnych 

 
punkt sr_masy( punkt P[], 

int

 n) 


   punkt p = {0,0,0}; 
   

double

 Masa = 0;                      

//  masa zbioru punktów materialnych 

    
   

for

int

 i = 0; i < n; i++ ){ 

      p.wspx += P[i].wspx * P[i].masa; 
      p.wspy += P[i].wspy * P[i].masa; 
 

  Masa += P[i].masa; 

   } 

                  

ś

=

     

ś

=

 

   p.wspx /= Masa; 
   p.wspy /= Masa;                
    
   

return

 p; 


 

int

 main() 


 

const

 

int

 MAX_N = 200; 

 punkt P[MAX_N]; 
 
 

int

 n; 

 cout << 

"Podaj liczbe n punktow materialnych (n <= "

 << MAX_N << 

"): "

 cin >> n; 
  
 srand(time(NULL)); 
  
 

int

 zw = 100;               

// zakres warto

ś

ci dla współrz

ę

dnych [-zw,zw]

 

 

int

 zm = 200;               

// zakres warto

ś

ci dla masy [0,zm] 

  
 gen_pkt( P, n, zw, zm );    
 
 cout << 

"     x       y         masa      "

 << endl; 

 cout << 

"---------------------------------"

 << endl; 

  
 

for

int

 i = 0; i < n; i++ ) 

    cout << fixed << setprecision(2)  
         << setw(8)  << P[i].wspx 
         << setw(8)  << P[i].wspy  
         << setw(12) << P[i].masa << endl;     
          
 punkt psm = sr_masy( P, n );         
          
 cout << 

"Srodek masy zbioru punktow materialnych ma wspolrzedne: "

 << endl 

      << 

"   x = "

 << setw(6) << psm.wspx << endl  

      << 

"   y = "

 << setw(6) << psm.wspy << endl; 

         
 system(

"pause"

);    

 

return

 0; 


 

background image

S t r o n a

 | 4                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Pytanie 

Jakiego typu są poniższe dane? 

a)

 

P[1] 

b)

 

P[1].masa 

Odpowiedź 

Poszczególne dane są następujących typów: 

a)

 

punkt 

b)

 

double 

Przykład L6_F0_P3   

Ważne wydarzenia z historii Polski reprezentowane są jako struktury o dwóch polach zawierających opis oraz 

datę wydarzenia. Data jest strukturą o trzech polach typu całkowitego reprezentujących rok, miesiąc i dzień 

wydarzenia. Przeanalizuj funkcję, która na podstawie danej daty rozstrzyga czy wydarzenie miało miejsce na 

wiosnę, latem, jesienią czy też zimą. Pełny program znajdziesz w pliku L6_F0_P3a.cpp

 

... 

struct

 t_data{ 

       

int

 dzien; 

       

int

 miesiac; 

       

int

 rok; 

}; 

 

struct

 wydarzenie{ 

       

char

[80] opis; 

         t_data data; 

}; 

 

// --- wyznacza astronomiczn

ą

 por

ę

 roku dla danego dnia (model uproszczony dla półkuli północnej) 

int

 pora_roku( t_data d ) 

    

const int

 PW = 321;    

// poczatek wiosny  21.03

 

    

const int

 PL = 622;    

// poczatek lata    22.06 

    

const int

 PJ = 923;    

// poczatek jesieni 23.09

 

    

const int

 PZ = 1222;   

// poczatek zimy    22.12

 

     

    

int

 w = 100 * d.miesiac + d.dzien; 

         

    

if

( PW <= w and w < PL ) 

return

 1;   

// wiosna

 

    

if

( PL <= w and w < PJ ) 

return

 2;   

// lato

 

    

if

( PJ <= w and w < PZ ) 

return

 3;   

// jesien

 

    

return

 4;                            

// zima

 

... 

Pytania 

1.

 

Jak  można  wykorzystać  metodę  zastosowaną  w  tym  przykładzie,  do  porównywania  innych  obiektów 

reprezentowanych jako struktury o wielu atrybutach będących liczbami? Podaj przykład funkcji, która 

pozwala porównywać karty do gry.  

2.

 

Jaką  formułę    można  zastosować  obliczając  w,  aby  porównując  daty  reprezentowane  przez  w 

uwzględnić również rok wydarzenia?  

3.

 

Jak należy zmodyfikować funkcję porządkującą liczby całkowite, aby otrzymać funkcję, która elementy 

tablicy struktur reprezentujących wydarzenia historyczne, porządkuje chronologicznie według dat. 

 

background image

S t r o n a

 | 5                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Odpowiedzi 

1.

 

Aby  porównać  karty  do  gry  można  zastosować  daną  poniżej  funkcję  karta_cmp.  Pełny  program 

znajdziesz w pliku L6_F0_P3b.cpp 

 

... 

struct

 t_karta{ 

       

int

 kolor; 

       

int

 figura; 

}; 

 

// --- porównanie kart (numeracja kolorów i figur mo

ż

e si

ę

 ró

ż

ni

ć

 w zale

ż

no

ś

ci od gry) 

int

 karta_cmp( 

const

 t_karta &karta1, 

const

 t_karta &karta2 )   

{  

    

int

 w1 = 100 * karta1.kolor + karta1.figura; 

    

int

 w2 = 100 * karta2.kolor + karta2.figura;     

         

    

if

( w1 < w2 ) 

return

 1;             

    

else if

 (w1 == w2) 

return

 0;        

    

else return

 -1;                     

... 

2.

 

Aby  porównać  daty  z  uwzględnieniem  roku  miesiąca  i  dnia  można  zastosować  następującą  formułę, 

która jednoznacznie konwertuje datę na liczbę całkowitą 

long int w  = 10000 * d.rok + 100*d.miesiac + d.dzien; 

3.

 

Porządkowanie wydarzeń według dat. Pełny program znajdziesz w pliku L6_F0_P3c.cpp 

 

... 

struct

 t_data{ 

       

int

 dzien; 

       

int

 miesiac; 

       

int

 rok; 

}; 

 

struct

 wydarzenie{ 

       

char

[80] opis; 

         t_data data; 

}; 

 

int

 data_cmp( 

const

 t_data &data1, 

const

 t_data &data2 )   

// --- porownanie dat

 

{  

    

long int

 w1 = 10000 * data1.rok + 100 * data1.miesiac + data1.dzien; 

    

long int

 w2 = 10000 * data2.rok + 100 * data2.miesiac + data2.dzien;     

         

    

if

( w1 < w2 ) 

return

 1;             

    

else if

 (w1 == w2) 

return

 0;        

    

else return

 -1;                     

 

void

 sort_wydarzenia( wydarzenie W[], 

int

 n ) 

  wydarzenie buf; 

 

  

for

int

 p = n-2; p >= 0; p-- )     

     

for

int

 i = 0; i <= p; i++ )  

      

if

( data_cmp( W[i].data, W[i+1].data) == -1 ) 

      { 

         buf = W[i+1]; 

         W[i+1] = W[i]; 

         W[i] = buf; 

      } 

... 

background image

S t r o n a

 | 6                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Przykład  L6_F0_P4    

Na prostokątnym placu magazynowym firmy zajmującej się spedycją, ustawione są stosy kontenerów. Każdy 

stos zawiera nie więcej niż 6 kontenerów. Stosy rozmieszczono na placu w rzędach i alejach w taki sposób, 

że numer  alei  oraz  rzędu,  jednoznacznie  identyfikują  każdy  stos.  W  systemie  zarządzania  kontenerami, 

o każdym kontenerze przechowywane są dane takie, jak nazwa właściciela, waga, itp. Jedną z funkcji systemu 

jest  sporządzenie  listy  kontenerów  zadanego  właściciela  wraz  z  podaniem  ich  lokalizacji  na  placu.  Zapoznaj 

się z poniższym programem.  W szczególności zwróć uwagę na definicje struktur oraz tablicy plac, a także na 

nagłówki  funkcji.  Zaobserwuj,  że  wynikiem  działania  funkcji  szukaj  jest  jednowymiarowa  tablica  ind 

o elementach  będących  strukturami  typu  trojka_indeksow,  z  których  każda  zawiera  współrzędne  jednego 

kontenera. 

 

// L6_F0_P4 --- zarz

ą

dzanie kontenerami 

 

#include

<iostream>

 

#include

<iomanip>

 

using namespace std; 

 

const int

 MAX_R = 15;             

// maksymalna liczba rz

ę

dów na placu 

const int

 MAX_A = 10;             

// maksymalna liczba alei na placu

 

const int

 MAX_N = 5;              

// maksymalna długo

ść

 nazwy wła

ś

ciciela 

const int

 MAX_N_T = MAX_N +1;     

// do u

ż

ycia w definicji napisu 

const int

 MAX_K = 6;              

// maksymalna liczba kontenerów na stosie

 

 
 

struct

 kontener{ 

        

char

 wlasciciel[MAX_N_T]; 

        

int

 waga; 

        

//

 

... oraz inne atrybuty według potrzeb

 

}; 
 

struct

 stos_kontenerow{ 

         

int

 ile;                  

// aktualna liczba kontenerów na stosie

 

         kontener stos[MAX_K];     

// tablica zawieraj

ą

ca kontenery stosu

 

}; 
 

struct

 trojka_indeksow{     

// struktura słu

żą

ca do zapisania poło

ż

enia kontenera na placu

 

       

int

 rzad;            

// rz

ą

d na placu

 

       

int

 aleja;           

// aleja na placu 

       

int

 wys;             

// numer kontenera wewn

ą

trz stosu

 

}; 
 
 

// --- generowanie stosów o losowej liczbie kontenerów, z których ka

ż

dy 

//     ma losow

ą

 zawarto

ść

. Nazwa wła

ś

ciciela jest losow

ą

 wielk

ą

 liter

ą

 ASCII. 

 

int

 gen_plac( stos_kontenerow  plac[][MAX_A], 

int

 r, 

int

 a ) 


    

int

 ile_kont = 0;  

     
     

for

int

 rzad = 0; rzad < r; rzad++ )  

        

for

int

 aleja = 0; aleja < a; aleja++ )  

        { 
             plac[rzad][aleja].ile = rand() % (MAX_K + 1); 
             ile_kont += plac[rzad][aleja].ile; 
             

for

 (

int

 k = 0; k < plac[rzad][aleja].ile; k++)  

             { 
                  plac[rzad][aleja].stos[k].waga = rand() % 100 + 1; 
                  plac[rzad][aleja].stos[k].wlasciciel[0]  
                        = static_cast<char>(rand() % (90 - 65 + 1) + 65); 
                  plac[rzad][aleja].stos[k].wlasciciel[1] = '\0'; 
             } 
        } 
    

return

 ile_kont; 


 

 
 
 
 
 

background image

S t r o n a

 | 7                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

 

// --- dla ka

ż

dego stosu wypisanie rz

ę

du i alei oraz zawarto

ś

ci wszystkich jego kontenerów 

 

void

 pisz_plac( stos_kontenerow  plac[][MAX_A], 

int

 r, 

int

 a ) 


     

for

int

 rzad = 0; rzad < r; rzad++ ) 

        

for

int

 aleja = 0; aleja < a; aleja++ )  

        { 
             cout << setw(10) << rzad+1 << setw(3) << aleja+1 << endl; 
             

for

 (

int

 k = 0; k < plac[rzad][aleja].ile; k++) 

                  cout << setw(3) << k + 1  
                       << setw(3) << plac[rzad][aleja].stos[k].waga 
                       << setw(2) << plac[rzad][aleja].stos[k].wlasciciel  
                       << endl; 
        } 

 

// ---- wyznaczenie współrz

ę

dnych (rzad, aleja, wys) kontenerów wła

ś

ciciela o nazwie  

//      danej jako czwarty parametr funkcji 

 

void

 szukaj(stos_kontenerow plac[][MAX_A], 

int

 r, 

int

 a, 

char

 nazwa[], trojka_indeksow ind[], 

int

 &n) 


      n = 0; 
      

for

int

 rzad = 0; rzad < r; rzad++ ) 

          

for

int

 aleja = 0; aleja < a; aleja++ ) 

          { 
              

for

 (

int

 k = 0; k < plac[rzad][aleja].ile; k++) 

                 

if

( !strcmp(plac[rzad][aleja].stos[k].wlasciciel, nazwa) ) 

                 { 
                     ind[n].rzad = rzad; 
                     ind[n].aleja = aleja; 
                     ind[n].wys = k; 
                     n++; 
                 } 
          } 

 

// --- wypisanie trójek indeksów (rzad, aleja, wys) identyfikuj

ą

cych poło

ż

enie kontenera 

 

void

 pisz_ind( trojka_indeksow ind[], 

int

 n ) 


     

for

int

 i = 0; i < n; i++ ) 

         cout << setw(3) << ind[i].rzad + 1  
              << setw(3) << ind[i].aleja + 1 
              << setw(3) << ind[i].wys + 1  
              << endl; 

 

// --- wypisanie "mapy" placu z podaniem liczby kontenerów na ka

ż

dym ze stosów 

 

void

 rysuj_plac( stos_kontenerow  plac[][MAX_A], int r, int a ) 


    

for

int

 rzad = 0; rzad < r; rzad++ ) { 

        

for

int

 aleja = 0; aleja < a; aleja++ ) 

            cout << setw(3) << plac[rzad][aleja].ile; 
        cout << endl; 
    }         

 

int

 main() 


    stos_kontenerow plac[MAX_R][MAX_A]; 
    

int

 r, a; 

    cout << "

Podaj rozmiary placu:"

 << endl; 

    cout << 

"rzedy: "

    cin >> r; 
    cout << 

"aleje: "

    cin >> a; 

     

    

int

 ile_kont = gen_plac( plac, r, a ); 

    cout << 

"Wygenerowano "

 << ile_kont << 

" kontenerow"

 << endl; 

     

    rysuj_plac( plac, r, a );     
    pisz_plac ( plac, r, a ); 

 

    trojka_indeksow ind[MAX_R*MAX_A*MAX_K]; 
    

char

 nazwa[MAX_N_T];                     

// nazwa wła

ś

ciciela, którego kontenerów szukamy 

    

int

 n;                      

     

    

background image

S t r o n a

 | 8                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

    
    cout << 

"Podaj nazwe klienta ktorego kontenerow poszukujesz: "

    cin >> nazwa;   
    szukaj( plac, r, a, nazwa, ind, n ); 
    cout << 

"Kontenery klienta znajduja sie w nastepujacych miejscach"

 << endl; 

    pisz_ind( ind, n ); 
         
    system(

"pause"

); 

    

return

 0; 

Pytania 

1.

 

Jakiego typu są poniższe dane? 

c)

 

plac[1][0] 

d)

 

plac[1][0].stos[1] 

e)

 

plac[1][0].stos[1].waga 

f)

 

plac[1][0].stos[1].wlasciciel 

g)

 

plac[1][0].stos[1].wlasciciel[1] 

2.

 

Które z poniższych zdań najlepiej opisuje typ zmiennej plac?  

a)

 

dwuwymiarowa tablica struktur, z których każda ma trzy pola będące liczbami całkowitymi, 

b)

 

dwuwymiarowa  tablica  struktur,  z  których  każda  ma  przynajmniej  jedno  pole  będące  tablicą 

jednowymiarową, 

c)

 

 struktura zawierająca pole będące tablicą jednowymiarową oraz pole będące liczbą całkowitą, 

d)

 

dwuwymiarowa tablica struktur, z których każda ma jedno pole będące tablicą jednowymiarową 

o elementach, które są strukturami,  oraz drugie pole typu całkowitego. 

3.

 

Funkcja szukaj ma aż sześć parametrów. Jak można uniknąć przesyłania tak dużej liczby parametrów, 

nie odbierając funkcji danych niezbędnych do jej poprawnego działania? 

Odpowiedzi 

1.

 

Poszczególne dane są następujących typów: 

c)

 

stos_kontenerow[][] 

d)

 

kontener 

e)

 

int 

f)

 

char[] 

g)

 

char 

2.

 

zdanie d) 

3.

 

Niektóre  z  parametrów  tej  funkcji,  np.  r  oraz  a,  są  ściśle  związane  ze  zmienną  plac  (są  aktualnymi 

rozmiarami  tablicy  plac).  Zamiast  tablicy  plac  można  zdefiniować  strukturę  typu  t_sklad  zawierającą 

trzy pola: placr oraz a.   

struct t_sklad{ 

      stos_kontenerow plac[MAX_R][MAX_A]; 

      int r; 

      int a; 

}; 

Jest  to  definicja  analogiczna  do  definicji  stos_kontenerow.  Tą  samą  konstrukcję  można  zastosować 

dla  tablicy  ind  i  jej  rozmiaru  n  definiując  zawierającą  je  strukturę  typu  t_indeksy.  Pozwala  to  na 

zmniejszenie liczby parametrów funkcji szukaj z 6 do 3. Nagłówek tej funkcji może być następujący:   

void szukaj (const t_sklad &sklad, char nazwa[], indeksy &indeksy) 

 

background image

S t r o n a

 | 9                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Testy 

 

1.

 

Wskaż  poprawne  deklaracje  struktury: 

a)

 

struct {int atr;} 

b)

 

struct struktura {int atr;} 

c)

 

struct struktura int atr; 

d)

 

struct struktura {int atr;}; 

2.

 

Które instrukcje są prawidłowymi instrukcjami dostępu do składowej  atr  struktury  s ? 

a)

 

s->atr; 

b)

 

s.atr; 

c)

 

s[n].atr; 

d)

 

s>>atr; 

3.

 

Które instrukcje są prawidłowymi instrukcjami dostępu do składowej  atr  struktury  *

a)

 

p->atr; 

b)

 

p.atr; 

c)

 

p[n].atr; 

d)

 

p>>atr; 

4.

 

Dane są następujące definicje 

struct osoba { char imie[5]; int wzrost; }; 

osoba A[50]; 

Przy  założeniu,  że  są  to  jedyne  definicje,  wskaż  które  instrukcje  są  prawidłowe  syntaktycznie.  Która  ze 

wskazanych przez ciebie instrukcji może spowodować błąd wykonania? 

a)

 

A[5] = ("Janek",178); 

b)

 

strcpy(A[5].imie,"Wojtek"); 

c)

 

strcpy(A.imie[3],"Adam"); 

d)

 

strcpy(A[15].imie,"Adam"); 

Odpowiedzi 

 

Test 1:    d) 

Test 2:    b) 

Test 3:    a) 

Test 4:    syntaktycznie  b)  oraz  d),  

                błąd może spowodować instrukcja b) ponieważ "Wojtek" ma więcej niż cztery znaki.

 

Zadania przygotowujące do laboratorium 

 

Zapoznaj się z treścią zadania, przemyśl rozwiązanie a następnie napisz, uruchom i przetestuj poszczególne 

funkcje  programu  będącego  prostą  bazą  danych  osób.    Przykład  realizacji  całego  programu  znajduje  się 

w pliku L6_F0_Z1.cpp 

 

 

background image

S t r o n a

 | 10                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

Zadanie  L6_F0_Z1 

Napisz  program  obsługujący  prostą  bazę  danych  osobowych.  Jako  podstawowej  struktury  danych  użyj 

jednowymiarowej  tablicy  struktur  typu  osoba,  z  których  każda  ma  pola:  nazwisko,  imie  i  pesel  będące 

napisami o odpowiednio dobranej długości. Program powinien zawierać między innymi następujące funkcje: 

a)

 

wypisującą dane pojedynczej osoby, 

b)

 

wypisującą listę wszystkich osób,  

c)

 

znajdującą osobę o podanym numerze pesel, 

d)

 

dodającą jedną osobę do bazy danych,  

e)

 

znajdującą wszystkie osoby o podanym nazwisku, 

f)

 

wypisującą listę wszystkich osób  o podanym nazwisku. 

Rozwiązanie 

Definicje podstawowych struktur danych: 

 

const int

 MAX_OS = 20;          

//

 

maksymalna liczba osób w tablicy

  

const int

 D_PES = 11;           

// liczba znaków w numerze pesel 

const int

 D_NAZ = 20;           

// maksymalna liczba znaków w nazwisku

 

const int

 D_IM = 10;            

// maksymalna liczba znaków w imieniu 

const int

 D_PES_T = D_PES + 1;  

// do u

ż

ycia w definicji napisu 

const int

 D_NAZ_T = D_NAZ + 1;  

//           -- || --

 

const int

 D_IM_T = D_IM + 1;    

//           -- || --

 

 

struct

 osoba{ 

    

char

 pesel[D_PES_T]; 

    

char

 imie[D_IM_T]; 

    

char

 nazwisko[D_NAZ_T]; 

}; 

 

int

 main() 

  osoba L[MAX_OS];    

// tablica zawieraj

ą

ca struktury typu osoba  - główna struktura danych

 

  

int

 ile_osob;       

// liczba osób w tablicy L

  

 

  

// ...  

 

 

a)

 

Wypisanie danych jednej osoby. 

 

void

 pisz_osobe (

const

 osoba os) 


  cout << setw(sizeof(os.pesel)+2)    << os.pesel; 
  cout << setw(sizeof(os.imie)+2)     << os.imie; 
  cout << setw(sizeof(os.nazwisko)+2) << os.nazwisko;  
  cout << endl; 

 

 

b)

 

Wypisanie listy wszystkich osób. 

 

void

 pisz_naglowek_listy () 


  cout << endl; 
  cout << 

"       pesel     |   imie    |      nazwisko       "

 << endl; 

  cout << 

"---------------------------------------------------"

 << endl; 


 

 
 
 

background image

S t r o n a

 | 11                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

 
 

 

void

 lista_osob (

const

 osoba L[], 

const int

 ile_osob) 


  pisz_naglowek_listy(); 
  

for

 (

int

 i=0; i<ile_osob; i++) 

     pisz_osobe(L[i]); 
  cout << 

"---------------------------------------------------"

 << endl; 

  cout << 

"liczba osob = "

 << ile_osob << endl; 

  cout << endl; 

 

 

c)

 

Wyznaczenie indeksu osoby o podanym numerze pesel. 

 

// Sprawdzenie czy w

ś

ród elementów o indeksach 0..ile_osob-1 

// istnieje element o zadanym numerze pesel: 
//   - je

ż

eli tak zwraca indeks tego elementu 

//   - je

ż

eli nie zwraca -1 

// Uwaga: pesel ma w tablicy unikalna warto

ść

 

// ----------------------------------------------------------- 

 

int

 szukaj_pes (

const

 osoba L[], 

const int

 ile_osob, 

char

 pesel[]) 


    

for

 (

int

 i = 0; i < ile_osob; i++) 

       

if

 (strcmp(L[i].pesel,pesel) == 0) 

return

(i); 

    

return

(-1); 


 

 

d)

 

Dodanie danych jednej osoby. 

 

// Dodanie osoby z kontrol

ą

 danych: 

//   - przekroczenie maksymalnej liczby osób MAX_OS 
//   - sprawdzenie unikalno

ś

ci numeru pesel 

// ----------------------------------------------------------- 

 

void

 dodanie_osoby (osoba L[], 

int

 &ile_osob) 


  

char

 pesel[D_PES_T]; 

  

int

 ind; 

   
  

if

 (ile_osob < MAX_OS) 

  { 
    cout << 

"Pesel: "

    cin >> pesel; 
    

if

 ( (ind = szukaj_pes(L,ile_osob,pesel)) == -1) 

    {  
      strcpy(L[ile_osob].pesel,pesel); 
      cout << 

"Nazwisko: "

      cin >> L[ile_osob].nazwisko; 
      cout << 

"Imie: "

      cin >> L[ile_osob].imie; 
      ile_osob ++; 
    } 
    

else  

    { 
      cout << 

"Osoba o numerze pesel "

 << pesel  

           << 

" jest juz zapisana w bazie danych"

 << endl; 

      pisz_osobe(L[ind]); 
      system(

"pause"

); 

    } 
  } 
  

else  

  { 
     cout << 

"Nie mozna dopisac kolejnej osoby - brak pamieci ;)"

 << endl; 

     system(

"pause"

); 

  } 

 

 

 

background image

S t r o n a

 | 12                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

e)

 

Wyznaczenie indeksów osób o podanym nazwisku. 

 

// Sprawdzenie czy w

ś

ród osób o indeksach 0..ile_osob-1 istnieje osoba o zadanym nazwisku: 

//   - je

ż

eli tak, to zwracana jest tablica Ind zawieraj

ą

ca indeksy znalezionych osób 

//     natomiast warto

ś

ci

ą

 funkcji jest ilo

ść

 tych osób 

//   - je

ż

eli nie, to warto

ś

ci

ą

 funkcji jest 0 a tablica Ind mo

ż

e zawiera

ć

 nieokre

ś

lone warto

ś

ci 

// --------------------------------------------------------------------------------------------- 

 

int

 szukaj_naz (

const 

osoba L[], 

const int

 ile_osob, 

char

 nazwisko[], 

int

 Ind[]) 


    

int

 ile = 0; 

    

for

 (

int

 i = 0; i < ile_osob; i++) 

       

if

 (strcmp(L[i].nazwisko,nazwisko) == 0)  Ind[ile++] = i; 

    

return

(ile); 


 

 

f)

 

Wypisanie listy osób na podstawie tablicy ich indeksów. 

 

void

 lista_osob_ind (

const

 osoba L[], 

const

 int Ind[], 

const int

 ile_ind) 


  pisz_naglowek_listy(); 
  

for

 (

int

 i=0; i<ile_ind; i++) 

     pisz_osobe(L[Ind[i]]); 
  cout << 

"---------------------------------------------------"

 << endl; 

  cout << 

"liczba osob = "

 << ile_ind << endl; 

  cout << endl; 

 

Zadania do samodzielnego rozwiązania po laboratorium 

L6_F3_Z1 

Przyjmując,  że  przedział  na  osi  liczb  rzeczywistych  reprezentowany  jest  jako  struktura  o  dwóch  polach, 

w których zapisane są liczby rzeczywiste będące odpowiednio lewym oraz prawym końcem przedziału, napisz 

funkcję,  której  wartość  mówi  o  wzajemnym  położeniu  dwóch  danych  na  jej  wejściu  przedziałów  p

1

,  p

2

Funkcja powinna rozróżniać następujące sytuacje:   

a)

 

p

1

 zawiera się w p

2

 

b)

 

p

2

 zawiera się w p

1

  

c)

 

przedziały są rozłączne 

d)

 

inne położenie  ( czyli żadne z opisanych w punktach a) – c) ) 

L6_F3_Z2 

Najmniejszy  prostokąt  ograniczający  (ang.  minimum  bounding  rectangle),  w  skrócie  oznaczany  MBR,  jest 

często wykorzystywany do przybliżonej reprezentacji obiektów graficznych i jest rozumiany jako najmniejszy 

prostokąt o bokach równoległych do osi układu współrzędnych, zawierający wszystkie punkty obiektu, który 

ogranicza.  Napisz  program,  który  wyznacza  MBR  dla  zbioru  punktów  reprezentowanego  tak,  jak 

w przykładzie  L6_F0_P2.  Prostokąt  MBR  zdefiniuj  jako  strukturę  składającą  się  z  czterech  pól  typu 

rzeczywistego,  w  których  zapisane  są  współrzędne  lewego  dolnego  i  prawego  górnego  wierzchołka 

prostokąta.  Czy  potrafisz  napisać  funkcję  rozstrzygającą  czy  dwa  prostokąty  MBR  przecinają  się  czy 

są rozłączne?  

 

 

background image

S t r o n a

 | 13                                                                                               WETI  Politechnika Gdańska, POP v.1.0.2 

L6_F3_Z3 

Przeanalizuj  poniższy  fragment  programu  służący  do  generowania  talii  kart  reprezentowanej  jako  tablica 

o elementach  typu  t_karta.  Następnie  napisz  program  zawierający  funkcje:  generującą  talię  kart,  tasującą 

talię  oraz  funkcję  porządkującą  karty  według  "koloru  i  figury"  (skorzystaj  z  funkcji  karta_cmp,  patrz 

L6_F0_P3). Jak zmienić funkcję porównującą, aby porządkowanie odbywało się względem "figury i koloru"? 

... 

const

 

int

 LK = 52;       

// liczba kart w talii 

struct

 t_karta { 

        

int

 kolor; 

        

int

 figura; 

}; 
 
t_karta talia[LK]; 
... 
 

int

 i = 0; 

 

for

int

 kolor = 1; kolor <=4 ; kolor++ ) 

  

for

int

 figura = 1; figura <= 13; figura++ ) { 

      talia[i].kolor = kolor; 
      talia[i].figura = figura; 
      i++; 
  } 
... 

 

 
L6_F3_Z4 

Do programu L6_F0_Z1.cpp dopisz funkcję usuwającą wszystkie osoby o podanym nazwisku.