cz7

cz7



Programowanie

Programowanie

tiriśigned; jnt


typ zmiennej

wypisywana jest, dziesiętne, liczba że znakiem identyczny do tczba bez znaku,; dziesiętnie iczba bez znaku, szesnastkowo, wykorzystane

bez znaku, szesnastkowo. wykorzystane są duże


bez znaku, ósemkowo

,, isanie wskaźnika jako adresu w pamięci w formacie 0x1234

wypisanie znaku podanego jako argument char*. wypisanie łańcucha z pamięci danych

prog_char* wypisanie łańcucha z pamięci programu _

liczba zmiennoprzecinkowa w formacie naukowym 1.23e±12

liczba zmiennoprzecinkowa w formacie naukowym 1.23ŁŁ12

liczba zmiennoprzecinkowa w formacie dziesiętnym 123.45

identyczny do f

jeśli eksponenta z notacji naukowej jest mniejsza niż -4, lub większa / równa precyzji, wykonywane jest przekształcenie równoważne że; w innym przypadku ; double    wykorzystane jest |


podobnie do g, tylko wykonywane są przekształcenia E


Tabela 6 - oznaczenia typów w formatowania


Tabela 7 - flagi w łańcuchu formatowania

#

dotyczy

opis

bez efektu

x lub X

zawsze z zerem przed całą liczbą vypisuje 0x przed liczbą

wszystkie

wyrównanie długości odbywa się jrzez dodanie zer zamiast spacji wyrównanie do lewej, spacje są

[spacja]

numeryczne

*3

numeryczne

eśli liczba jest dodatnia, w miejscu gdzie powinien znajdować się znak + wprowadzana jest spacja; ma znaczenie dla wyrównania -domyślnie żaden znak nie zostałby wprowadzony eśli liczba jest dodatnia pojawia się przed nią znak

naksymalną


naków, jak


wypisa


Składnia funkcji printf wygląda następująco: int printf(const char fmt,...)

Widoczne trzy kropki to nie żadne Wprowadzone przeze mnie uproszczenie. To dość ciekawa oraz całkowicie formalna cecha języka C. Trzy kropki pojawiają się zawsze za ostatnim argumentem. Nie można za nimi umieścić jeszcze kolejnego, ustalonego argumentu. Format, z jakim mamy tułaj do czynienia oznacza, że zaraz za parametrem fmt możemy umieścić dowolną ilość dowolnych parametrów.

Pierwszym parametr nazywany jest z angielska „Format String”, co można tłumaczyć jako łańcuch formatujący. W nim zawarte są informacje, jakie parametry zostały wprowadzone i z jego pomocą są one odzyskiwane. Sposób podawania odpowiednich informacji pojawi się za chwilę, teraz jednak skupmy się na reszcie argumentów.

Każdy kolejny argument, wpisany w miejsce trzech kropek, jest umieszczany na stosie. Jednak wrzucane są one „od tyłu”. W efekcie, w chwili wywołania funkcji, pierwszy argument znajduje się na samym szczycie stosu i może być jako pierwszy z niego zdjęty. Zmienne zdejmowane będą od najmłodszego bąjtu do najstarszego.

W ten sposób można do funkcji przekazać argumenty w objętości ograniczonej jedynie pojemnością pamięci przeznaczonej na stos. Jest to niezwykle wygodne w funkcji takiej jak printf, gdzie nie da się określić, jakie argumenty będą potrzebne, jednak z możliwości tej trzeba korzystać bardzo ostrożnie...

Ryzyko i wady rozwiązania

Osoby obeznane trochę z programowaniem zdają sobie sprawę z tego, jak ważnym elementem jest stos. Jakikolwiek błąd w przepływie informacji między stosem a rejestrami może skutkować zawieszeniem się całego programu. Trzeba zdać sobie sprawę, że o ile w przypadku zwyczajnych funkcji, z ustalonymi parametrami, to kompilator dba o prawidłową obsługę stosu, nie jest on w stanie pilnować jego działania, gdy korzystamy z otwartej listy argumentów. Gdy decydujemy się na takie działanie, to na nas spoczywa odpowiedzialność za prawidłowe jego funkcjonowanie. Kompilator nic będzie także w' stanie sprawdzić, czy podawane argumenty są właściwego typu. Bardzo ważne jest więc, aby podane argumenty zgadzały się z tym, co deklarujemy w łańcuchu formatowania. W innym przypadku funkcja printf może nie zdjąć wszystkich informacji zc stosu. Może także zdjąć ich zbyt wiele. Błąd stosu może spowodować, że dalej, do rejestrów wpisane zostaną przypadkowe dane. W skrajnym przypadku śmieci zostaną wprowadzone do licznika rozkazów... rozumiesz na pewno, co się wtedy stanie.

Oprócz koniecznej ostrożności trzeba zwrócić uwagę na jeszcze jedną sprawę. Jeśli wywoływana funkcja posiada jedynie stałe argumenty, w miarę możliwości są one umieszczane bezpośrednio w rejestrach. Odpowiedni podprogram w

dokładnie typy wszystkich argumentów - ma je podane niejako „na tacy”. Jeśli natomiast wywołujemy funkcję

wszystkie one muszą zostać umieszczone na stosie. Wymaga to dodatkowego czasu oraz kodu przed wywołaniem podprogramu. Sam podprogram także musi być bardziej rozbudowany.

Ogólnie, jeśli to możliwe, funkcji tego typu raczej się unika. Czasami jednak jest to albo jedyne... albo najlepsze rozwiązanie - mimo wszystkich wad.

w naszej funkcji. Teraz dowiemy się, jak ją wykorzystać. Bardzo ważny jest łańcuch formatujący. TO w nim zawarta jest informacja o przekazanych parametrach oraz o sposobie, w jaki zostaną one wyświetlone. Znaki z łańcucha formatującego są wysyłane bezpośrednio na wyjście do chwili natrafienia na znak Znaki występujące za nim są interpretowane jako informacja o kolejnym argumencie.

Rysunek powyżej pokazuje format opisu argumentu oraz sposobu jego wyświetlenia.

Z naszego punktu widzenia, najważniejsza jest informacja o typie argumentu. Oznaczenia poszczególnych typów przedstawia tabela 6. Nie sugeruj się zbyt mocno podanymi tam typami zmiennych. Najważniejsze jest zachowanie ich rozmiaru. Pod tym względem int oraz unsigned int są identyczne.

Przydatne flagi zamieściłem w tabeli 7.

Nasz kompilator udostępnia tylko jeden modyfikator: ‘I’ oznaczający, że zamiast zmiennej typu int podajemy zmienną typu long int.

Znaczenie precyzji oraz szerokości wyjaśnia dodatkowa, niewielka ramka.

printf - pola precyzja oraz szerokość

Znaczenie pola precyzji zmienia się zależnie od typu. Dla typów zmiennoprzecinkowych oznacza ono liczbę miejsc po przecinku. Dla iypów numerycznych minimalną liczbę cyfr (dopełnienie zerami, niczalcż-

Jeśli długość napisu tworzonego prze? kształcenie jest mniejsza niż szerokość, dodawane są spacje, względnie zera (flaga ‘0’) po lewej lub prawej (flaga 1 stronie napisu. Parametr len nigdy nie powoduje przycięcia wyniku.


jakie efekty da podanie określonej szerokości lub precyzji. Wypróbuj różne flagi. Spróbuj skorzystać także z typów ‘s’ oraz ‘S\

Ponieważ jest to dość ciekawe,


Rys. 40 Działanie programu z listingu 57

proponuję Ci zapoznanie się z rysunkiem 41. który pokazuje ostatni kod uruchomiony za pomocą programu AVRStudio. Spróbuj samemu przeprowadzić pokazaną na nim symulację. Widzimy tutaj, w jaki sposób poszczególne argumenty są przesyłane do funkcji. Widzimy, że jest to jak najbardziej zgodne z opisem w ramce o naszej funkcji. Zauważ, że w tym przypadku także parametr określający adres łańcucha formatowania przesyłany jest przez stos. Informacja o tym znajduje się w dokumentacji dołączonej do WinAVR... nie ma dla nas tak dużego znaczenia przesyłanie, nieznanej nam wcześniej, otwartej listy argumentów.

Pamięć programu

Jeśli w którymś momencie zadałeś sobie pytanie, dlaczego ciągle umieszczam łańcuchy w pamięci danych, zamiast jak już pokazywaliśmy

Elektronika dla Wszystkich Luty2006 45


Wyszukiwarka

Podobne podstrony:
314 V. Funkcje wielu zmiennych Jasne jest dla czytelnika, że wypowiedziany wyżej warunek daje inną f
Podstawy programowania - JAVAĆwiczenie 2 1. Program rozwiązujący równanie kwadratowe (zmienne
Poznaj C++ w$ godziny0174 Referencje 163 Linie 24-26 zamieniają wartości. Efekt zamiany wypisywany j
Dane jest zadanie programowania liniowego przy nieujemnych zmiennych decyzyjnych: Xi - X2 -> max
Nadmiar i niedomiar w U2Wystąpienie nadmiaru lub niedomiaru wskazuje że programista źle dobrał typ d
Specyfikowanie programów imperatywnych S, S : Stan — wartościowanie zmiennych. II : program — relac
cz2 Programowanie Programowanie Tabela 1 Typy proste zmiennych dostępne w
cz7 Programowanie wyjj/yjjjuwuifla jj/uaaau/uww ] wM©    «■ ts(„HeTlo v Rys. 37 Zmia
cz7 Programowanie kształceń. Wymaga od nas jedynie stworzenia funkcji wypisującej oraz odczytującej
cz7 Programowanie Listing 57— wykorzystanie funkcji printf int main(void) l ■int a - 1234; int b
TI(312[01]) arkusz X0007 Zadanie 20. W wyniku działania programu wyświetlona wartość zapisana w zmie
Ponieważ program pamięta wszystkie wykorzystywane zmienne, więc w przypadku wprowadzenia nowej zmien
122 123 122 Programowanie liniowe całkowitoliczbowe Ponieważ zmienne *,, *,, x4 mogą przyjmować jedy
Programuj w „dobrym stylu” Nazwy zmiennych powinny odzwierciedlać sens istnienia zmiennej w
Slajd7 Schemat monitora Programowanie współbieżne z zastosowaniem monitorów. Zmienne warunkowe. 7
398 399 398 Programowanie dynamiczne Jednostkowe koszty zmienne uzupełnienia zapasów wynoszą 2 i są

więcej podobnych podstron