Napity w pamięci programu
Podaj wyfafany Jfz^c WfbUntoc#
Kontynuujemy dziś rozwijanie naszej zaawansowanej obsługi wyświetlacza alfanumerycznego. Stworzymy interfejs umożliwiający obsługę wiciu języków jednocześnie. Przy tej okazji poznamy tablicę wielowymiarową oraz typ wyliczeniowy. Pokażę, w jaki sposób umieścić w pamięci programu tablicę wskazująca na napisy w pamięci programu ta konstrukcja wbrew pozorom nie jest tak bardzo oczywista.
Dzisiejszy program będzie korzystał z większości plików, które zostały utworzone w poprzedniej części. Utwórz nowy katalog i skopiuj do niego pliki icd.h, Icd.c, makra.h oraz harddef.h z części 9. Możesz skopiować także dotychczasowy makefite, jednak z plików źródłowych usuwamy local.c, a polu TARGET przypisujemy multilang (nazwę nowego projektu).
W katalogu projektu utwórz nowy folder o nazwie iang. Umieścimy w nim pliki definiujące wszystkie nasze języki. Proponuję dodanie utworzonego katalogu do projektu Programmcrs Notcpada jako „Magie Folder”. Folder taki odwzorowuje rzeczywistą zawar-
ABC... C
Tablice wielowymiarowe
W ę/yku C tablice wielowymiarowe są Iwonom: w pewien specyficzny sposób. (XI strony logicznej taka tablica jest tablica składającą się z tablic. Wiąże się z lym określony sposób tworzenia oraz obsługi. Przykład utworzenia dwuwymiarowej tablicy: char tablica[z] [ d] ;
Do poszczególnych elementów dostajemy się następująco: tablica [a] [b] « 0;
Nic tak jak ma to miejsce na przykład w Paskalu: tablica [a, b] ■ 0; //Źle!
Fizycznie, w pamięci, elementy rozłożone są tak jak pokazuje rysunek w ramce. Ta wiedza pozwala nam obliczyć pozycję w pamięci danego elementu. Jest to ważne, jeśli chcemy dostać się do lahlicy za pomocą wskaźnika. Dla naszej tablicy:
Przesunięcie = a*3 + b
Tablicę do funkcji możemy przekazać r.a dwa sposoby. Pierwszy z nich to poprzez wskaźnik: void ZerujP(char* pt, uint 16_t ilosc)
{
for(; ilosoO; ilosc-)
*(pn-0 ■ 0;
Przykład wywołania takiej funkcji dla naszej .ablicy: Zeruj PC (char*) tablica, 6);
tość katalogu. Klikamy prawym klawiszem na ikonie projektu w oknie Projects i z pojawia-
Idea rozwiązania.
Myślą przewodnią tworzonego dziś wielojęzycznego interfejsu jest oddzielenie wszystkich napisów od reszty aplikacji. Interlejs powinien być napisany w taki sposób, aby wybór języka następował tylko w jednym miejscu (na przykład odpowiednia pozycja menu) i tylko w tym miejscu musimy zainteresować się tym, ile języków zostało ..zainstalowanych”, jakie to są języki i jakie są ich nazwy. Cała reszta programu powinna działać niezależnie od w ybranego języka i nie będzie nawet „wiedziała”, jaki „ę?yk został wybrany.
Ideę rozwiązania pokazuje rysunek w ramce. Dla czytelności nic umieściłem tutaj tablicy zawierającej informacje o znakach specjalnych. Napisy nadal umieszczamy w pamięci programu.
Jednak teraz, w stosunku do prostej wersji jedno języcznej, stworzymy tablicę dwuwymiarową, która będzie zawierać wskaźniki na wszystkie łańcuchy. Takie rozwiązanie zajmuje dodatkowo po 2 bajty na każdy napis (szes-nastobitowy wskaźnik) 7 jednej strony
Drugi sposob wymaga jawnego podania rozmiaru tablicy:
void zeruićchar t[2][3])
uinL16_t d|b;
for(a®G; a<2; a++) forCb-0; b<3: b++)
t[a][b] » 0;
Zauważ, że aby obliczyć pozycję elementu w pamięci, kompilator nie potrzebuje informacji o rozmiarze najwyższego wymiaru (2). Rzeczywiście okazuje się, że można go pominąć przy podawaniu iisty argumentów funkcji:
void 7emjCchar t[][3])...
Wywołanie naszej funkcji zerującej przebiegałoby teraz następująco:
Zeruj (tablica);
Co bardzo ważne, dn funkcji /ostanie przesłany jedynie wskaźnik - nic kopia całej tablicy.
Aby zainicjować wstępnie tablicę wielowymiarową, poszczegćlne wiersze grupujemy za pomocą nawiasów klamrowych Powstaje dość intuicyjny zapis Char tablica[2] [3] -{
{‘a’, ‘b\ ‘c’}.
{•A1, ‘B\ ‘C’}
} i
Ponownie najłatwiej powy2szy zapis zrozumieć, odnosząc sic do naszego stwierdzenia, że mamy
jącego się menu wybieramy Add Magie Folder. Uruchomiony zostanie kreator, który zwiększa to zajętość pamięci, jednak / drugiej umożliwia szybkie wyszukanie interesującego nos tekstu. Nie możemy umieszczać tekstów bezpośrecniD w tablicy, ponieważ każdy napis raozc mieć inną długość.
Funkcje korzystające 7 napisów' będą posługiwać się ich identyfikatorem, czyli indeksem w tablicy. Naszym zadaniem będzie także takie zdefiniowanie identyfikatorów, aby ich numeracja b>ła tworzona automatycznie.
do czynienia z tablicą tablic. Tablica dwucicmcatcwa zawiera dane inicjujące każdą z jej składowych, troje-lementowych tablic. Rozumując w identyczny sposób, można inicjować tablice o dowolnej liczbie wymiarów.
Na koniec warte wspomnieć o pewnym drobiazgu, korzystaliśmy już z tablic, których rozmiar był wyliczany automatycznie przez komp:la:or. W przypadku tablic wielowymiarowych automatycznie obliczony może być jedynie wymiar najwyższy.
Char tablica [][] =* //21e
char tablica[] [3] - //Dobrze
d*ix**TK>nt0WB tablica, ikiadaiąca t* z tatte dń**tęcb*tarwńo*ych, składających aię z tabłe citeroetonmtowyęĄ $W»d6jącycn uę z etomantów typu uini16_t
[ uitl5_t t*blic«[?][10][4j}
0 tablic*[C][o][o] 2 tablica[Oj[U][l]
4 tabllc*[C][0][2]
6 tablica[C][0][3]
6 tablica[C][1][0]
10 tablica [C][l][l]
12 tablic*[C][l][2]
14 tablio*[0][l]C3] (...)
168 tablica[l](0]Ci]
Przykład: listing 97
3B Czerwiec 2006 Elektronika dla Wszystkich