Zmienne cz. 2 - wartości całkowite - Programowanie jest łatwe

Podczas programowania, poza własną wyobraźnią, ograniczają nas dwie rzeczy: prędkość przetwarzania (szybkość procesora) oraz pojemność pamięci. Przyjrzyjmy się bliżej temu drugiemu.

Grosz- najmniejsza, niepodzielna wartość waluty nowy polski złoty

Języki programowania można podzielić na dwa rodzaje: te z silnym typowaniem oraz te, ze słabym typowaniem. Różnica polega na tym jak w tych językach podchodzi się do zmiennych. W silnym typowaniu, programista musi zadbać o to, aby do zmiennych o określonym typie wprowadzać pasujące wartości, w innym przypadku napotka błąd/ostrzeżenie podczas kompilacji. W słabym typowaniu rodzajów zmiennych rozróżnienia między wartościami całkowitymi a zmiennoprzecinkowymi, czy wartościami liczbowymi a ciągami znaków. Praktycznie nie ma i nie trzeba się tym w ogóle zajmować, jednak podczas działania programu mogą pojawić się tzw. runtime errors (tłumaczenie dosłowne to “błąd podczas wykonywania”). Taka sytuacja zajść może, gdy algorytm, który ma operować na wartościach liczbowych i je np. mnożyć przez inną wartość, dostanie wartość znakową.

Pierwsza grupa języków jest trudniejsza, ponieważ podczas pisania jest więcej rzeczy, o które należy zadbać, jednak odwdzięcza się to stabilnością pracy programu. Języki z silnym typowaniem to C, C++, JAVA, C#. Słabe typowanie, umożliwiające szybkie (i niestety, nierzadko łapserdackie pisanie kodu) to np. JavaScript, PHP, Perl.

Z lotu pataka na pamięć

W komputerze istnieje wiele rodzajów pamięci:

Podane rodzaje umieściłem wg odległości od jednostki przetwarzającej. Im większa odległość od rdzenia, tym dłuższy czas dostępu do komórki pamięci. Programując, interesujemy się przede wszystkim rejestrami procesora oraz pamięcią RAM. Po uruchomieniu programu, system operacyjny umieszcza plik wynikowy w pamięci operacyjnej. Skompilowany program zawiera zestaw instrukcji (algorytm) oraz segment pamięci, który jest przeznaczony na przechowywanie danych. Dane, o których tu mowa to po prostu zmienne deklarowane przez programistę. Im więcej zmiennych podczas pisania programu użyjemy, tym większą ilość pamięci zajmie nasz program.

Z powyższego wynika, że konsekwencją każdej deklaracji zmiennej jest zmniejszenie ilości dostępnej pamięci. Jest to powód, dla którego wprowadzono kilka rodzajów typów zmiennych.

Typy w językach silnie typowanych

Różnią się one w zależności od języka, ale przyjmę tutaj nomenklaturę C, ponieważ jest najbardziej powszechna.

Po pierwsze, zacznijmy od rodzajów danych, które chcemy przechowywać w pamięci. Typy proste odpowiadają na następujące potrzeby:

Wróćmy na chwilę do magicznych rejestrów procesora. Rejestr może pomieścić maksymalnie tyle bitów danych, w jakiej architekturze został stworzony. Np. procesor o architekturze 64-bitowej może pomieścić w swoich rejestrach (tzn. przetworzyć) 64 bity czyli 8 bajtów. Czyli maksymalna wartość zmiennej, która całkowicie wypełnia rejestr to 18 446 744 073 709 551 615 (2 do potęgi 64, minus 1). Ponieważ zwyczajowo jeden (najstarszy) bit zmiennej nie jest używany do przechowywania wartości tylko do kodowania znaku (plus albo minus), zakres wartości mieści się w przedziale −9 223 372 036 854 775 808 do +9 223 372 036 854 775 807.

To całkiem sporo i w większości przypadków takie ogromne wartości nie będą nam do niczego potrzebne. Jednak deklarując taką zmienną, zajmujemy aż 8 bajtów. Dlatego twórcy języków dali programistom możliwość kontrolowania wielkości zajmowanej przez nich pamięci.

Wartości całkowite

Najprostszym rodzajem zmiennej jest zmienna liczbowa typu całkowitego, nazywana int (skrót od ang. Integer- liczba), która umożliwia przechowywanie liczb dodatnich i ujemnych- jak wcześniej napisałem, jeden bit jest przeznaczany na określenie, czy zmienna jest dodatnia czy ujemna (np. jeżeli najstarszy bit jest ustawiony na 1, to znaczy, że mamy do czynienia z wartością ujemną).

Tak dużo mi nie potrzeba

Int zawsze zajmuje całą szerokość rejestru. W przypadku, gdy mamy do czynienia z dużą ilością zmiennych, ale jesteśmy pewni, że na pewno nie potrzebujemy całego zakresu, jaki daje nam int (np. Mamy do czynienia z wartościami do 10000 włącznie), możemy zaoszczędzić zajmowaną pamięć. Do tego celu jest typ short int. Short int ma takie same właściwości jak int z tym, że zajmuje o połowę mniej miejsca. W przypadku architektury 64-bitowej będzie to 32 bity czyli 4 bajty.

Plus albo minus

Jest jeszcze jedna rzecz, którą możemy wykorzystać. Gdy zajdzie sytuacja, że będziemy chcieli zużyć cały zakres na wartości, ale będzie ich naprawdę sporo, możemy świadomie zrezygnować ze znaku zmiennej (plus/minus) i przeznaczyć ten bit na zwiększenie jej maksymalnej wielkości wielkości (dla 64-bitowej architektury będzie to zakres do 18 trylionów, a nie 9 jak w przypadku zmiennej ze znakiem). Aby to uzyskać, wystarczy użyć odpowiednio unsigned int albo unsigned short int (ang. unsigned- bez znaku).

Jest jeszcze jedna zaleta korzystania z unsigned. W przypadku, gdy np. tworzymy funkcję, która jako argument ma przyjmować tylko i wyłącznie wartości dodatnie, możemy wymusić tylko takie wartości, deklarując argument funkcji jako unsigned. Wtedy, już podczas kompilacji, jeżeli przez przypadek przekażemy zmienną typu int, kompilator ostrzeże nas, że coś może być nie tak w kodzie, który napisaliśmy.

Ćwiczenia

  1. Jak wpływa wielkość zajmowanej przez program pamięci na prędkość działania algorytmu?
  2. Jaka jest zakres wartości zmiennej w architekturze 32 bitowej a jaki w architekturze 16 bitowej?
  3. Co się stanie, gdy zostanie wczytana (np. z pliku albo z klawiatury) wartość ujemna do zmiennej bez znaku (unsigned)?
  4. Co się stanie, gdy do zmiennej typu int zostanie wprowadzona wartość zmiennoprzecinkowa?
  5. Jaka wartość zostanie zapisana w zmiennej b, c i d a jaka jest powinna być prawdziwa wartość ?
    int b = 5 / 1.23;
    int c = 5 / 2;
    int d = 5 / 2.9;
  6. Co się stanie, gdy do zmiennej typu short int wprowadzisz wartość np. 9999999999999 ?

Dodano: 2018-02-16 06:07 przez Piotr Poźniak

ćwiczenia , zmienne , wartości całkowite , int , short , unsigned , pamięć , rejestr , ram , pamięć operacyjna ,
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.