« Pojęcie zmiennej i podstawowe typy danych, lekcja »
Rozdział 8. Omówienie podstawowych zagadnień związanych ze zmiennymi: dostępne typy danych; tworzenie i inicjalizacja zmiennych oraz operacja przypisania. (lekcja)
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!
Autor: Piotr Szawdyński
Kurs C++

Pojęcie zmiennej i podstawowe typy danych

[lekcja] Rozdział 8. Omówienie podstawowych zagadnień związanych ze zmiennymi: dostępne typy danych; tworzenie i inicjalizacja zmiennych oraz operacja przypisania.
Po kilku rozdziałach za sobą prawdopodobnie czujesz, jak wiatr Ci wieje w plecy i posuwasz się w szybkim tempie do przodu. Od tej pory wiatr będzie wiał Ci prosto w oczy, jeśli nie będziesz czytał tekstu uważnie. Dochodzimy bowiem do zagadnień, które nie są już takie oczywiste i intuicyjne dla osoby, która nigdy nie zajmowała się programowaniem. Wdech... wydech... wdech... wydech... i zaczynamy :)

Pojęcie zmiennej

Programy jakie do tej pory napisaliśmy, wyświetlały jedynie tekst na ekranie. Aplikacje, które wypisują tylko i wyłącznie komunikaty są zazwyczaj mało interesujące. Biblioteka <iostream> pozwala nam nie tylko wypisywać tekst, ale również wczytywać dane do zmiennych. Zanim jednak zapoznamy się z instrukcją wczytywania, należy zapoznać się z pojęciem zmiennej. Zmienna, jak sama nazwa wskazuje będzie się zmieniać w trakcie programu. Zmienna to pewien stosunkowo mały obszar w pamięci, w którym możemy przechowywać dane różnego typu np. liczby całkowite, liczby rzeczywiste (zmiennoprzecinkowe), znak, tekst oraz kilka innych wartości, które będą nas w przyszłości interesowały. Nie można jednak wszystkiego zapisywać do jednej zmiennej. Każda zmienna ma swoje przeznaczenie, wielkość i właściwości. Na zmiennych liczbowych możemy wykonywać operacje matematyczne, w innych z kolei możemy przechowywać tekst.

Typy danych

Skoro już wiemy co to jest zmienna, pora zapoznać się z podstawowymi typami danych jakie są dostępne w C++.
Nazwa typuIlość
Bajtów
Zakres wartości
bool1false lub true
char1od -128 do 127
unsigned char1od 0 do 255
wchar_t2od 0 do 65'535
short2od -32'768 do 32'767
unsigned short2od 0 do 65'535
int4od -2'147'483'648 do 2'147'483'647
unsigned int4od 0 do 4'294'967'295
long4od -2'147'483'648 do 2'147'483'647
unsigned long4od 0 do 4'294'967'295
long long8od -9'223'372'036'854'775'808 do 9'223'372'036'854'775'807
unsigned long long8od 0 do 18'446'744'073'709'551'615
float43.4E +/- 38 (7 cyfr)
double81.7E +/- 308 (15 cyfr)
long double81.7E +/- 308 (15 cyfr)
Powyższe rozmiary danych są podane dla 32-bitowego kompilatora Visual C++. Jeśli chcesz sprawdzić ile w rzeczywistości zajmuje określony typ danych dla Twojego kompilatora, wystarczy napisać prosty program i wykorzystać w nim słowo kluczowe sizeof. Przykładowo, dla kompilatora GNU g++ rozmiar typu long double wynosi 12 bajtów, a nie 8 bajtów jak w Visual C++.

Przykład zastosowania sizeof

C/C++
#include <iostream>
#include <cstdio>
int main()
{
    std::cout << "sizeof(bool) = " << sizeof( bool ) << std::endl;
    std::cout << "sizeof(char) = " << sizeof( char ) << std::endl;
    std::cout << "sizeof(unsigned char) = " << sizeof( unsigned char ) << std::endl;
    std::cout << "sizeof(wchar_t) = " << sizeof( wchar_t ) << std::endl;
    std::cout << "sizeof(short) = " << sizeof( short ) << std::endl;
    std::cout << "sizeof(unsigned short) = " << sizeof( unsigned short ) << std::endl;
    std::cout << "sizeof(int) = " << sizeof( int ) << std::endl;
    std::cout << "sizeof(unsigned int) = " << sizeof( unsigned int ) << std::endl;
    std::cout << "sizeof(long) = " << sizeof( long ) << std::endl;
    std::cout << "sizeof(unsigned long) = " << sizeof( unsigned long ) << std::endl;
    std::cout << "sizeof(long long) = " << sizeof( long long ) << std::endl;
    std::cout << "sizeof(float) = " << sizeof( float ) << std::endl;
    std::cout << "sizeof(double) = " << sizeof( double ) << std::endl;
    std::cout << "sizeof(long double) = " << sizeof( long double ) << std::endl;
    return 0;
}

Przykład

Zademonstruję teraz na przykładzie, jak się deklaruje zmienne i jak się z nich korzysta.
C/C++
#include <iostream>

int main()
{
    int to_jest_zmienna;
    unsigned int tylkoDodatnie;
   
    float zmiennoprzecinkowa;
   
    char jeden_znak;
    unsigned char rowniez_znak;
   
    int abc = - 53;
   
    tylkoDodatnie = 22;
    zmiennoprzecinkowa = 12.42;
    rowniez_znak = 'c';
   
    std::cout << "Wypisujemy zmienne:" << std::endl;
    std::cout << "  to_jest_zmienna = " << to_jest_zmienna << std::endl;
    std::cout << "  tylkoDodatnie = " << tylkoDodatnie << std::endl;
    std::cout << "  abc = " << abc << std::endl;
    std::cout << "  zmiennoprzecinkowa = " << zmiennoprzecinkowa << std::endl;
    std::cout << "  jeden_znak = " << jeden_znak << std::endl;
    std::cout << "  rowniez_znak = " << rowniez_znak << std::endl;
    return 0;
}
Efekt działania powyższego programu może wyglądać np. tak:
Wypisujemy zmienne:
  to_jest_zmienna = 2293728
  tylkoDodatnie = 22
  abc = -53
  zmiennoprzecinkowa = 12.42
  jeden_znak = 
  rowniez_znak = c

Process returned 0 (0x0)   execution time : 0.062 s
Press any key to continue.
Zwróć uwagę na wypisane wartości zmiennych, którym nie została przypisana wartość początkowa. Wartości są przypadkowe. Warto więc inicjalizować wszystkie zmienne początkową wartością.

Co to jest inicjalizacja

Inicjalizacja jest to nadawanie początkowej wartości zmiennej w chwili jej tworzenia.

Tworzenie zmiennych

Powyższy przykład pokazuje nam, jak tworzy się zmienne w programie. W ogólnym przypadku, tworzenie zmiennych zapisuje się następująco: typ_zmiennej nazwa_zmiennej; lub typ_zmiennej nazwa_zmiennej = wartość_zmiennej;. Pierwszy zapis, rezerwuje nam pamięć w programie. Należy pamiętać, że wartość w zmiennej będzie przypadkowa. Kompilator nie zeruje wartości zmiennych! Jeśli chcemy od razu nadać zmiennej początkową wartość, możemy to zrobić korzystając z zapisu drugiego - dokonujemy wówczas inicjalizacji zmiennej początkową wartością.

Instrukcja przypisania

Jeśli nie chcemy nadawać od razu początkowej wartości zmiennej, możemy zawsze to zrobić później w następujący sposób: nazwa_zmiennej = nowa_wartość_dla_zmiennej;. Operator = służy do przypisywania nowej wartości zmiennej. Wartość jaką przechowuje zmienna, możesz zmieniać wielokrotnie w trakcie działania aplikacji.

Nazewnictwo zmiennych

Kolejną rzeczą o której należy wspomnieć jest nazewnictwo zmiennych. Nazwy zmiennych nie mogą zawierać polskich znaków. Dozwolone znaki to: (a..z), (A...Z), podkreślenie ( _ ) i cyfry (0...9). Nazwa zmiennej nie może się również zaczynać od liczby. Zmienne muszą posiadać unikatową nazwę w obrębie całego programu (dokładniej to w obrębie funkcji, ale o tym przypomnę gdy dojdziemy do tematu funkcji). Warto tu również podkreślić, że zmienna int abc; nie jest tą samą zmienną co int ABC;. Są to dwie różne zmienne, o różnych nazwach.

Zasięg zmiennych

Każda zmienna ma również swój zasięg, w którym jest widoczna. Zasięg ten determinują klamry { ... }. Zmienna, którą utworzysz będzie widoczna tylko w obrębie danego bloku. Na razie nie będziemy wgłębiali się w szczegóły. Jak przyjdzie na to pora, przypomnę tą informację, z szerszym wyjaśnieniem i odpowiednim przykładem.

Słowo kluczowe unsigned

Kolejną sprawą, którą należy wyjaśnić jest słowo kluczowe unsigned przed niektórymi zmiennymi. Wyraz ten możemy wpisywać przed każdą zmienną całkowitą/znakową, jeśli chcemy, aby przechowywane w zmiennej wartości były nieujemne. Dzięki temu do zmiennej możemy zapisać dwa razy większą liczbę dodatnią. Nie możemy natomiast zapisać już do niej liczby ujemnej.

Zadanie domowe

Mamy następujący kod:
C/C++
#include <iostream>
int main()
{
    std::cout << "Liczba = " << nieznana << std::endl;
    return 0;
}
Próba kompilacji powyższego programu się nie powiedzie, a w logu kompilacji otrzymamy następujący komunikat:
error: 'nieznana' was not declared in this scope
Popraw program tak, aby się skompilował i wypisał na ekranie liczbę 123. W programie nie wolno usuwać ani zmienić żadnej istniejącej linijki.
Poprzedni dokumentNastępny dokument
Przestrzeń nazw stdObsługa strumienia wejściowego