inf‎ > ‎

Wykład 5. Dodatki

Uwaga! Takie zadania były realizowane w programie nauczania szkoły podstawowej kilka lat temu (wiem, bo przez 10 lat produkowałem oprogramowanie matematyczne na zlecenie Wydawnictw Szkolnych i Pedagogicznych).
W ciągu tych lat miałem lekcje testowe z dziećmi z podstawówki, i z praktyki wiem, że dzieciaki dawały radę lepiej niż większość współczesnych studentów.
Zdaję sobie też jednak sprawę z tego, że na maturze z matematyki już w tym roku będzie obowiązywać zadanie "Drwal sprzedał drewno za 100 zł. Pokoloruj drwala.", dlatego postanowiłem łopatologicznie podejść do problemu wyświetlania liczby całkowitej w systemie dziesiętnym (zadanie z 5. laborki).

Weźmy zmienną całkowitą bez znaku, np. unsigned char x. Wartości, jakie może ona przyjmować, to 0..255. W systemie dziesiętnym można więc wydrukować tę liczbę jako 1, 2, lub 3-znakowy napis.
Np. kiedy x == 123, to wyświetlone powinny być kolejno znaki '1', '2', '3'. Dość oczywiste, prawda?

Gdybyśmy chcieli wyświetlić wartość tej zmiennej w konsoli tekstowej, użylibyśmy np. printf(...) z odpowiednimi argumentami. Co jednak zrobić, kiedy nie można użyć funkcji printf? Laborka nr 5 zmusza do kombinowania — jak wyświetlać napisy, liczby (i nie tylko!), mając do dyspozycji zaledwie funkcję wyslij_znak(char c). 

Liczby całkowite w systemie dziesiętnym wyświetla się wcale nie tak trudno, jak mogłoby się wydawać.

Niech x jest liczbą 3-cyfrową, wtedy jej kolejne cyfry to abc. Symbol a to cyfra setek, b to cyfra dziesiątek, zaś c stanowi cyfrę jedności. Przykładowo, dla x==7 wartości abc będą odpowiednio wynosiły 0-0-7, zaś dla x==123 będzie to a==1, b==2, c==3.
Załóżmy teraz, że ktoś wpisał do zmiennej x pewną wartość, nie wiemy jaką. W jaki sposób można wyznaczyć a, b oraz c?
Z innego wykładu wiemy, co oznaczają operatory / oraz % dla operandów (argumentów) będących liczbami całkowitymi. Są to odpowiednio część całkowita i reszta z dzielenia.
Co otrzymamy po wykonaniu instrukcji x % 10 ? Jest to reszta z dzielenia zmiennej x przez 10, czyli właśnie cyfra jedności!
Z kolei wynikiem dzielenia (x / 10) będzie to, co pozostanie po odcięciu cyfry jedności, czyli inaczej sklejone ab
Konkretny przykład: niech x == 123. 
c = x % 10 --> 3
ab = x / 10 --> 12

No dobrze, a jak 'rozmontować' na elementy składowe sklejone ab? Zadanie sprowadza się do rozbicia tej 2-cyfrowej liczby na cyfrę dziesiątek oraz cyfrę jedności ('indywidualne' a oraz b).
a = ab / 10;
b = ab % 10;

Czy jest sens wprowadzać dodatkową zmienną o nazwie ab? Niekoniecznie, wiemy przecież, że ab to nic innego jak (x/10).
Ostatecznie mamy:
c = x %10;
b = (x/10) % 10;
a = (x/10) / 10; 

Zauważmy, że można to zapisać inaczej:

c = (x/1) % 10; //cyfra jedności 
b = (x/10) % 10; //cyfra dziesiątek
c = (x/100) % 10; //cyfra setek
d = (x/1000) % 10; //cyfra tysięcy
e = (x/10000) % 10; //cyfra dziesiątków tysięcy
f = (x/100000) % 10; //cyfra setek tysięcy
itd. 

Reszta należy do was :)