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;
}
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 wspx, wspy 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;
};
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;
}
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.
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;
}
}
...
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;
}
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;
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: plac, r 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)
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 *p ?
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
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;
}
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"
);
}
}
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?
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.