Pomoce:

Instalacja Code Blocks i tworzenie projektu aplikacji konsoli.
Struktura programu w języku C++

 

Zmienne i strumienie w języku C++

Definicja zmiennej

Zmienna (ang. variable) jest obiektem przechowującym przetwarzaną w programie informację. W języku C++ wszystkie zmienne muszą być zdefiniowane przed pierwszym użyciem. Definicja zmiennej określa rodzaj przechowywanej w niej informacji oraz nazwę, poprzez którą program posiada dostęp do tej informacji.

 

typ_zmiennej  nazwa_zmiennej;

 

Rozróżniamy następujące typy podstawowe zmiennych:

 

int - zmienne całkowite
double - zmienne rzeczywiste podwójnej precyzji
char - zmienne znakowe
bool - zmienne logiczne

 

Nazwy zmiennych (ang. variable names) mogą składać się z liter małych i dużych (są rozróżniane!), cyfr oraz znaków podkreślenia _. Pierwszym znakiem nazwy zmiennej nie może być cyfra. Również nazwa nie powinna się rozpoczynać od znaku podkreślenia. W nazwie zmiennej nie powinno być więcej niż 31 znaków w celu zapewnienia przenośności (możliwości uruchomienia twojego programu na komputerach innego typu niż IBM-PC - np. Macintosh, Amiga, VAX, CRAY). Dodatkowo nazwom zmiennych powinniśmy nadawać zrozumiałą postać zgodną z ich funkcją w programie - poprawia to czytelność twojego programu. Nazwa zmiennej nie może być identyczna ze słowem kluczowym języka C++ (np. if, for, while, int, double). Poniżej mamy przykłady poprawnych nazw zmiennych:

 

wynik
alfa
x12

 

oraz mniej poprawne:

 

qxj15zxkl
_12
_

 

i całkiem złe:

 

1x
bool

 

Oto kilka definicji zmiennych:

 

int a;         // definiujemy zmienną całkowitą a
int b,c,d;     // definiujemy trzy zmienne całkowite b,c,d
double x1,x2// definiujemy dwie zmienne rzeczywiste x1 i x2
char znak;     // definiujemy zmienną znakową znak
bool p,w;      // definiujemy dwie zmienne logiczne p i w

 

Typy całkowite

Zmienna typu int może przechowywać 32 bitowe liczby całkowite ze znakiem w kodzie U2. Zakres takich liczb wynosi od -231 ... 231 - 1, tj. ~ -2 mld ... 2 mld. Jest to podstawowy typ danych całkowitych. Co ciekawe, mikroprocesor Pentium szybciej przetwarza dane 32-bitowe niż 16 czy 8 bitowe. Ten typ danych po prostu pasuje do architektury procesora 32-bitowego, jest jakby naturalnym dla niego typem danych. Obecnie coraz powszechniejsze stają się procesory 64 bitowe. Można z tego wywnioskować, iż w niedalekiej przyszłości, gdy układy te się upowszechnią, typ int będzie oznaczał daną 64 bitową (dawniej int oznaczał daną 16 bitową, gdy królowały procesory 16 bitowe). Programując inne komputery musisz zawsze sprawdzać w instrukcji, jaki rozmiar posiadają poszczególne typy danych - nasz opis odnosi się do bieżącej wersji kompilatora Mingw dla systemu 32 bitowego IBM-PC.

Oprócz podstawowego typu int mamy dostępne jego odmiany:

unsigned int - liczby 32 bitowe w naturalnym kodzie dwójkowym, zakres 0 ... 232 - 1, tj. ~ 0 ... 4 mld. Przy definicji zmiennej tego typu słowo int można pominąć, zostawiając jedynie unsigned.

long long int - liczby 64 bitowe ze znakiem w kodzie U2, zakres -263 ... 263 - 1, tj. -9223372036854775808 ... 9223372036854775807. Słowo int można pominąć.

unsigned long long int - liczby 64 bitowe w naturalnym kodzie binarnym, zakres  0 ... 264 - 1, tj. 0 ... 18446744073709551617.Słowo int można pominąć.

short int - liczby 16 bitowe ze znakiem w kodzie U2, zakres -215 ... 215 - 1, tj. -32768 ... 32767. Słowo int można pominąć.

unsigned short int - liczby 16 bitowe w naturalnym kodzie binarnym, zakres 0 ... 216 - 1, tj. 0 ... 65535. Słowo int można pominąć.

char - liczby 8 bitowe. Mogą być traktowane jako liczby ze znakiem w kodzie U2 (zakres -27... 27 - 1, -128...127) lub jako liczby bez znaku w naturalnym kodzie binarnym (zakres 0...28 - 1, 0 ... 255). Standardowo typ char oznacza liczby ze znakiem będące kodami liter. Stąd kody znakowe większe niż 127 posiadają wartość ujemną. Można jednakże utworzyć bezznakowy typ char posiłkując się słowem unsigned.

Podane powyżej typy wykorzystuje się tylko w szczególnych wypadkach, gdy podstawowy typ int staje się nieodpowiedni. My ograniczymy się jedynie do typów:

int - liczby całkowite ze znakiem,

unsigned - liczby całkowite bez znaku,

char - litery.

 

Typy rzeczywiste

Dane rzeczywiste są liczbami zmiennoprzecinkowymi, które mogą reprezentować również liczby ułamkowe. Podstawowym typem danych jest typ double - typ zmiennoprzecinkowy o podwójnej precyzji. Dana typu double ma długość 64 bitów. Cechą charakterystyczną liczb zmiennoprzecinkowych jest dokładność (precyzja) przedstawiania liczby - typ double pozwala reprezentować liczby z precyzją około 15 cyfr - jeśli zapis liczby wymaga więcej cyfr, to tylko pierwsze 15 będą przedstawione dokładnie (czasem nawet i ta reguła nie jest spełniona - patrz dalej), natomiast pozostałe cyfry są już niewiarygodne.

Oprócz podstawowego typu danych double mamy do dyspozycji dwa dodatkowe typy zmiennoprzecinkowe:

float - 32 bitowe (4 bajty) liczby zmiennoprzecinkowe, dokładność 7-8 cyfr. Nie zalecany.

long double - 80 bitowe (10 bajtów) liczby zmiennoprzecinkowe, dokładność 20 cyfr. Typ ten nie jest przenośny na inne systemy, gdyż jest wewnętrznym typem danych koprocesora arytmetycznego, który wykonuje dla mikroprocesora Pentium operacje na liczbach zmiennoprzecinkowych. Aby ułatwić procesorowi dostęp do pamięci, dana typu long double zajmuje 12 bajtów - 3 słowa 32-bitowe, z których tylko 10 jest wykorzystywane na zapis liczby, a 2 pozostałe są jedynie wypełnieniem. Po prostu mikroprocesor Pentium szybciej odczytuje pamięć w porcjach 32 bitowych niż 16 czy 8 bitowych.

Podobnie jak dla typów całkowitych, typy float i long double stosuje się w przypadkach wyjątkowych. My konsekwentnie stosować będziemy typ double.

 

Typ logiczny

Dane typu bool zajmują w pamięci 8 bitów (1 bajt). Z tych 8 bitów wykorzystywany jest tylko najmłodszy. Jeśli ma on wartość 0, to dana reprezentuje wartość logiczną false. Jeśli ma on wartość 1, to dana reprezentuje wartość logiczną true.

 

Instrukcja przypisania

Informację umieszczamy w zmiennej przy pomocy instrukcji przypisania (ang. assignement statement). Składnia tej instrukcji jest następująca:

 

nazwa_zmiennej = wyrażenie;

 

Wartość wyrażenia zostaje obliczona, zamieniona na typ danych zgodny z typem zmiennej i umieszczona w podanej zmiennej. Poprzednia zawartość zmiennej zostaje utracona.

Przykłady:

 

a = 10;     // w zmiennej a zostanie umieszczona liczba 10
c = a + b// w zmiennej c znajdzie się wynik sumowania zmiennych a i b

 

Instrukcja przypisania posiada wartość równą przypisywanemu wyrażeniu. Pozwala to stosować ją w wyrażeniach arytmetycznych:

 

a = b = c = 5 // do wszystkich zmiennych a,b i c trafi liczba 5.

a = 2 * (b = 3); // do zmiennej b trafi 3, do zmiennej a trafi 6.

 

Osobiście nie polecam tego typu rozwiązań, chociaż może i wyglądają oszczędnie, ale są później trudne w analizie (np. a = b = c = b = a;) i mogą prowadzić do dziwnych błędów.

Jeśli w wyrażeniu używana jest ta sama zmienna, do której trafi wartość wyrażenia, to mamy do czynienia z operacją modyfikacji zawartości zmiennej. Wyrażenie korzysta z wartości, którą zawierała zmienna przed operacją. Wartość wyrażenia zastąpi poprzednią zawartość zmiennej.

Przykłady modyfikacji:

 

a = a + 5// zawartość zmiennej a zostanie zwiększona o 5
b = b * c// zawartość zmiennej b zostanie pomnożona przez c
a = -a;     // zawartość zmiennej a zmieni znak na przeciwny.

 

Ponieważ niektóre modyfikacje wykonuje się często w programach, posiadają one skrócone wersje zapisu instrukcji przypisania:

 

Wersja skrócona Odpowiednik instrukcji
a += wyrażenie; a = a + wyrażenie;
a -= wyrażenie; a = a - wyrażenie;
a *= wyrażenie; a = a * wyrażenie;
a /= wyrażenie; a = a / wyrażenie;
a %= wyrażenie; a = a % wyrażenie;

 

Przykłady modyfikacji skróconej:

 

a += 3;   // zawartość zmiennej a zwiększy się o 3
a += b;   // zawartość zmiennej a zwiększy się o zawartość zmiennej b
a *= 2;   // zawartość zmiennej a zostanie pomnożona przez 2

 

Proste zwiększanie i zmniejszanie o 1 realizujemy instrukcjami:

 

zmienna++;    lub   ++zmienna;
zmienna--;
  lub   --zmienna;

 

Przykłady modyfikacji o 1:

 

a++;    // zmienna a zwiększy swoją zawartość o 1
--b;    // zmienna b zmniejszy swoją zawartość o 1.

 

Jeśli operacje powyższe realizujemy jako samodzielne instrukcje, to nie ma znaczenia, czy wybierzemy formę zmienna++/zmienna--, czy ++zmienna/--zmienna. Jednakże różnica pojawia się gdy modyfikacja staje się częścią wyrażenia. Wtedy ++zmienna/--zmienna oznacza, iż w wyrażeniu zostanie zastosowana zawartość zmiennej po modyfikacji (odpowiednio zwiększona o 1 lub zmniejszona o 1), a zmienna++/zmienna-- oznacza, że w wyrażeniu będzie użyta zawartość zmiennej przed modyfikacją o jeden - modyfikacja nastąpi dopiero po wyliczeniu wartości wyrażenia.

Przykłady:

 

b = ++a// do b trafi a zwiększone o 1, zmienna a zwiększy zawartość o 1
b = a++;  // do b trafi poprzednia zawartość a, zmienna a zwiększy zawartość o 1

 

Strumienie wejścia i wyjścia danych dla konsoli

Instrukcja przypisania pozwala przetwarzać dane w zmiennych. Do odczytu danych z konsoli znakowej Windows służy specjalny obiekt biblioteki STL (ang. Standard Template Library) zwany strumieniem cin (ang. console input). Używamy go następująco:

 

cin >> nazwa_zmiennej;

 

Do wyprowadzania danych na ekran konsoli służy strumień wyjścia cout (ang. console output). Stosujemy go następująco:

 

cout << wyrażenie;

 

Wyrażenie może być arytmetyczne lub tekstowe - ten drugi typ pozwala przesyłać na ekran konsoli różne napisy. Dodatkowo do strumienia cout przesyła się często tzw. manipulatory, czyli funkcje modyfikujące sposób pracy strumienia wyjściowego.

 

Manipulator Opis
endl Przenosi wydruk na początek nowego wiersza.
setw(n) Ustawia szerokość wydruku liczby. Jeśli liczba posiada mniej cyfr niż wynosi n, to reszta pola jest wypełniana spacjami. Manipulator setw(n) działa jedynie na następną liczbę przesłaną do strumienia. Kolejne dane nie będą nim już objęte. Cyfry liczby standardowo dosuwane są do prawej krawędzi pola wydruku.
   cout << setw(6) << a << endl;
width(n) To samo co setw(n).
left Umieszcza cyfry liczby po lewej stronie pola wydruku. Stosuje się tylko po manipulatorze setw(n).

   cout << setw(6) << left << a << endl;

right Umieszcza cyfry liczby po prawej stronie pola wydruku. Manipulator jest ustawiony standardowo, zatem jego użycie ma sens tylko do anulowania manipulatora left. Stosuje się tylko po manipulatorze setw(n).
setfill(ch) Manipulator używany tylko po setw(n). Ustawia on znak, którym zostanie wypełnione puste miejsce w polu wydruku liczby - jeśli liczba posiada mniej cyfr niż wynosi szerokość pola, to puste miejsca są zwykle wypełniane spacjami. Manipulator setfill() pozwala zmienić spacje na inny znak. Poniższy przykład formatuje wydruk liczb całkowitych na 6 cyfr z wiodącymi zerami, np. zamiast 173 otrzymamy 000173:
    cout << setw(6) << setfill('0') << a << endl;
setprecision(n) Manipulator ustawia liczbę cyfr po przecinku przy wydruku liczb zmiennoprzecinkowych. Stosuje się do wszystkich liczb zmiennoprzecinkowych, które po manipulatorze trafią do strumienia wyjściowego.
fixed Manipulator powoduje, iż kolejne liczby zmiennoprzecinkowe będą wyświetlane ze stałą liczbą cyfr po przecinku. Liczbę cyfr ustala manipulator setprecision(). Jeśli nie był wcześniej zastosowany, to standardowo otrzymamy 6 cyfr po przecinku:

   cout << fixed << x << endl;

scientific Po zastosowaniu tego manipulatora liczby zmiennoprzecinkowe będą wyświetlane w postaci naukowej:

1.56E-2  odpowiada liczbie 1.56 × 10-2 = 1,56 × 0,01 = 0,0156

 

Używanie strumieni cin i cout wymaga dołączenia pliku nagłówkowego iostream oraz, dla wygody użycia przestrzeni nazw std. Jeśli stosujemy manipulatory (za wyjątkiem endl), to musimy również dołączyć plik nagłówkowy iomanip. Poniżej mamy kilka przykładowych programów.

 

// Program  wykorzystujący
// strumienie cin  i  cout
// (C)2010 I LO w Tarnowie
//------------------------

#include <iostream>

using namespace std;

int main()
{
    int wiek;
    cout << "WITAJ W PROGRAMIE C++\n"
            "---------------------\n\n"
            "ILE MASZ LAT? : ";
    cin >> wiek;
    cout << "OK, TERAZ MASZ LAT : " << wiek << endl
         << "ALE ZA 15 LAT BEDZIESZ MIAL JUZ "
         << wiek + 15 << endl << endl;
    return 0;
}

 

// Program  przeliczający stopnie
// Celsjusza na stopnie Fahrenheita.
// (C)2010 I LO w Tarnowie
//----------------------------------

#include <iostream>

using namespace std;

int main()
{
    int tc,tf;
    cout << "Przeliczanie stopni Celsjusza na stopnie Fahrenheita\n"
            "----------------------------------------------------\n\n"
            "Temperatura w stopniach Celsjusza?  : ";
    cin  >> tc;
    tf = (9 * tc) / 5 + 32;
    cout << "Temperatura w stopniach Fahrenheita : " << tf << endl << endl;
    return 0;
}

 

// Program  obliczający obwód
// i pole prostokąta.
// (C)2010 I LO w Tarnowie
//---------------------------

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
    double a,b,pole,obwod;
    cout << fixed << setprecision(4)
         << "Obwod i pole prostokata\n"
            "-----------------------\n\n"
            "Bok a = ";
    cin  >> a;
    cout << "Bok b = ";
    cin  >> b;
    pole  = a * b;
    obwod = 2 * (a + b);
    cout << endl
         << "Pole  = " << setw(10) << pole << endl
         << "Obwod = " << setw(10) << obwod << endl << endl;
    return 0;
}

 

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe