Kurs C++

Transkrypt

Kurs C++
Podstawy Informatyki
Wykład 5
Różne pożyteczne algorytmy
Algorytm sprawdzania parzystości liczby
We:
sprawdzana liczba x
y = (x/2)*2
N
WY: x nieparzyste
T
?
x=y
WY: x parzyste
Algorytm sprawdzania parzystości liczby
Program parzystosc;
{ Deklaracja zmiennych }
x,y:
całkowita;
Początek
pisz(‘podaj liczbe x’);
czytaj(x);
y := x/2;
y := y*2;
jeżeli (x=y) to pisz („liczba x jest parzysta”)
w przeciwnym razie pisz („liczba x jest nieparzysta”)
koniec.
Uwaga:
Program ma sens tylko dzięki własności dzielenia liczb całkowitych
.
Algorytm sprawdzania czy trójkąt jest prostokątny
We:
a,b,c – boki trójkąta
d = a*a + b*b
WY: trójkąt nie
jest prostokątny
N
T
?
d=c*c
WY: trójkąt jest
prostokątny
Algorytm sprawdzania czy trójkąt jest
prostokątny
Program trojkat prostokatny;
{ Deklaracja zmiennych }
a,b,c,d:
całkowita;
Początek
pisz(‘podaj boki a,b,c);
d:=a*a+b*b;
jeżeli (d=c*c) to pisz („trójkąt prostokątny”)
w przeciwnym razie pisz („trójkąt nie
jest prostokątny”)
Gdzie tkwi błąd?
Jak poprawić ten program?
koniec.
.
Obliczanie pierwiastka kwadratowego
Obliczanie pierwiastka kwadratowego:
Przykład:
Jak obliczyć pierwiastek z x?
Metoda Newtona:
y + xy
y=
2
x- liczba pierwiastkowana
y - wynik pierwiastkowania
.
Obliczanie pierwiastka kwadratowego - algorytm:
Program pierwiastek kwadratowy;
{ Deklaracja zmiennych }
x,y:
rzeczywista;
i:
całkowita;
Początek
pisz(‘podaj x);
y := 1;
dla i:=0 do i:= 20
y:=(y+x/y)/2;
pisz („pierwiastek z”, x, „ = ” , y)
.
koniec.
Sito Erastotenesa
Wyszukiwanie liczb pierwszych
1
2
3
4
5
6
7
8
9
10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26
2
3
4
5
6
7
8
9
10 11 12 13
↑
14 15 16 17 18 19 20 21 22 23 24 25 26
Sito Erastotenesa
2
3
5
7
9
11
13
↑
15
2
17
3
19
5
21
23
7
25
11
13
↑
17
19
Kiedy koniec? Dla √n
23
25
program sito
a: tablica [1...1000] elementów całkowitych
i,j,n,m,x,y:całkowite
pisz 'podaj górną granicę przedziału, max 1000'
czytaj n
m=int(sqrt(n)) {maksymalny mnoznik – pierwiastek z n)
dla i=1 do n wykonuj
a[i]=i {podstawienie kolejnych liczb do tablicy}
dla j=2 do m wykonuj
początek
jeśli a[j] <>0 to
początek
dla i=j+1 do n wykonuj
początek
x=a[i]
y=(x/j)*j {sprawdzanie podzielności}
jeśli x=y to a[i]=0
koniec
koniec
koniec
pisz 'w podanym zakresie liczby pierwsze to:'
dla i=2 do n
jeśli a[i] <>0 to drukuj a[i]
koniec
Krótki kurs C++
Historia
•Lata 70-te XX w – język C (do pisania systemów operacyjnych)
•"The C programming language" B. Kernighan, D. Ritchie
– pierwszy standard
•Koniec lat 80 – standard ANSI C
•1983 - C++ (Bjarne Stroustrup)
•Do chwili obecnej nie stosuje się jednego standardu!
Kompilatory C++
•Microsoft Visual C++ (w ramach licencji MSDN AA)
Darmowe:
Linux (PC), Solaris (SUN) :
•http://gcc.gnu.org/ - g++
Windows :
•http://www.bloodshed.net/dev/devcpp.html - Dev-C++
•http://www.delorie.com/djgpp/ - DJGPP
•http://www.mingw.org/ - MinGW
Kompilacja
*.cpp
nagłówki
moduły
biblioteki
kompilator
linker
błędy
błędy
UNIX
Kompilacja:
1) g++ prog.cpp
2) g++ -o prog prog.cpp
Uruchomienie:
1) a.out
2) prog
programm
Pierwszy program
#include <iostream>
#include <string>
using namespace std;
int main()
{
string komunikat;
double a,b,c;
komunikat = "Koniec obliczeń";
cout <<"Podaj a i b: ";
cin >>a>>b;
c=a+b;
cout <<" suma "<<a<<" i "<<b<<" wynosi
"<<c<<'\n';
cout<<komunikat<<'\n';
return 0;
}
Dyrektywy preprocesora
#include <iostream>
#include <string>
Program przed kompilacją dołącza zewnętrzne pliki – np pliki
nagłówkowe.
Poniżej fragment pliku iostream:
extern _IO_istream_withassign cin;
// clog->rdbuf() == cerr->rdbuf()
extern _IO_ostream_withassign cout, cerr;
Zdefiniowanie przestrzeni nazw:
using namespace std;
Program główny
int main()
{
...
...
return 0;
}
Program główny traktowany jest jak funkcja – musi
zwrócić jakąś wartość (typu integer)
Zwracając do systemu operacyjnego wartość 0 informujemy,
że program zakończył się bez błędu.
Deklaracja zmiennych
string komunikat;
double a,b,c;
•short int - typ całkowity krótki
•int - typ całkowity.
•long int - typ całkowity długi
•float - typ zmiennoprzecinkowy pojedynczej precyzji.
•double - typ zmiennoprzecinkowy podwójnej precyzji.
•long double - typ zmiennoprzecinkowy podwójnej precyzji długi.
•char - typ znakowy
•string – ciąg znaków
Nazwy zmiennych mogą składać się z liter,cyfr i podkreślenia _
Nazwa nie może się zaczynać od cyfry
unsigned – zmienna bez znaku (tylko dodatnia) – dla typów int
int (–127,128)
unsigned int (0,255)
Operatory
komunikat = "Koniec obliczeń";
c=a+b;
•operator przypisania
•operator dodawania
•operator odejmowania
•operator mnożenia
•operator dzielenia
•operator reszty z dzielenia (modulo)
•operator znaku liczby (np. -45)
=
+
*
/
%
Operatory złożone
+=
-=
*=
/=
%=
zmienna += 2
zmienna -= 7
zmienna *= 3
zmienna /= 5
zmienna %= 3
≡
≡
≡
≡
≡
zmienna = zmienna + 2
zmienna = zmienna - 7
zmienna = zmienna * 3
zmienna = zmienna / 5
zmienna = zmienna % 3
Operatory inkrementacji i dekrementacji
++ zwiększenie wartości o 1, np. i++ to jest to samo co i=i+1
-- zmniejszenie wartości o 1, np. i-- to jest to samo co i=i-1
Uwaga! Operatory te można stosować przed i po zmiennej, tzn.
liczba++ lub ++liczba. Podobnie dla --. Mimo, że działanie
operatora w obu wypadkach jest podobne, to nie jest jednak
identyczne!
++liczba najpierw dodaje do liczby 1, a potem zwraca jej wartość
liczba++ najpierw zwraca wartość, a potem dodaje
liczba =5;
a) cout<<++liczba;
drukuje 6
b) cout<<liczba++;
drukuje 5
a liczba jest po instrukcji a lub b zawsze równa 6
Operatory relacji
==
!=
>
>=
<
<=
równa się
jest różne
jest większe
jest większe lub równe
jest mniejsze
jest mniejsze lub równe
Operatory logiczne
|| suma - prawdziwe jeśli którekolwiek z wyrażeń jest prawdziwe
&& iloczyn - prawdziwe jeśli oba wyrażenia są prawdziwe
! negacja logiczna - powoduje zaprzeczenie wyrażenia
Uwaga!
Przypisanie = zwraca wartość przypisania czyli np. a=3 zwraca
wartość 3, a każda liczba różna od zera jest w języku C++
traktowana jako prawda. Tylko wartość 0 jest traktowana jako fałsz.
(a=2) || (3==5) ⇒ zawsze prawda;
(a==2)||(3==5) niekoniecznie
Opercje wejścia i wyjścia
Strumienie – biblioteka iostream
cout - powiązany ze standardowym urządzeniem wyjścia
cin - powiązany ze standardowym urządzeniem wejścia
cerr - strumień błędów - połączony ze standardowym
urządzeniem wyjścia
clog - podobnie jak cerr, ale wydajniejszy przy wielu danych
<< - operator wysyłania do strumienia
>> - operator pobierania ze strumienia
np.
cin >>a>>b;
cout <<x1;
cout <<y1<<' '<<y2<<'\n';
Instrukcja warunkowa
if (warunek)
instrukcja1;
else
instrukcja2;
if (warunek)
{
instrukcja1;
instrukcja2;
...
instrukcjan;
}
else
{
instrukcja1;
instrukcja2;
...
instrukcjan;
}
Tablice
int calkowite[20];
char znaki[5];
double liczby[1000];
string napisy[5];
- przechowuje 20 liczb typu int
- p. 5 znaków
- p. 1000 liczb typu double
- p. 5 napisów (wieloznakowych)
Uwaga! Rozmiar tablicy musi być podany przed kompilacją
znaki[0] - pierwszy element tablicy znaki
znaki[4] – piąty element tablicy
Inicjacja tablicy
int calk[5]={2,-3,4,8,12};
int aa[3]={12,-3};
Nie zainicjowane wyrazy otrzymują wartość 0
Nie zainicjowana tablica ma nieokreślone wartości.
int bb[3]={2,-3,4,8}; //Kompilator wykaże błąd!
a=bb[4] – program nie zasygnalizuje błędu, ale
przeczyta nieprzewidywalne dane!
Pętle (1) - for
for (licznik=pocz;licznik<konc;++licznik)
{
Instrukcje w pętli
....
}
licznik – zmienna sterująca pętlą
Wykonuje się dla wartości licznik: od pocz do konc
z dodaniem 1 (++licznik) za każdym cyklem
-------------------------------------------------------------------------------------------for (licznik=pocz;licznik<konc;++licznik)
{
Instrukcje w pętli
....
++licznik
}
Licznik zwiększamy dwa razy!
int licznik;
for (licznik=pocz;licznik<konc;++licznik)
{
Instrukcje w pętli
....
}
Pętla wykona się 9 razy
Po zakończeniu pętli zmienna licznik wynosi 10
--------------------------------------------------------------------------------Nie musimy deklarować oddzielnej zmiennej licznik:
for (int licznik=pocz;licznik<konc;++licznik)
{
Instrukcje w pętli
....
}
Po zakończeniu pętli zmienna licznik... nie istnieje
Odliczanie "z góry"
int licznik;
for (licznik=10;licznik>=0;--licznik)
{
Instrukcje w pętli
....
}
Pętla wykona się 11 razy
Po zakończeniu pętli zmienna licznik wynosi -1
Nie możemy w tym przypadku zadeklarować zmiennej licznik jako
unsigned int
Pętle zagnieżdżone
int i, j,k=1;
for (i=1;i<=10; i+=3)
{
for (j=5;j>=2;--j)
{
Instrukcje w pętli
.......
cout<<i<<j<<k;
++k;
}
}
i
j
k
1
5
1
1
4
2
1
3
3
1
2
4
4
5
5
4
4
6
4
3
7
4
2
8
7
5
9
7
4
10
7
3
11
7
2
12
10
5
13
10
4
14
10
3
15
10
2
16
Pętle (2) – do ... while
do
{
instrukcje w pętli
...
}
while (warunek);
Wykonuje się dla wartości warunek: prawda
Gdy warunek przestaje być prawdziwy – wychodzimy z pętli
-------------------------------------------------------------------------------------------Pętla wykona się co najmniej jeden raz!
W pętli for warunek (zakresu) był sprawdzany na początku i instrukcje
w pętli mogły się nie wykonać ani raz!
Pętle (2) – do ... while
int i=3;
do
{
instrukcje w pętli
.....
cout<<i<<'\n';
++i;
}
while (i<10);
3
4
5
6
7
8
9
int i=3;
do
{
instrukcje w pętli
.....
cout<<i<<'\n';
++i;
}
while (i<1);
3
Pętle (3) – while
while (warunek)
{
instrukcje w pętli
...
}
Wykonuje się dla wartości warunek: prawda
Gdy warunek przestaje być prawdziwy – wychodzimy z pętli
-------------------------------------------------------------------------------------------Pętla może się nie wykonać ani jeden raz!
W pętli while warunek jest sprawdzany na początku i instrukcje w pętli
mogą się w ogóle nie wykonać
Pętle (3) – while
int i=3;
while (i<10)
{
instrukcje w pętli
.....
cout<<i<<'\n';
++i;
}
3
4
5
6
7
8
9
int i=3;
while (i<1)
{
instrukcje w pętli
.....
cout<<i<<'\n';
++i;
}
(nic)
Pętle i tablice
int tabl[n]; //tablica n-elementowa
unsigned int i; //zmienna sterujaca petlami
for (i=0;i<n;++i)
// wczytanie elementow tablicy
{
cout <<"Podaj "<<i+1<<". element tablicy: ";
cin >>tabl[i];
}
for (i=0;i<n;++i)
// dodanie liczby 10 do kazdego elementu tablicy
tabl [i]+=10;
for (i=0;i<n;++i)
// wypisanie elementow tablicy
cout <<tabl[i]<<'\n ';
Pętle i tablice
const int n=26; // rozmiar tablicy z danymi
float dane[n];
unsigned int i; //zmienna sterujaca petlami
float suma,srednia;
// suma wyrazow, petla while
i=0;
suma=0;
while (i<n)
{
suma+=dane[i];
++i;
}
srednia=suma/n;
Break – przerwanie pętli
Liczymy średnią arytmetyczną wczytanych liczb (max 100).
Element równy zero kończy wczytywanie.
int i;
float a,suma=0,srednia;
for (i=0;i<99;++i)
{
cin>>a;
if (a==0)
break;
suma+=a;
}
srednia=suma/i;
cout<<srednia<<'\n'
Jeśli stosujemy zagnieżdżone pętle i użyjemy instrukcji break w pętli
najbardziej wewnętrznej, to zostanie przerwana jedynie ta najbardziej
wewnętrzna pętla, pozostałe pętle będą się wykonywać.
Continue – przerwanie kroku pętli
Z przedziału 1..n podajemy liczby podzielne przez 3
for (unsigned int i=0;i<=n;++i)
{
if ((i%3)!=0)
continue;
cout <<"Liczba "<<i<<"jest podzielna przez 3\n";
}
Program wraca na początek pętli i wykonuje kolejny krok
Etykiety i instrukcje skoku goto
{
instrukcje programu
......
goto NazwaEtykiety2;
.......
NazwaEtykiety1:
.........
........
goto NazwaEtykiety1;
.......
.......
NazwaEtykiety2:
.....
.....
}
W miejscu umieszczenia etykiety dwukropek
Po instrukcji goto średnik
Operator warunkowy
wyrażenie1 ? wyrażenie2 : wyrażenie3;
Jeżeli wyrażenie1 jest prawdziwe, to wykonuj wyrażenie2 ,
a jeśli jest fałszywe – wykonuj wyrażenie3
(a<b) ? cout <<"a jest mniejsze" : cout <<"b jest mniejsze";
zastępuje:
if (a<b)
cout <<"a jest mniejsze";
else
cout <<"b jest mniejsze";
Instrukcja wyboru switch
switch (wyrażenie)
{
case wartosc1:
Instrukcje1;
break;
case wartosc2:
Instrukcje2;
break;
...
case wartoscn:
InstrukcjeN;
break;
default:
InstrukcjaDomyslna;
}
Obliczana jest wartość wyrażenia. Jeśli jest równa wartosc1 – wykonywane są
instrukcje1, jeśli wynik wynosi wartość2 – wykonywane są instrukcje2 itd.
Jeśli wynik wyrażenia nie jest równy żadnemu przypadkowi (case) –
wykonywana jest instrukcja domyślna (default)