Zmienne cz. 4 - zmienne znakowe - Programowanie jest łatwe

Komputer operuje wyłącznie na wartościach, które są zakodowane za pomocą systemu binarnego. Jak to możliwe więc, że na ekranie komputera pojawiają się znaki, a w plikach znajdujemy tekst? Jest kilka sposobów na kodowanie znaków. Odpowiadają za to zmienne znakowe.

Maszyna Gutenberga- każda litera osobno ułożona na matrycy

Słowem wstępu

Wartości dziesiętne są kodowane do systemu binarnego. Ze znakami (literami, cyframi przedstawianymi za pomocą znaków) jest nieco inaczej. Otóż najprostszym sposobem jest podstawienie pod każdą literę jakiejś wartości liczbowej, która symbolizowałaby tę literę. To, co opisałem nosi miano kodowania znaków. Najpopularniejszym i powszechnie obecnym kodowaniem znaków jest system ASCII, który za pomocą jednego bajtu koduje wszystkie znaki alfanumeryczne, znaki specjalne, cyfry, a także białe znaki takie jak spacje, tabulacje czy nowe linie. Wykorzystuje jeden bajt dlatego może zakodować do 255 znaków, ponieważ wartość 0 jest uznawana za znak specjalny, który jest wykorzystywany do oznaczania końca tekstu (ale o tym będzie więcej w części o ciągach znaków).

ASCII koduje znaki to znaczy, że pod daną wartością kryje się symbol konkretnego znaku. Wszystkie można odnaleźć w tzw. tablicy ASCII. To kodowanie ma zasadniczą wadę- jest ograniczone do 255 znaków. O ile posługujemy się alfabetem łacińskim, bez tzw. ogonków nie ma problemu. Wyzwanie pojawia się, gdy chcemy używać polskich, niemieckich, czeskich znaków specjalnych albo posłużyć się cyrylicą- wszystkie te symbole nie zmieszczą się w jednym bajcie. Ucieczką od tego problemu okazały się tak zwane "strony kodowania". Polega to na tym, że dany zestaw znaków, np. polskich, jest umieszczany pod tymi samymi wartościami, jak np. znaki czeskie. Informacja o stronie kodowania pozwala na poprawne wyświetlanie znaków na ekranie. Ten problem jest zapewne Tobie znany, jeżeli korzystasz z napisów do filmów i czasami albo program do odtwarzania filmów pyta Ciebie o format (stronę kodowania) albo, gdy zamiast polskich ogonków widzisz dziwne znaki. To sytuacja, w której błędnie określono stronę kodowania. Polskie znaki są kodowane za pomocą ASCII przy pomocy standardu ISO8859-2.

Alternatywą dla ASCII jest dwubajtowy unicode (UTF-8 albo UTF-16). Po prostu wykorzystują więcej miejsca w pamięci i pozwalają na przechowanie wszystkich możliwych znaków. Istnieją także rozszerzenia jak utf8mb4, które pozwalają na kodowanie emotikonek i innych wodotrysków. Ale to jako ciekawostka.

Zmienne znakowe

Najbardziej rozpowszechnioną zmienną, która służy do przechowywania znaków jest char. Zwyczajowo zajmuje 1 bajt w pamięci i służy do przechowania dokładnie jednego znaku. Czyli kiedy chcemy zapisać do pamięci "ala ma kota" potrzebujemy 12 bajtów (ostatni bajt oznaczony jako 0, symbolizujący koniec ciągu znaków). Jednak do char można zapisać tylko jeden znak. Jak sobie radzić z tekstem- o tym w innych ćwiczeniach (o tablicach).

Pojedyncze znaki umieszcza się w zmiennej typu char umieszczając jej symbol pomiędzy apostrofami, np. char zmienna = 'a';. Zapisując do takiej zmiennej wartość liczbową, np. char zmienna2 = 64; umieszczamy znak, który występuje w tablicy ASCII pod wartością 64 (czyli znak @).

Znaki od a do z są kodowane wartościami kolejno od 97 do 122. To znaczy, że możemy porównać zmienne, które przechowują znaki. Np.

char zmienna1 = 'b';
char zmienna2 = 'm';

if (zmiena1 < zmienna2) {
    printf("b jest mniejsze od m!");
}

Dzięki temu można porównywać litery wg kolejności, a co za tym idzie sortować wyrazy alfabetycznie. Mało tego, możemy te wartości ze sobą dodawać lub odejmować. Powiedzmy, że chcemy dowiedzieć się ile liter jest pomiędzy 'r' a 'w'. Wystarczy odjąć od 'w' 'r', da to wartość liczbową 5.

Niuans

Jest jedna rzecz, która może być na początku kłopotliwa. Zmienne znakowe to zarówno wartość liczbowa jak i znak. To znaczy, że można się w tym pogubić. Np. '9' to nie to samo co 9. '9' to Znak 9, który jest kodowany wartością 57. To samo z zerem: '0' ma wartość 48 więc nie można porównać '0' z 0… Drugą rzeczą jest wyświetlanie na ekranie. Czasami będziemy chcieli wyświetlić wartość ASCII, którą przechowuje zmienna zamiast jej symbolu. Wtedy należy rzutować tę zmienną na wartość zmiennej liczbowej. O rzutowaniu (czy konwersji) w innym rozdziale, tutaj tylko dla przykładu:

```c char zmienna1 = 'x'; int wartosc = (int)zmienna1;



Ponieważ zmienne znakowe są używane do radzenia sobie z tekstem, czyli podstawowym narzędziem komunikacji programu z użytkownikiem, naprawdę warto dobrze się zapoznać z tym typem wartości.

#Ćwiczenia
1. Pod jaką wartością, w ASCII, przechowywany jest znak spacji?
2. Co się stanie po dodaniu dwóch wartości znakowych 'u' i 'p'?
3. Czy można mnożyć wartości znakowe?
4. Napisz pętlę, która wyświetli kolejne litery alfabetu od a do z.
5. Napisz pętlę, która wyświetli kolejne litery alfabetu od A do Z.
6. Czym się różni mała litera od wielkiej litery?
7. Sortując znaki alfabetu, która litera będzie pierwsza: 'a' czy 'A'? Dlaczego?

- - - 
- _Następna część: [Odpowiedzi, cz. 1](https://programowaniejestlatwe.pl/artykul/zmienne-odpowiedzi-cz-1?internal=1 "Odpowiedzi, cz. 1")_
- _Poprzedni część: [Zmienne cz. 3 - liczby zmiennoprzecinkowe](https://programowaniejestlatwe.pl/artykul/zmienne-cz-3-liczby-zmiennoprzecinkowe?internal=1 "Zmienne cz. 3 - liczby zmiennoprzecinkowe")_

Dodano: 2018-03-02 08:21 przez Piotr Poźniak

ćwiczenia , zmienne , litery , cyfry , znaki , char , ascii , utf8 ,
Piotr Poźniak
O autorze:

Programuję od ponad 15 lat. Prowadzę software house. Angażuję i zachęcam wszystkich do programowania w ramach inicjatywy Programowanie jest łatwe.