Programowanie
Programowanie
ABC... C
Zamieszanie z puts i gets
W praktyce większość funkcji posiada swoje wersje z przedrostkiem f, mogące działać ńa wybranym strumieniu. Trochę zamieszania wprowadzają w tym przypadku jedynie funkcje fputs oraz fgeis: Otóż funkcja puls po wysianiu napisu dołącza na jego koniec znak nowej linii (przypominam: Funk-
cja /p»K tego nie robi. Podobnie, funkcja gets wczytuje napis do znaku końca linii, i podanego bufora. Funkcja fgets znaknowej linii.
-NiŚjjćsttó błąd wprowadzony w Win.WR, działanie takie określa standard ANSI.-C. Nie pytajcie . mnie dlaczego.
Listing 59 - wykorzystanie funkcjifputs
#inc1ude <avr/io.h>
#i nelude <stdi o.h>
#include <avr/pgnspace.h>
#inc"lude „rs.h"
#include „harddef.h"
int main(void)
{
file* fRs;
iiimiiiiiiiii/iiiiiuiii/iiiiiinii/iiiiii
// Inicjacja portu szeregowego
rs_sst_baudCdef_bsud);
tICSROC = 1«'JRSEL0 | 1«'JCSZ01 | l«ucszoo; UCSR33 = 1«RXENC | 1«TXEN0; ucsroa = 0;
// Koniec inicjacji
////////////////////////////////////////////
// Inicjacja we/wy
etts = fdevoper.(rs_pur, rs_get, 0);
fputo_s(psTR(„Heno world!\r\n“), fRs);
Uwaga - #include i nazwy plików
Podczas rozmowy jeden z twórców biblioteki z której dziś korzystamy, zalecił mi stosowanie znaków slash (/) zamiast backslash (\) w nazwach plików. Podobno zapis taki jest kompatybilny z większą ilością syslcmów. Nasz kompilator „przełknie” obie konwencje. Od dzisiejszego od-, ęinka będę konsekwentnie stosował nowy zapis.
W poprzedniej części zapoznaliśmy się z funkcją prinlf. Pokazałem ideę działań na strumieniach i korzystaliśmy ze strumieni domyślnych. Dziś kontynuujemy poznawanie możliwości biblioteki sidło.
Do tej pory korzystaliśmy ze standardowego wejścia-wyjścia. W przypadku WinAVR wykorzystanie strumieni innych niż standardowe nie jest dużo trudniejsze, a może już dziś dać nam spore korzyści.
Zajrzyj do ramki ABC... C Powiązanie strumienia z „plikiem”. Zawarte tam informacje oraz zdobyta do tej pory wiedza powinny być wystarczające do zrozumienia niewielkich zmian wprowadzonych do programów z zeszłego miesiąca. Oba programy przerobione zostały zgodnie z listingami 59 oraz 60. Jeśli porównasz je z programami, które
W pierwotnej wersji operacje z biblioteki Stdio miały na celu działanie na plikach. Urządzenia wejścia-wyjścia były traktowane, od strony programowej, jako plik o pewnych specyficznych właściwościach. Stąd też wzięła się nazwa prawdopodobnie najważniejszej dla naszej struktury biblioteki. Struktura FILE przechowuje wszystkie informacje na temat strumienia, umożliwiające działanie funkcji do niego piszących lub z niego czytających: Ze strukturą-tą związana jest pewna „nieprzyjemność". Standard w ogóle nie definiuje jej zawartości. Jest to zmienna wewnętrzna biblioteki stt/io i służy do przekazywania informacji tylko między jej funkcjami. Co ważniejsze, twórcy biblioteki dołączonej do \VinAVR informują, że jej zawartość może zmieniać się w przyszłych wersjach. Na razie nie wnikając w sprawę głęboko, możemy założyć, żę znajdą się tam przede wszystkim wskaźniki na nasze funkcje pul oraz gel. które inicjowane są w chwili
uzyskaliśmy w zeszłym miesiącu, stwierdzisz zapewne, że różnica jest niewielka i łatwa do zrozumienia. Tym sposobem zaczęliśmy posługiwać się strumieniami innymi niż domyślne.
Obiecałem Ci, że zaoszczędzimy na pamięci. Jeśli skompilowałeś nowe wersje programów, przyjrzyj się wynikowi kompilacji. U mnie pierwszy zajął co prawda kilka bajtów mniej, drugi z kolei zajął kilka więcej. Stanowczo nie to miałem na myśli, pisząc o oszczędzaniu pamięci. Gdzie tkwi przyczyna lego, że pozornie prosty program z listingu 59 wciąż zajmuje ponad lkB pamięci?
Sposobem, aby się o tym przeko
tle nie wpisuje go do wpisuje występujący
wywołania fdevopen. Funkcja fdcvopen nie jest standardów'.! funkcją ANS! C. Jest próbą umieszczenia biblioteki stdio tam, gdzie nie występują rzeczywiste pliki. Wspomniana funkcja wykonuje dla nas dwa działania. l’o pierwsze, na podstawie podanych danych tworzy strukturę FILE, oraz zwraca wskaźnik do niej - powiemy, że dokonuje powiązania między strumieniem a plikiem.
Po drugie, jeśli odpowiedni strumień domyślny (śtdin lub/i stdout - podajemy get lub/i jiut) nie jest jeszcze zainicjowany, wpisuje do niego wskaźnik na aktualnie utworzoną strukturę.
Ody powiążemy już urządzenie, z-]®-kiern, mamy możliwość operowania .pośrednio na związanym z nim strumieniu.
Do tej pory zajmowaliśmy się tylko funkcjami operującymi na strumieniach domyślnych. Niewielka zmiana w programie umożiiw-ia nam działanie na podanym strumieniu. Wystarczy zapamiętać wskaźnik zwrócony przez fdevopen. Praktycznie wszystkie funkcje stdio posiadają swoje
nać jest kolejne usuwanie wywoływanych funkcji. Umieszczenie znaku komentarza przed funkcjąTpu/.s- powoduje zaoszczędzenie jedynie trochę ponad 100B. Dopiero zaznaczenie komentarzem funkcji fdevopen zdradza nam sekret. Wywołanie tylko funkcji piszącej na wyjście spowodowało spadek zajęcia pamięci do 340B! Okazuje się więc, że duży udział w zajętości pamięci programu ma pozornie prosta funkcja tworząca powiązanie. Problem przybliży trochę znajdująca się na tej stronie ramka Jak to robi GCC.
odpowiedniki z przedrostkiem f. Funkcje zaczynające się od tej litery przyjmują jako jeden z parametrów-zapamiętany przez nas w-skaźnik, a swoje działanie kierują do strumienia połączonego z podaną strukturą FILE.
Elektronika dla Wszystkich Marzec 2006 37