cz8

cz8



Programowanie

Znamy już przyczynę problemu. Jak go rozwiązać? W posiadanej przez nas wersji

Jak to robi GCC Dlaczego fdevopen jest tak pamięciochłonna?

Dokumentacja funkcji fdevopcn informuje nas, żc tunkcja ta tworzy nową strukturę FILE, alokując w tym celu dynamicznie pamięć. Daje nam to dość ciekawą możliwość: gdy zaczynamy używać na przykład interfejsu RS232, dokonując powiązania poprzez funkcję fdevnpcn, zajmujemy pamięć. Gdy teraz zamkniemy połączenie za pomocą funkcji felose - pamięć zostanie zwolniona. Jest

Dynamiczna alokacja pamięci danych wymaga umieszczenia dość skomplikowanych procedur w pamięci programu. Czy to się opłaca? Zauważyłeś może, że do tej pory nie zapoznałem Cię z funkcją felose? Prawda jest taka, żc w mikrokontrolerze bardzo rzadko mamy do czynienia z sytuacją, gdy chcemy zamknąć otwarty strumień.

W ogromnej większości przypadków to po prostu nic ma sensu. Zwykle dokonamy powiązania wszystkich strumieni w chwili startu programu i nie będziemy ich nigdy zwalniać. Wykorzystanie dynamicznego przydzielania pamięci jest więc dla nas przerostem formy nad treścią.

biblioteki stdio nie ma innej niż fdevopen funkcji umożliwiającej powiązanie strumienia ze zmienną FILE. Rozwiązaniem byłoby samodzielne utworzenie zmiennej typu FILE w normalny, poznany przez nas do tej pory sposób - bez dynamicznego zajmowania pamięci. Następnie musielibyśmy samodzicl-

Ustmg 60 - wykorzystanie funkcjifprintf

int mainfyoid)

{

FILE* IRS; int a = 1234; int b = Oxff;

//////////////////////////////

// inicjacja portu szeregowego

(..0

// Koniec inicjacji

//////////////////////////////

H Inicjacja we/wy

£‘SS = fdevopen(rs_put, rs_get, 0);

farintf P(fRS i PSTO( „a(%%d)=%d\r\n"

„a(»Sx)=%x\r\n"

„a(%%x)=%x\r\n‘‘

„b(%%#x)=9ś#x\r\n"

„b(%%o)=Sto\r\n"),

nie wpisać do niej odpowiednie wartości. Nie jest to eleganckie rozwiązanie... jest ponadto (pozornie) niemożliwe.

Zmienna typu FILE jest definiowana w ramach omawianej biblioteki jako struktura. Zapoznaj się z ramką opisującą korzystanie z tych użytecznych tworów. Trochę przydatnych informacji o tym, jak używać struktury jako nowego typu danych, znajdziesz w ramce ABC... C typedef- nazywanie typu. Zajrzyj do niej. Niedługo będziemy korzystać z opisanej tam możliwości.

Początek naszej idei pozbycia się problemu pokazuje listing 61, będący przeróbką programu z listingu 59. Chwilowo nie wpisujemy nic do struktury (jeszcze nic wiemy, jakie posiada składowe). Ważne jest jedynie sprawdzenie, jak zareaguje kompilator. Okaże się, że już na tym poziomie pojawią się problemy. Spróbuj skompilować taki program. Jeśli wszystko zrobiłeś prawidłowo, to kompilacja pójdzie... źle. Otrzymasz komunikat o błędzie polegającym na tym, że nie jest znany rozmiar struktury gJRS. Cóż to za dziwna struktura, której rozmiar jest nieokreś-

{


pPt-:


Sytuacja bardzo zbliżona do poprzed- memc niej, korzystamy jedynie z innego operatora.

GO prawda możliwe jest działanie bardziej „zakręco-

(«p?t).X = 0 ;

Przypomnę, żc za pomocą operatora gwiazdki dostajemy się do obiektu wskazywanego przez wskaźnik. Możemy korzystać z tego jak powyżej, ale jest to mniej eleganckie j mniej czytelne niż podanyj wcześniej sposób.

Przedstawioną funkcję wywołamy jak niżej;

; Zeruj(4punktA) _

Przykład może nie jest zaawansowany, ale pokazuje już siłę, jaka drzemie w strukturach. Zauważ, że do funkcji Zeruj przekazujemy tak naprawdę tylko jeden argument - 16-bitowy adres a w jej wnętrzu mamy dostęp do wszystkich pól naszej struktury.

Nadanie wartości początkowych

Nadanie wartości początkowych strukturze odbywa się podobnie jak miało to miejsce w przypadku tablic. W nawiasach klamrowych musimy podać wartości


Wspomnialem o tym, że zmienna typu FILE to struktura. Struktura to bardzo wygodny obiekt, w którym możemy pogrupować wszystkie potrzebne nam zmienne jakiegoś typu. Wyobraźmy sobie, że chcemy utworzyć strukturę zawierającą informację o punkcie: struct [punkt]

{

int x; int y; int z;

} [punkLA, punktB, x];

Pola umieszczone w nawiasach kwadratowych są opcjonalne. Zaraz zą słowem kluczowym struct występuje etykieta. Jeśli umieścimy ją tutaj, będziemy mogli wykorzystać ją zamiast wszystkiego, co zawarliśmy w nawiasach'klamrowych. Przykładowo, chcemy utworzyć kolejny punkt:

I struct punkt Kolejny;

Z kolei wszystko, co ż.ostanie umieszczone za nawiasem klamrowym, powoduje utworzenie odpowiednich zmiennych. W praktyce składnia:

Struct {...} zmienna;

Oznacza to samo co:

; int zmienna;

Z tym że w pierwszym przypadku tworzymy obiekt typu podanej struktury, w drugim tworzymy obiekt typu int.

W nawiasach klamrowych umieszczamy informacje o składowych struktury. Po prostu wymieniamy kolejno występujące w niej zmienne oraz nadajemy im nazwy. Możemy korzystać tutaj z wszelkich dostępnych typów zmiennych. Wcześniej zdeklarowane struktury także mogą być wykorzystane.

Należy pilnować jedynie, aby nazwy składowych nie pokrywały się między sobą. Jednak nazwa struktury może przyjąć postać identyczną jak na przykład etykieta czy nazwa zmiennej globalnej - nie ma obawy o błędy w programie.

Dostęp do odpowiedniej zmiennej w strukturze jest rozróżniany poprzez kontekst.

Dostęp do składowych, wykorzystanie w programie

Do składowych Struktury możemy się dostać na dwa sposoby. Pierwszy z nich dotyczy przypadku, gdy dysponujemy odpowiednią zmienną. W naszym przypadku rueclj będzie to pfmltlA. Do poszczególnych pól Struktury dostaniemy się za pomocą operatora kropki: punkt A. x = 0; punktA.y = 1;

punktA.z = 2;

Myślę, że nie budzi to wątpliwości. Jeśli teraz wydaje się nienaturalne, stanie się prostsze podczas pisania przykładów.

Drugi sposób dotyczy momentu, gdy mamy dostęp do wskaźnika na strukturę. Można wyobrazić sobie następujący przykład:

31 d Zeruj (struct punkt *pPt)

< = 0;

każdej składowej. Pamiętaj, że takie działanie dozwolone jest jedynie w chwili tworzenia zmiennej: struct punkt z = {0, 1, 2};

Operowanie całymi strukturami

Jeśli stworzysz własną strukturę, możesz przekonać się, że nic działają na. nich standardowe operatory. Zapis jak poniżej jest nieprawidłowy: puntA = punktB;

Strukturę należy traktować jako pewien ciąg danych w pamięci (obrazek w ramce). Sprawa jest zbliżona do działania tablic. Mamy dwie możliwości zastąpienia powyższego przepisania. Jedna polega na przepisywaniu wszystkich pól, dla których powyższe działanie jest dozwolone: punktA.x = punktB.x; punktA.y = punktB.y; punktA.z = punktB.z;

Poła x, y, z są typu int. Ożycie operatora przypisania na zmiennych typu int jest możliwe.

Druga, wygodniejsza i często bardziej optymalna metoda polega na przekopiowaniu bloku pamięci: :py(&punktA, &punktB, SIzeof (punktA)) ;

Funkcja memepy skopiuje dane z obszaru wskazywanego przez drugi argument do obszaru wskazywanego przez pierwszy argument Trzeci argument podaje w bajtach ilość danych do skopiowania. Operator sizeof zostanie w czasie kompilacji zamieniony na odpowiednią wartość.

j Każda składowa ; typu int zajmie

Wskaźnik na zmiennąpsn&Ł4

38 Marzec 2006 Elektronika dla Wszystkich


Wyszukiwarka

Podobne podstrony:
cz4 Programowan ie Jak to robi GCC Co to są tak naprawdę zmienne lokalne? Kiedy zdefiniujesz jakąś
[BADANIA OPERACYJNE - PROGRAMOWANIE LINIOWE] Koszalin 20063 Problem transportowy 3.1 Wstęp Rozwiązan
nr w szkolnym zestawie programów: 37/SP/2014 program: Zajęcia techniczne 4-6 podręcznik: tytuł: Jak
FAQ (3) - często zadawane pytania Macie na płycie pełne wersje programów, ale wymagają one rejestrac
opracowane w tym celu metody obliczeniowe. Jedną z nich jest, poznana już przez nas w wersji dla obw
ku. Nikt nie wie, jak to robi. Należy do wielkiej ferajny i wszyscy złodzieje są na jej usługi. Jest
c) kiedy już wiemy, że inne wartości stają się dla nas interesujące, ważniejsze, to właściwie zmiana
IMG 9 spojlowanie programu robinsonowie :c; program może się już nie pozbierać. Jak wykrzyknął jeden
Slajd49 4 Metoda simpleks Jak już wspomniano, program liniowy może mieć więcej niż jedno rozwiązanie
Jak widać, program zawiera wiele treści o problematyce zdrowotnej, chorobach cywilizacyjnych, możliw
68164 skanuj0154 Odwrócenie to potężna część Pracy, lak długo, jak długo myślisz, że przyczyna probl
Tomasz HOFFMANN one leżeć zarówno po stronie nadawcy, jak i odbiorcy. Zazwyczaj przyczyną problemów
CCI20100224071 wielką część jego powieści. Wiem, że ze wszystkich problemów żaden go nie niepokoił
-    Znam go? -    Nie, nie sądzę! Mogą już iść? - chciała jak najszyb
ScannedImage ZADANIE HERMENEUTYKI1 ( Esej ten ma na celu opisanie problemu hermeneutyczne-go tak, ja
Osteoporoza obraz kliniczny, leczenie, profilaktyka (1) 18.7. Zapobieganie endometriozie Zapobiegan

więcej podobnych podstron