Podstawy języka C++

Transkrypt

Podstawy języka C++
WPROWADZENIE DO JĘZYKA C++
1. Pierwszy program w C++
Przykład 1.1. pierwszy_program.cpp
1:
#include <iostream>
//Dołączenie do programu biblioteki <iostream>
2:
using namespace std;
//Deklaracja przestrzeni nazw std
3:
int main()
5:
{
//Początek definicji programu
6:
cout << "Pierwszy program!\n";
7:
return 0;
8:
}
Po uruchomieniu program powinien wypisać:
Pierwszy program!
Przykład 1.2. wprowadzanie_wypisywanie.cpp
#include <iostream>
using namespace std;
int main()
{
cout<<"Moj pierwszy program";
int a;
cout<<"Podaj bieżący rok";
cin>>a;
cout<<"Podany rok to: "<<a;
system("PAUSE");
return 0;
}
Korzystanie z bibliotek standardowych
Jeśli masz bardzo stary kompilator, przedstawiony powyżej program nie będzie
działał — nie zostaną odnalezione nowe biblioteki standardu ANSI (ANSI nowy standard
języka C++). W takim przypadku zmień kod programu na:
0: #include <iostream.h>
1:
2: int main()
3: {
4:
cout << "Pierwszy program!\n";
5:
return 0;
6: }
Zwróćmy uwagę, że tym razem nazwa biblioteki kończy się na .h (kropka-h) i że nie
korzystamy już z przestrzeni nazw std. Jest to stary, poprzedzający ANSI styl plików
nagłówkowych. Jeśli twój kompilator zadziała z tym programem, lecz nie poradzi sobie
z wersją przedstawioną wcześniej, oznacza to, że jest prawdziwym antykiem.
2. Zmienne i stałe
Program musi mieć możliwość przechowywania używanych przez siebie danych
z których korzysta. Dzięki zmiennym i stałym mamy możliwość reprezentowania,
przechowywania i manipulowania tymi danymi.
2.1. Czym jest zmienna?
W C++ zmienna jest miejscem które służy do przechowywania informacji.
Zmienna jest miejscem w pamięci komputera, w którym możesz umieścić wartość, i
z którego możesz ją później odczytać. Należy zwrócić uwagę, że jest to jedynie
tymczasowe miejsce przechowywania. Gdy wyłączysz komputer, wszystkie zmienne
zostają utracone.
Dane są przechowywane w pamięci
Pamięć komputera można traktować jako szereg pojemników. Każdy pojemnik
jest jednym z bardzo wielu takich samych pojemników, ułożonych jeden za drugim.
Każdy pojemnik — czyli miejsce w pamięci — jest oznaczony kolejnym numerem. Te
numery są nazywane adresami pamięci. Zmienna rezerwuje jeden lub więcej
pojemników, w których może przechowywać wartość.
Rysunek 2.1. Schematyczna reprezentacja pamięci
Przydzielanie pamięci
Gdy definiujesz zmienną w C++, musisz poinformować kompilator o jej rodzaju: czy
jest to liczba całkowita, znak, czy coś innego. Ta informacja mówi kompilatorowi, ile miejsca
ma zarezerwować dla zmiennej oraz jaki rodzaj wartości będzie w tej zmiennej
przechowywany.
Każdy pojemnik ma rozmiar jednego bajta. Jeśli tworzona zmienna ma rozmiar czterech
bajtów, to wymaga czterech bajtów pamięci, czyli czterech pojemników. Typ zmiennej (na
przykład liczba całkowita) mówi kompilatorowi, ile pamięci (pojemników) ma przygotować dla
zmiennej.
Rozmiar liczb całkowitych
W każdym komputerze każdy typ zmiennych zajmuje stałą ilość miejsca.
Oznacza to, że liczba całkowita może mieć w jednym komputerze dwa bajty, zaś w
innym cztery, lecz w danym komputerze ma zawsze ten sam, niezmienny rozmiar.
Zmienna typu char (używana do przechowywania znaków) ma najczęściej rozmiar
jednego bajta.
Krótka liczba całkowita (short) ma w większości komputerów rozmiar dwóch
bajtów, zaś długa liczba całkowita (long) ma zwykle cztery bajty. Natomiast liczba
całkowita (bez słowa kluczowego short lub long) może mieć dwa lub cztery bajty.
Można przypuszczać, że język powinien to określać precyzyjnie, ale tak nie jest.
Ustalono jedynie co musi zostać zapewnione, to że typ short musi mieć rozmiar
mniejszy lub równy typ int (integer, liczba całkowita), który z kolei musi mieć rozmiar
mniejszy lub równy typowi long.
Najprawdopodobniej jednak pracujesz z komputerem, w którym typ short ma dwa
bajty, zaś typy int i long mają po cztery bajty.
Zapis ze znakiem i bez znaku
Wszystkie typy całkowite występują w dwóch odmianach: signed (ze znakiem) oraz
unsigned (bez znaku). Czasem potrzebna jest liczba ujemna, a czasem dodatnia. Liczby
całkowite (krótkie i długie) bez słowa kluczowego unsigned są traktowane jako liczby ze
znakiem. Liczby całkowite signed są albo dodatnie albo ujemne, zaś liczby całkowite
unsigned są zawsze dodatnie.
Liczby ze znakiem i liczby bez znaku mają po tyle samo bajtów, więc największa
liczba, jaką można przechować w zmiennej całkowitej bez znaku jest dwa razy większa niż
największa liczba dodatnia jaką można przechować w zmiennej całkowitej ze znakiem.
Zmienna typu unsigned short może pomieścić wartości od 0 do 65 535. Połowa tych
wartości (reprezentowana przez zmienną typu signed short) jest ujemna, więc zmienna
tego typu może przechowywać jedynie wartości od –32 768 do 32 767. Jeśli wydaje ci się to
skomplikowane, zajrzyj do dodatku A.
Podstawowe typy zmiennych
Język C++ posiada jeszcze kilka innych wbudowanych typów zmiennych. Można je
wygodnie podzielić na typy całkowite, typy zmiennopozycyjne oraz typy znakowe.
Zmienne zmiennoprzecinkowe zawierają wartości, które można wyrazić w postaci ułamków
dziesiętnych — stanowią obszerny podzbiór liczb rzeczywistych. Zmienne znakowe mają
rozmiar jednego bajtu i są używane do przechowywania 256 znaków i symboli pochodzących
z zestawów znaków ASCII i rozszerzonego ASCII.
W tabeli 1.1 przedstawione zostały typy zmiennych używanych w programach C++.
Tabela pokazuje typ zmiennej, jej rozmiar w pamięci oraz rodzaj wartości, jakie mogą być
przechowywane w zmiennej takiego typu.
Tabela 1.1. Typy zmiennych
Rozmiar
Wartości
bool
1 bajt
prawda lub fałsz
unsigned short int
2 bajty
Od 0 do 65 535
short int
2 bajty
Od –32 768 do 32 767
unsigned long int
4 bajty
Od 0 do 4 294 967 295
long int
4 bajty
Od –2 147 483 648 do 2 147 483 647
int (16 bitów)
2 bajty
Od –32 768 do 32 767
int (32 bity)
4 bajty
Od –2 147 483 648 do 2 147 483 647
unsigned int (16 bitów)
2 bajty
Od 0 do 65 535
unsigned int (32 bity)
4 bajty
Od 0 do 4 294 967 295
char
1 bajt
256 różnych znaków
float
4 bajty
Od 1.2e-38 do 3.4e38 (dodatnich lub ujemnych)
8 bajtów
Od 2.2e-308 do 1.8e308 (dodatnich lub ujemnych)
Typ
double
UWAGA: Rozmiary zmiennych mogą się różnić od pokazanych w tabeli (w zależności od
używanego kompilatora i komputera).
2.2. Definiowanie zmiennej
Zmienną tworzy się lub definiuje poprzez określenie jej typu, po którym wpisuje się
jedną lub więcej spacji, zaś po nich nazwę zmiennej i średnik. Nazwę zmiennej może
stanowić praktycznie dowolna kombinacja liter, lecz nie może ona zawierać spacji.
Poprawnymi nazwami zmiennych są na przykład: x, J23qrsnf czy myAge.
Składania deklaracji zmiennej:
typ nazwa_zmiennej;
Przykład definicji (deklaracji zmiennej całkowitej o nazwie x: int x;
UWAGA: Gdy deklarujesz zmienną, jest dla niej alokowana (przygotowywana
i rezerwowana) pamięć. Wartość zmiennej stanowi to, co w danej chwili znajduje się
w tym miejscu pamięci.
Przykłady deklaracji – definiowania zmienny i przypisywania wartości:
Przykład 1:
int main()
{
int x, y, z; //deklaracja zmiennych całkowitych x, y, z
z = x * y; //zmiennej z przypisujemy wartość wartości iloczynu x i y
return 0;
};
Przykład 2:
int main()
{
unsigned short a, b, P; //deklaracja zmiennych całkowitych bez znaku
P = a * b;
return 0;
};
Przykład deklarowania i wypisywania zmiennych
#include <iostream> //przyłaczenie biblioteki
using namespace std; //deklaracja przestrzeni nazw std
int main()
{
//Wprowadzenie danych z klawiatury
cout<<"Podaj a = "; //Wypisanie komunikatu na ekranie;
int a; //deklaracja zmiennej a;
cin>>a;
cout<<"Podaj płeć: m lub k:
"; //Wypisanie komunikatu
na ekranie;
char p; //deklaracja zmiennej z;
cin>>p;
cout<<"\n";
cout<<"\n";
cout<<"Licza pierwsza to: "<<a<<"\n"<<"Plec: "<<p;
cout<<"\n\n";
system("PAUSE");
return 0;
}
Uwzględnianie wielkości liter
Język C++ uwzględnia wielkość liter. Innymi słowy, odróżnia małe i duże litery. Zmienna
o nazwie wiek różni się od zmiennej Wiek, która z kolei jest uważana za różną od zmiennej
WIEK.
Słowa kluczowe
Niektóre słowa są zarezerwowane przez C++ i nie można używać ich jako nazw
zmiennych. Są to słowa kluczowe, używane do sterowania działaniem programu. Należą do
nich if, while, for czy main. Dokumentacja kompilatora powinna zawierać pełną listę słów
kluczowych, ale słowem kluczowym prawie na pewno nie jest każda sensowna nazwa
zmiennej.
Uwagi:
1. Definiuj zmienną, zapisując jej typ, a następnie jej nazwę.
2. Używaj znaczących nazw dla zmiennych.
3. Pamiętaj, że język C++ uwzględnia wielkość znaków.
4. Zapamiętaj ilość bajtów, jaką każdy typ zmiennej zajmuje w pamięci oraz jakie wartości można
przechowywać w zmiennych danego typu.
5. Nie używaj słów kluczowych języka C++ jako nazw zmiennych.
6. Nie używaj zmiennych bez znaku dla wartości ujemnych.
2.3. Tworzenie kilku zmiennych jednocześnie
W jednej instrukcji możesz tworzyć kilka zmiennych tego samego typu; w tym celu
powinieneś zapisać typ, a po nim nazwy zmiennych, oddzielone przecinkami.
Na przykład:
int a, b; //dwie zmienne typu int
long short int area, width, length; //trzy zmienne typu long
Jak widać, a i b są zadeklarowane jako zmienne typu int. Druga linia deklaruje trzy
osobne zmienne typu long; ich nazwy to area (obszar), width (szerokość) oraz length
(długość). W obrębie jednej instrukcji nie można deklarować zmiennych o różnych typach.
2.4. Przypisywanie zmiennym wartości
Do przypisywania zmiennej wartości służy operator przypisania (=). Na przykład zmiennej
a przypisujemy wartość 5, zapisując:
int a; a = 5;
inaczej:
int a = 5; //deklaracja i inicjalizacja jednocześnie;
Inicjalizacja jest podobna do przypisania, a w przypadku zmiennych całkowitych
różnica między nimi jest niewielka.
2.5. Znaki
Zmienne znakowe (typu char) zwykle mają rozmiar jednego bajtu, co wystarczy do
przechowania jednej z 256 wartości. Typ char może być interpretowany jako mała liczba (od
0 do 255) lub jako element zestawu kodów ASCII. Skrót ASCII pochodzi od słów American
Standard Code for Information Interchange. Zestaw znaków ASCII oraz jego odpowiednik
ISO (International Standards Organization) służą do kodowania wszystkich liter (alfabetu
łacińskiego), cyfr oraz znaków przestankowych.
W kodzie ASCII mała litera „a” ma przypisaną wartość 97. Wszystkie duże i małe litery,
wszystkie cyfry oraz wszystkie znaki przestankowe mają przypisane wartości pomiędzy 0 a
127. Dodatkowe 128 znaków i symboli jest zarezerwowanych dla „wykorzystania” przez
producenta komputera, choć standard kodowania stosowany przez firmę IBM stał się niejako
„obowiązkowy”.
Znaki specjalne
Kompilator C++ rozpoznaje pewne specjalne znaki formatujące. Najpopularniejsze z
nich przedstawia tabela 3.2. Kody te umieszcza się w kodzie programu, wpisując znak
odwrotnego ukośnika, a po nim znak specjalny.
Znak specjalny \ zmienia znaczenie znaku, który po nim następuje. Na przykład, normalnie
znak n oznacza po prostu literę n, lecz gdy jest poprzedzony znakiem specjalnym \, oznacza
przejście do nowej linii.
Tabela 3.2. Znaki specjalne
Znak
Oznacza
\a
Bell (dzwonek)
\b
Backspace (znak wstecz)
\f
Form feed (koniec strony)
\n
New line (nowa linia)
\r
Carriage return (powrót „karetki”; powrót na początek linii)
\t
Tab (tabulator)
\v
Vertical tab (tabulator pionowy)
\'
Single quote (apostrof)
\"
Double quote (cudzysłów)
\?
Question mark (znak zapytania)
\\
Backslash (lewy ukośnik)
\0oo
Zapis ósemkowy
\xhhh
Zapis szesnastkowy
2.6. Stałe
Do przechowywania danych służą także stałe. Jednak w odróżnieniu od zmiennej, jak
sama nazwa sugeruje, wartość stałej nie ulega zmianie. Podczas tworzenia stałej trzeba ją
zainicjalizować; później nie można już przypisywać jej innej wartości.
W języku C++ istnieją dwa sposoby deklarowania stałych symbolicznych. Starszy, tradycyjny
(obecnie uważany za przestarzały) polega na wykorzystaniu dyrektywy preprocesora,
#define.
Definiowanie stałych za pomocą #define
Aby zdefiniować stałą w tradycyjny sposób, możesz napisać:
#define nazwa_stałej wartość;
Przykłady:
a) #define a 15; //definicja stałej całkowitej
b) #define w ‘z’; //definicja stałej znakowej
c) #define x 15.0; //definicja stałej rzeczywistej
d) #define wynik true //definicja stałej logicznej
Uwaga: wartość stałej określa jej typ.
Definiowanie stałych za pomocą const
Definiowanie stałych w C++ za pomocą nowszego, lepszego sposobu:
const typ nazwa_stałej = wartość;
Przykłady:
a) const int a =15; //definicja stałej całkowitej
b) const char w = ‘z’; //definicja stałej znakowej
c) const float x = 15.0; //definicja stałej rzeczywistej
d) const bool wynik = true //definicja stałej logicznej
2.7. Stałe wyliczeniowe
Stałe wyliczeniowe umożliwiają tworzenie nowych typów, a następnie definiowanie
ich zmiennych. Wartości takich zmiennych ograniczają się do wartości określonych w
definicji typu. Na przykład, możesz zadeklarować typ COLOR (kolor) jako wyliczenie, dla
którego możesz zdefiniować pięć wartości: RED, BLUE, GREEN, WHITE oraz BLACK.
Składnię definicji wyliczenia stanowią słowo kluczowe enum, nazwa typu, otwierający
nawias klamrowy, lista wartości oddzielonych przecinkami, zamykający nawias klamrowy
oraz średnik.
Składnia definicji stałej wyliczeniowej:
enum nazwa { wartość1, wartość2, wartość3, …, wartośćn };
Przykłady:
a) enum kolor {red, blue, green, white, black}
b) enum tydzien {pn, wt, sr, czw, pt, sob, n}
Przykład programu ze stałą wyliczeniową
0: #include <iostream>
1: int main()
2: {
3:
enum Days { Sunday, Monday, Tuesday,
4:
Wednesday, Thursday, Friday, Saturday };
5:
6:
Days today;
7:
today = Monday;
8:
9:
if (today == Sunday || today == Saturday)
10:
std::cout << "\nUwielbiam weekendy!\n";
11:
else
12:
std::cout << "\nWracaj do pracy.\n";
13:
14:
15:
return 0;
}
wartość wyliczeniową Monday, którą następnie sprawdzamy w linii 9.
3. Wyrażenia i instrukcje
Program stanowi zestaw kolejno wykonywanych instrukcji. Jakość działania programu
zależy od możliwości wykonywania określonego zestawu instrukcji w danych warunkach.
3.1. Instrukcje
W C++ instrukcje kontrolują kolejność działania programu, obliczają wyrażenia lub nie
robią nic (instrukcja pusta). Wszystkie instrukcje C++ kończą się średnikiem (nawet
instrukcja pusta, która składa się wyłącznie ze średnika).
Jedną z najczęściej występujących instrukcji jest instrukcja przypisania.
Składnia instrukcji przypisania:
zmienna = wartość;
Przykłady:
a) a = 20;
b) x = a + b;
Operator przypisania przypisuje to, co znajduje się po prawej stronie znaku równości
elementowi znajdującemu się po lewej stronie.
3.2. Wyrażenia
Wszystko, co staje się wartością, w C++ jest uważane za wyrażenie. Mówi się, że wyrażenie
zwraca wartość. Skoro instrukcja 3+2; zwraca wartość 5, więc jest wyrażeniem. Wszystkie
wyrażenia są jednocześnie instrukcjami.
Wyrażenie:
x = a + b;
nie tylko dodaje do siebie a oraz b, a wynik umieszcza w x, ale także zwraca wartość tego
przypisania (nową wartość x). Zatem instrukcja przypisania także jest wyrażeniem. Ponieważ
jest wyrażeniem, może wystąpić po prawej stronie operatora przypisania:
y = x = a + b;
Ta linia jest przetwarzana w następującym porządku:
Dodaj a do b.
Przypisz wynik wyrażenia a + b do x.
Przypisz rezultat wyrażenia przypisania, x = a + b, do y.
3.3. Operatory
Operator jest symbolem, który powoduje, że kompilator rozpoczyna działanie. Operatory
działają na operandach, zaś wszystkie operandy w C++ są wyrażeniami. W C++ istnieje kilka
kategorii operatorów. Dwie z tych kategorii to:
operatory przypisania,
operatory matematyczne.
Operator przypisania
Operator przypisania (=) powoduje, że operand znajdujący się po lewej stronie operatora
przypisania zmienia wartość na wartość operandu znajdującego się po prawej stronie
operatora.
To wyrażenie:
x = a + b;
przypisuje operandowi x wynik dodawania wartości a i b.
Operatory matematyczne
Piątka operatorów matematycznych to:
a) dodawanie (+),
b) odejmowanie (–),
c) mnożenie (*),
d) dzielenie (/),
e) reszta z dzielenia (%), przykład: 17 % 5 = 2.
Dodawanie i odejmowanie działają rutynowo, choć odejmowanie liczb całkowitych bez znaku
może prowadzić do zadziwiających rezultatów gdy wynik będzie ujemny. Poniższy przykład
pokazuje, co się stanie gdy odejmiesz dużą liczbę całkowitą bez znaku od małej liczby
całkowitej bez znaku.
3.4. Inkrementacja i dekrementacja
Operator inkrementacji (++) zwiększa wartość zmiennej o jeden.
Operator dekrementacji (--) zmniejsza wartość zmiennej o jeden.
Jeśli chcemy inkrementować zmienną C, możemy użyć następującej instrukcji:
C++; // zaczynamy od C i inkrementujemy
Ta instrukcja stanowi odpowiednik bardziej jawnie zapisanej operacji:
C = C + 1;
którą, jak wiemy, możemy zapisać w nieco prostszy sposób:
C += 1;
Przedrostki i przyrostki
Zarówno operator inkrementacji (++), jak i dekrementacji (--) występuje w dwóch
odmianach: przedrostkowej i przyrostkowej.
Odmiana przedrostkowa jest zapisywana przed nazwą zmiennej (++x), zaś odmiana
przyrostkowa — po niej (x++).
Na początku może to wydawać się dość niezrozumiałe, ale jeśli x jest zmienną całkowitą
o wartości 5, to gdy napiszesz
int a = ++x;
poinformujesz kompilator, by inkrementował zmienną x (nadając jej wartość 6), po czym
pobrał tę wartość i przypisał ją zmiennej a.
Zatem po wykonaniu tej instrukcji zarówno zmienna x, jak i zmienna a mają wartość 6.
Jeśli następnie napiszesz
int b = x++;
to poinformujesz kompilator, by pobrał wartość zmiennej x (wynoszącą 6) i przypisał ją
zmiennej b, po czym powrócił do zmiennej x i inkrementował ją. W tym momencie zmienna b
ma wartość 6, a zmienna x ma wartość 7.
Operatory relacji
Operatory relacji są używane do sprawdzania, czy dwie liczby są równe, albo czy jedna
z nich jest większa lub mniejsza od drugiej. Każdy operator relacji zwraca prawdę lub fałsz.
Tabela 4.1. Operatory relacji
Nazwa
Operator
Równe
==
Nie równe
!=
Większe
>
Większe lub równe
>=
Mniejsze
<
Mniejsze lub równe
<=
Przykład
Wynik
100 == 50;
false (fałsz)
50 == 50;
true (prawda)
100 != 50;
true (prawda)
50 != 50;
false (fałsz)
100 > 50;
true (prawda)
50 > 50;
false (fałsz)
100 >= 50;
true (prawda)
50 >= 50;
true (prawda)
100 < 50;
false (fałsz)
50 < 50;
false (fałsz)
100 <= 50;
false (fałsz)
50 <= 50;
true (prawda)
Uwaga:
1. Pamiętaj, że operatory relacji zwracają wartość true (prawda) lub false (fałsz).
2. Nie myl operatora przypisania (=) z operatorem relacji równości (==). Jest to jeden z
najczęstszych błędów popełnianych przez programistów C++.
3.5. Operatory logiczne
Tabela 4.2. Operatory logiczne
Operator
Symbol
Przykład
I (AND)
&&
wyrażenie1 && wyrażenie2
LUB (OR)
||
wyrażenie1 || wyrażenie2
NIE (NOT)
!
!wyrażenie
Logiczne I
Instrukcja logicznego I (AND) oblicza dwa wyrażenia, jeżeli oba mają wartość true,
wartością całego wyrażenia I także jest true.
Zatem
if ( (x == 5) && (y == 5) )
będzie prawdziwe, gdy zarówno x, jak i y ma wartość 5, zaś będzie nieprawdziwe, gdy któraś
z tych zmiennych będzie miała wartość różną od 5. Zapamiętaj, że aby całe wyrażenie było
prawdziwe, prawdziwe muszą być oba wyrażenia.
Logiczne LUB
Instrukcja logicznego LUB (OR) oblicza dwa wyrażenia, gdy któreś z nich ma wartość true,
wtedy wartością całego wyrażenia LUB także jest true. Jeśli prawdą jest, że masz gotówkę
LUB prawdą jest że, masz kartę kredytową, WTEDY możesz zapłacić rachunek. Nie
potrzebujesz jednocześnie gotówki i karty kredytowej, choć posiadanie obu jednocześnie nie
przeszkadza. Zatem
if ( (x == 5) || (y == 5) )
będzie prawdziwe, gdy x lub y ma wartość 5, lub gdy obie zmienne mają wartość 5.
Logiczne NIE
Instrukcja logicznego NIE (NOT) ma wartość true, gdy sprawdzane wyrażenie ma wartość
false. Jeżeli sprawdzane wyrażenie ma wartość true, operator logiczny NIE zwraca wartość
false. Zatem
if ( !(x == 5) )
jest prawdziwe tylko wtedy, gdy x jest różne od 5. Identycznie działa zapis:
if (x != 5)
Literatura:
1. Jesse Liberty „C++ dla każdego”, Helion