tej lekcji wr≤cimy do operowania zmiennymi. Znasz ju┐ podstawowe typy (int, float, char) i umiesz przechowywaµ je w pamiΩci. Dla ka┐dej nowej zmiennej deklarowa│e╢ nazwΩ i przypisywa│e╢ j▒ do okre╢lonego typu. Nied│ugo zaczniesz pisaµ programy bardziej skomplikowane, w kt≤rych bΩdziesz u┐ywa│ wielu zmiennych. Deklarowanie ka┐dej z nich z osobna oka┐e siΩ wtedy zupe│nie niepraktyczne.
Dlatego poznasz dzi╢ tablice. Tablica jest to uporz▒dkowany zbi≤r wielu zmiennych jednego typu. Typ tych zmiennych okre╢la typ tablicy. Na przyk│ad, je╢li w tablicy bΩdziemy przechowywaµ liczby typu int, to tablica te┐ jest typu int. Uporz▒dkowanie tablicy oznacza, ┐e jej elementy nie s▒ przechowywane w niej ot tak, lecz ka┐dy ma swoje miejsce.
Deklaracja i proste u┐ycie tablicy wygl▒da tak:
#include <stdio.h> #include <conio.h> main (void) { int tablica[5]; int suma; clrscr(); printf("Podaj pierwsz▒ liczbΩ: \n"); scanf("%d",&tablica[0]); printf("Podaj drug▒ liczbΩ: \n"); scanf("%d",&tablica[1]); printf("Podaj trzeci▒ liczbΩ: \n"); scanf("%d",&tablica[2]); tablica[3]=5; tablica[4]=23; suma=(tablica[0]+tablica[1]+tablica[2]+tablica[3]+tablica[4]); printf("Suma element≤w tablicy wynosi: %d\n",suma); getch(); return 0 ; }
Jak │atwo zauwa┐yµ, deklaracja tablicy wygl▒da prawie identycznie jak deklaracja │a±cucha (tak naprawdΩ jest jednak odwrotnie, bo to │a±cuch by│ traktowany jako tablica znak≤w). Nale┐y w niej jednak zaznaczyµ ilo╢µ element≤w znajduj▒cych siΩ p≤╝niej w tablicy. Nie musimy u┐ywaµ ich wszystkich, lecz np. pierwsze trzy, ale zawsze nale┐y okre╢liµ ich ilo╢µ i dopilnowaµ, aby tej granicy nie przekroczyµ. Inaczej m≤wi▒c, je╢li na samym pocz▒tku zadeklarujemy tablicΩ: int tablica[10], to nie mo┐emy potem u┐ywaµ elementu tablica[11]. Zauwa┐my r≤wnie┐, ┐e zliczanie element≤w tablicy zaczynamy od elementu numer zero. Dlatego tablica w powy┐szym przyk│adzie jest tablic▒ piΩcioelementow▒, zawiera bowiem elementy o numerach: 0,1,2,3,4.
Nasz przyk│adowy program oblicza sumΩ z element≤w tablicy. Elementy te mo┐na wczytaµ z klawiatury dziΩki funkcji scanf() lub te┐ przypisaµ im warto╢µ w kodzie programu. Poniewa┐ wszystkie elementy tablicy s▒ typu int, zatem tablica ta te┐ jest typu int. Nie mo┐e siΩ zdarzyµ, ┐e jeden z element≤w by│by innego typu.
Przedstawiona tu tablica by│a niewielka, ale mo┐na te┐ tworzyµ wiΩksze tablice. Opr≤cz tego mo┐na r≤wnie┐ u┐ywaµ tablic dwu- i wiΩcej wymiarowych. Tablica dwuwymiarowa w zasadzie nie r≤┐ni siΩ od uk│adu wsp≤│rzΩdnych kartezja±skich. Deklaracja tablicy dwuwymiarowej mo┐e wygl▒daµ tak: int tablica[9][9];. Znaczy to, ┐e tablica ma w sumie 100 element≤w (np. 10 wierszy i 10 kolumn). Odwo│anie do kt≤rego╢ z element≤w tej tablicy zapisujemy np. tablica[nr_kolumny][nr_wiersza] (choµ, wydaje siΩ, ze powinno byµ na odwr≤t, ale jest w│a╢nie tak). Elementu tablicy mo┐emy u┐ywaµ tak jak ka┐dej innej zmiennej. Np. je╢li tablica zawiera liczby mo┐na napisaµ: a=9*tablica[3][1]+5;.
W rzeczywisto╢ci zdarza siΩ jednak czΩsto, ┐e potrzebujemy przechowaµ w pamiΩci dane r≤┐nych typ≤w, jednak┐e w wielu kopiach. Na przyk│ad tworzymy bazΩ danych z informacjami na temat uczni≤w w jakiej╢ klasie. O ka┐dej osobie potrzebujemy zapamiΩtaµ jego imiΩ, nazwisko, numer w dzienniku i ╢redni▒. Widaµ wiΩc, ┐e wszystkie te dane nie mog▒ byµ jednego typu (imiΩ i nazwisko - typ char*, numer - typ int, ╢rednia - typ float). Oczywi╢cie mo┐na stworzyµ cztery tablice okre╢lonych typ≤w, i w ka┐dej z nich przechowywaµ okre╢lone informacje, np. w pierwszej imiona, w drugiej nazwiska itp. Jest to jednak niezbyt praktyczne wyj╢cie, poniewa┐ │atwo popl▒taµ informacje o ka┐dej z os≤b.
Do rozwi▒zania tego problemu s│u┐▒ rekordy. Zbieraj▒ one w ca│o╢µ informacje r≤┐nych typ≤w.
#include <stdio.h> #include <conio.h> main (void) { struct { char *imie, *nazwisko; int numer; float srednia; }uczen[30]; clrscr(); uczen[0].imie="Anna"; uczen[0].nazwisko="Miedzianowska"; uczen[0].numer=1; uczen[0].srednia=4.5; uczen[0].imie="Jan"; uczen[0].nazwisko="Kowalski"; uczen[0].numer=2; uczen[0].srednia=4.0; printf("ImiΩ pierwszej osoby to %s.\n",uczen[0].imie); printf("Nazwisko pierwszej osoby to %s.\n",uczen[0].nazwisko); printf("ªrednia drugiej osoby to %.2f.\n",uczen[0].srednia); getch(); return 0 ; }
Po uruchomieniu program napisze:
ImiΩ pierwszej osoby to Anna. Nazwisko pierwszej osoby to Miedzianowska. ªrednia drugiej osoby to 4.00
Rekord deklarujemy jak ka┐d▒ inn▒ zmienn▒. DeklaracjΩ rekordu rozpoczynamy s│≤wkiem struct. NastΩpnie miΩdzy nawiasami klamrowymi deklarujemy zmienne wchodz▒ce w sk│ad rekordu. Nazywa siΩ to polami rekordu. Po zamkniΩciu nawiasu klamrowego piszemy nazwΩ rekordu. Mo┐e to byµ pojedynczy rekord postaci:
struct{ int zmienna1; float zmienna2; char zmienna3; }nazwa;
Takich rekord≤w mo┐emy zadeklarowaµ kilka lub te┐ utworzyµ zbi≤r takich samych rekord≤w w postaci tablicy (tak, jak w przyk│adzie). Pojedynczy rekord jest wiΩc traktowany jako pojedyncza zmienna. Ta zmienna m≤wi nam jednak o wiele wiΩcej ni┐ pojedyncza zmienna typu np. int. Rekordy zebrane w tablicy deklaruje siΩ na zasadzie:
struct{ int zmienna1; float zmienna2; char zmienna3; }nazwa[ilosc_pol];
A jak odczytaµ warto╢ci zapisane do rekordu? Nie mo┐na wypisaµ warto╢ci rekordu (np. w funkcji printf), je╢li nie okre╢limy pola, o kt≤re nam chodzi. Znaczy to, nie mo┐emy zapytaµ programu jednocze╢nie o ca│y rekord numer1, ale mo┐emy zapytaµ o ka┐de z p≤l rekordu numer1. U╢ci╢lenie, o jakie pole nam chodzi nastΩpuje po napisaniu nazwy tablicy rekord≤w, numeru rekordu w nawiasie kwadratowym, a nastΩpnie po kropce wypisaniu nazwy interesuj▒cego pola. Tak w│a╢nie zrobili╢my w naszym przyk│adzie.
Podsumowuj▒c: