Pierwszą lekcję mamy już za sobą. Była długa i nie dawała zbyt efektownego wyniku. Program wyświetlił napis i poczekał na wciśnięcie klawisza. Aby lepiej współpracować z programem, należy zająć się pojęciem zmiennych.
Zmienne najogólniej mówiąc służą do tego, aby zapamiętać sobie tymczasową wartość, którą potem można zmienić w każdej chwili według potrzeby.
Istnieje kilka typów zmiennych:
Dla nas najważniejsze są pierwsze trzy typy i na razie tymi będziemy się zajmować.
Operacje arytmetyczne przypominają konwencjonalny matematyczny zapis. Również kolejność działań jest identyczna jak w matematyce. Poniżej przedstawiam zestaw najczęściej używanych operatorów:
+, -, *, /, = | dodawanie, odejmowanie, mnożenie, dzielenie, operator przypisania |
% | reszta z dzielenia (odpowiada operacji modulo) |
++, -- | inkrementacja i dekrementacja |
! | negacja |
<, > | mniejsze, większe |
<=, >= | nie większe, nie mniejsze |
&&, || | i, lub (logicznie) |
== | równe |
+=, -=, *=, /= | połączenie operatorów przypisania i innych |
Kilka operatorów wymaga krótkiego omówienia. Inkrementacja jest to proces zwiększenia zmiennej o 1, a dekrementacja zmniejszenia o 1. W tej chwili wydaje się to zupełnie niepotrzebne, ale w dalszych lekcjach okaże się bardzo przydatne. Zmienną A możemy inkrementować na dwa sposoby:
Podobnie sprawa się ma z ostatnim przykładem w powyższej tabelce, czyli z połączeniem operatorów przypisania z innymi operatorami. Działanie takich złożonych operatorów można opisać używając sposobu tradycyjnego:
Sposób krótszy | Sposób tradycyjny |
a+=5; | a=a+5; |
b-=3; | b=b-3; |
a*=2; | a=a*2; |
b/=4; | b=b/4; |
Pierwszy przykład oznacza, że nową wartość zmiennej a uzyskamy dodając do jej obecnej wartości liczbę 5.
Drugi przykład oznacza, że nową wartość zmiennej b uzyskamy odejmując od jej obecnej wartości liczbę 3.
Trzeci przykład oznacza, że nową wartość zmiennej c uzyskamy mnożąc jej obecną wartość przez liczbę 2.
Czwarty przykład oznacza, że nową wartość zmiennej d uzyskamy dzieląc jej obecną wartość przez liczbę 4.
Znając typy zmiennych i zapis operacji matematycznych, możemy zabrać się za pisanie następnego programu. Najprostszym przykładem użycia zmiennych jest prosty kalkulator. Napiszemy więc program, który poprosi nas o wpisanie dwóch liczb i wykona na nich podstawowe działania matematyczne: zsumuje je, odejmie, pomnoży i podzieli. Na początku program musi wczytać dwie liczby:
#include <stdio.h> #include <conio.h> main (void) { int a,b; //deklaracja zmiennych a i b clrscr(); printf("Podaj liczbę A: \n"); scanf("%d",&a); printf("Podaj liczbę B: \n"); scanf("%d",&b); printf("Wpisane liczby to: %d, %d.\n",a,b); getch(); return 0 ; }
W efekcie na ekranie możemy zobaczyć na przykład napisy:
Podaj liczbę A 15 Podaj liczbę B 28 Wpisane liczby to: 15, 28.
A teraz komentarz:
Na początku w funkcji głównej programu zadeklarowaliśmy zmienne a i b. Najpierw napisaliśmy typ zmiennych (calkowity), a następnie po przecinku wymienialiśmy nazwy zmiennych tego typu. Jak po każdej instrukcji i tu pojawił się średnik. Typ int (integer=całkowity) oznacza, że zmienna może przyjmować wartości z zakresu +/- 32767. Należy o tym pamiętać, jeżeli zamierzamy używać w programie dużych liczb (wtedy zamiast typu int używamy typu long). Teraz kompilator już wie, że w kodzie programu będą pojawiać się zmienne a i b i wie ile pamięci musi zarezerwować na ich przechowanie.
Następnie wypisujemy na ekranie komunikat, który prosi nas o wpisanie liczby. Program zatrzyma się w tym miejcu i będzie czekał dotąd, aż napiszemy liczbę i zatwierdzimy ję ENTERem. To co wpiszemy przechwyci z klawiatury funkcja scanf(). Zapis tej procedury wyglada dość skomplikowanie, ale w rzeczywistości wystarczy znac kilka tzw. wzorców konwersji. Wzorzec konwersji określa typ zmiennej, którą wpiszemy z klawiatury lub wypiszemy na ekranie. Należy zapamiętać kilka podstawowych wzorców. Poniższa tabela przedstawia deklaracje zmiennych określonego typu, odpowiednie dla nich wzorce konwersji oraz przykłady ich użycia:
typ zmiennej | deklaracja | wzorzec | postaś funkcji scanf() | postaś funkcji printf() |
liczba całkowita | int A | %d | scanf("%d",&A); | printf("Liczba A wynosi: %d",A); |
liczba rzeczywista | float B | %f | scanf("%f",&B); | printf("Liczba B wynosi: %f",B); |
ciąg znaków | char *C | %s | scanf("%s",&C); | printf("Lańcuch ma postać: %s",C); |
pojedynczy znak | char D | %c | scanf("%c",&D); | printf("Znak D to: %c",D); |
Są oczywiście jeszcze inne wzorce, ale te są najważniejsze i na razie tylko tymi będziemy się zajmować.
Podsumowując:
Jest coraz lepiej - program komunikuje się z nami, ale nadal jeszcze nic nie oblicza. Jest to jednak sprawa prosta. Teraz należy tylko zadeklarować kilka nowych zmiennych, które przechowają wyniki zamierzonych działań i wykonać określone działania. Modyfikujemy nasz program do postaci:
#include <stdio.h> #include <conio.h> main (void) { int a,b; //deklaracja zmiennych a i b int suma,roznica,iloczyn; float iloraz; clrscr(); printf("Podaj liczbę A: \n"); scanf("%d",&a); printf("Podaj liczbę B: \n"); scanf("%d",&b); suma=a+b; roznica=a-b; iloczyn=a*b; iloraz=a/b; printf("Wyniki działań:\n"); printf("Suma: %d\n",suma); printf("Różnica: %d\n",roznica); printf("Iloczyn: %d\n",iloczyn); printf("Iloraz: %f\n",iloraz); getch(); return 0 ; }
Jak widać zmienna nie musi być przedstawiana jako pojedyncza litera. Może to być również wyraz, ale należy zwracać uwagę na wielkość liter. Ekran powykonaniu programu może wyglądać tak:
Podaj liczbę A 21 Podaj liczbę B 8 Wyniki działań: Suma: 29 Różnica: 13 Iloczyn: 168 Iloraz: 2.000000
Pierwsze trzy działania nie budzą żadnych zastrzeżeń. W końcu suma, różnica i iloczyn liczb całkowitych daje w wyniku również liczbę całkowitą. Ale rzadko się zdarza, aby również iloraz był liczbą całkowitą. Przewidzieliśmy to deklarując zmienną iloraz jako liczbę rzeczywistą, a nie całkowitą. Tymczasem komputer po podzieleniu liczby 21 przez 8 otrzymał w wyniku 2...
To nie jest żadna pomyłka. Operator / jest nazywany czasem operatorem dzielenia całkowitego, a więc bez reszty. Gdybyśmy wpisali zamiast / operator % uzyskalibyśmy wynik reszty z dzielenia. Ale nie znaczy to jednak, że uzyskanie wyniku 2,625 nie jest możliwe. Sekret tkwi w typie argumentów użytych do operacji dzielenia, czyli w typie zmiennych a i b. Gdybyśmy zadeklarowali je jako liczby rzeczywiste (a więc float a,b;) operacja dzielenia byłaby traktowana jako normalne dzielenie, a nie dzielenie całkowite.
Tak mogłoby już zostać, ale skoro pokusiliśmy się o zmianę typów wczytywanych liczb, warto zmienić również typ wyników wszystkich działań na rzeczywisty. Proszę jednak nie zapominać, po zmianach w deklaracji zmiennych, należy zmienić także wzorce konwersji z %d na %f!
Tak naprawdę wcale nie trzeba było deklarować osobnych zmiennych dla przedstawienia wyniku działan. Chodziło mi jednak o przedstawienie operacji przypisania (=). Funkcja printf umożliwia bowiem takie samo wyświetlenie wyniku przy następujacej konstrukcji: printf("Suma: %d",a+b);
Na koniec ostatnia rada przy używaniu liczb rzeczywistych. Nie zawsze zależy nam na tak dużej dokładności, aby znać aż 6 miejsc po przecinku. Zaokrąglić liczbę do mniej dokładnej możemy w bardzo prosty sposób. Przyda się nam do tego wzorzec konwersji, który należy trochę uzupełnić. Przekształćmy wzorzec w funkcji printf wyświetlającej wynik dzielenia z postaci %f na %.3f. Wydaje się to mało czytelne, ale spowoduje, że liczba przy wyświetleniu zostanie obcięta do 3 miejsc po przecinku.
Podsumowując: