Title: C Bjarne Stroustrup AT
1CBjarne StroustrupATT Bell-Laboratories
- Historia
- 1980 - dodanie do C klas itp., jako punkt wyjscia
przyjeto jezyk Simula 67 (C z klasami) - 1983/84 - powstanie C
- 1989 C wesja 2 (CFront 2.0, m.in.
wielodziedziczenie) - 1998 - Standard C (ISO/IEC 148821998).
- 2003 - tech. korekty (ISO/IEC 148822003)
- Zalety
- Bazuje na bardzo popularnym C
- efektywnosc polaczona z obiektowoscia
- mozliwosc tworzenia duzych systemów ulatwiona
przez obiektowosc - duza przenaszalnosc
- ciagly rozwój
- Wady
- polaczenie mechanizmów niskopoziomowych (z C) z
wysokopoziomowymi mechanizmami obiektowymi - w
C trudno programowac dobrze - C zawiera prawie wszystkie znane mechanizmy
obiektowe, a takze polaczenie tych mechanizmów z
innymi, np. przeciazaniem funkcji
2Literatura
- Jezyk C Bjarne Stroustrup WNT 2000 wyd. 5te
i zmienione, - Jezyk C, cwiczenia i rozwiazania David
Vandevoorde WNT 2001, - The C Standard Incorporating Technical
Corrigendum No. 1, British Standards
Institute782 pages, 2nd ed.,19 December 2003, - Podstawy jezyka C Stanley B. Lippman, Josee
Lajoie WNT 2001, - Podstawy jezyka C, cwiczenia i rozwiazania
Clovis L. Tondo WNT 2001, - C Biblioteka standardowa, podrecznik
programisty Nicolai M. Josuttis Helion 2003, - Projektowanie i rozwój jezyka C, Bjarne
Stroustrup, WNT 1996, - C zadania i odpowiedzi, Tony L. Hansen, WNT
1994, - Internet (draft proposed International Standard
for Information Systems Programming language
C, X3J16/96-0225, 2 XII 1996 699 stron w tym
370 jezyk, 329 biblioteki).
3Komentarze / wielowierszowy / //
jednowierszowy Deklaracje zmiennych int x //
zmienna x typu integer int y 3 // zmienna y z
okreslona wartoscia poczatkowa 3 int z y //
zmienna z okreslona wartoscia pocz. y (czyli
3) char p // zmienna p typu wskaznik do
znaku T y // zmienna y typu T // T moze byc
typem pierwotnym, klasa, struktura // lub
unia float tab 100 // 100-elementowa tablica
liczb rzeczywistych int tablica // zapewne
tablica liczb calkowitych // rozmiar zostanie
okreslony przez new char str // zapewne
tablica wskazników do znaków (czyli //
napisów), rozmiar zostanie okreslony przez
new int (arr) 10 // wskaznik do
10-elementowej tablicy liczb int p 4, 7,
8 // 3-elementowa tablica zawierajaca liczby
4, 7, 8 Uwaga nazwa tablicy jest utozsamiana ze
stalym wskaznikiem do pierwszego elementu
tablicy. Elementy tablicy sa zawsze indeksowane
od 0. int tab1 100 jest prawie
równowazne int tab2 tab1 10 123
(tab2 10) 123 (tab1 10) 123
tab2 10 123 a nawet 10tab1
123 10tab1 123 ALE tab1 jest
zainicjowane a tab2 NIE i po lewej jest
100-elementowa tablica, a po prawej nie ma
jeszcze zadnej tablicy!!!
4Stale (tylko C) const int x 145 // nie
mozna zmienic wartosci x const int p // nie
mozna zmien. liczb wsk. przez p const int V
1, 2, 3, 4 // nie mozna zmienic eltów tablicy
V const char napis abcdef char const nap
abcdef const char const nap3
"abcdef" Specyfikacja const stwierdza, ze nie
mozna zmienic obiektu w ten sposób
zadeklarowanego. V 3 10 // nielegalne V
new int // ok napis 3 0 //
nielegalne napis xyz // ok nap 3
0 // ok nap xyz // nielegalne Czesto
uzywa sie deklaracji const dla parametru funkcji
aby podkreslic, ze funkcja tego parametru nie
moze zmienic (read only). char strcpy (char
p, const char q) // q nie moze byc
zmieniane Typy (Niektóre) typy pierwotne char,
short, int, long, float, double Typy
wyprowadzane (derived types) wskaznik referen
cja tablica ( ) funkcja Typy
wyliczeniowe enum kolor czerowny, bialy,
czarny, zielony // wprowadza juz nazwe typu -
kolor
5Konwersja typów (stare) (char ) w
float (29) (nowe) static_castltfloatgt(3) t
yp void pusty typ
Wyrazenia Instrukcja przypisania jest wyrazeniem
(z efektami ubocznymi). x 23 x wartoscia
wyrazenia jest x po wykonaniu wyrazenia x ma
wartosc zwiekszona o 1 x wartoscia wyrazenia
jest x1 po wykonaniu wyrazenia x ma wartosc
zwiekszona o 1 x-- --x podobnie x w // x
x w Zamiast moze wystapic inny operator, np.
, - koniunkcja alternatywa ! negacja p
orównanie ! rózne int p int x p obiekt
wskazywany przez p x adres obiektu x uzycie
p x Uwaga na wskazniki char p new
charstrlen(src1) strcpy(src, p) // Bledny
fragment programu (ale kompilujacy sie bez //
ostrzezen) zwn zle polozenie czerwonego nawiasu.
6Referencje
T - typ, T - typ referencja do T Referencja
jest inna nazwa obiektu (aliasem). int i
1 int r i // wartoscia i oraz r jest ten
sam obiekt (liczba) // zmienna
typu referencyjnego musi byc zainicjowana r 5
// teraz takze i 5 Referencje sa uzywane
przy parametrach funkcji do przekazywania parametr
ów przez referencje (tak, jak przez zmienna w
Pascalu). Nie moze byc wskazników do referencji
(ani tablic referencji). Ale referencja do
wskaznika jest poprawna. Referencja to nie jest
wskaznik !!! Przyklad Funkcja zamieniajaca
wartosci dwóch zmiennych. (1) za pomoca
wskazników void swap (int a, int b) int
temp temp a a b b temp
wywolanie swap (x, y ) // tu oznacza
adres (2) za pomoca referencji swap (int a, int
b) // parametrem aktualnym musi byc
zmienna int temp temp a a b b
temp wywolanie swap (x, y) Referencji
uzywamy najczesciej wtedy, gdy jako parametr
funkcji chcemy przekazac obiekt, a nie jego kopie.
7 Instrukcje Wyrazenie zakonczone jest
instrukcja. np. x lista instrukcji if
(wyrazenie) instrukcja if (wyrazenie) instrukcja1
else instrukcja2 if (x lt 0) x while
(wyrazenie) instrukcja do instrukcja while
(wyrazenie) while (i lt n tab i ! x) //
n - rozmiar tablicy i do x x - y while
(x gt y) char nap1 123456789 char nap2
100 char p, q p nap1 q
nap2 while ( p ! 0) q p for
(instr_start wyr_koncowe wyr) instrukcja2 instr
_start while (wyr_koncowe) instrukcja2 wyr
for (i0 i lt n i) tab i 100
8break // przerywa wykonanie petli lub
instrukcji switch return wyrazenie // powrót z
funkcji switch (wyr) case const1
instr1 instr2 ..... break // powoduje wyjscie
z instrukcji switch case const2 instr1 ...... de
fault instr1 instr2 .... Funkcje float
pow (float x, int n) float y 0 if (n lt 0)
error ( ujemny wykladnik) else switch ( n
) case 0 y 1 break case 1 y x
break dafault y x pow ( x, n-1
) return(y)
9void main ( ) ...... // glówna
funkcja Przekazywanie parametrów przez
wartosc tylko (normalny sposób w C) ALE moze byc
typ referencyjny (tylko C) void zamien (int
x, int y) // zamienia wartosci zmiennych x i
y int pom pom x x y y pom void
main ( ) int a 13 int b 3445 zamien (a,
b) ...
10 Deklaracja funkcji okresla jej naglówek
(nazwe, typ, liczbe i typy argumentów) int
zamien (int x, int y) Definicja funkcji
definiuje tresc funkcji int zamien (int x, int
y) .... Kazda funkcja musi byc
zadeklarowana przed uzyciem. Argumenty domyslne
(tylko C) void f (int i, float x 1.0) //
argumenty domyslne musza
byc na koncu mozliwe wywolania f (2,
3.0) f ( 5) Argument domyslny jest obliczany w
momencie wywolania funkcji. Funkcje wstawiane
(inline) (tylko C) inline int max (int x, int
y) return x gt y ? x y Przeciazanie
funkcji (tylko C) Deklaracja kilku funkcji o
tej samej nazwie, lecz o róznej liczbie
lub róznych typach argumentów. void print (char
s) // bedzie wykonana dla wywolania print
(aaa) void print (int n) // bedzie
wykonana dla wywolania print (10)
11 Typy - c.d. (w C) Struktury i unie struct
para char nazwa int wartosc para p,
kolor k struct entry char nazwa char
typ // n - dla napisu, l - dla liczby union
char wartosc_napis // uzywana, gdy typ
n int wartosc_liczba // uzywana, gdy typ
l entry en ... if (en.typ n) cout ltlt
en.wartosc_napis else cout ltlt en.wartosc.liczba
Tworzenie i niszczenie obiektów char s new
char 10 // napis 9-cio znakowy int wsk
new int wsk new int // wskaznik do nowego
obiektu - liczby delete wsk // zwalnia pamiec
wskazywana przez wsk delete s // zwalnia
10-cio elementowa tablice s
12Wejscie/wyjscie (strumienie) (tylko
C) operatory ltlt gtgt wynikiem zastosowania
tych operatorów jest strumien. standardowe
strumienie cin, cout, cerr cout ltlt Podaj
wartosci dla i oraz j cin gtgt i gtgt j cout ltlt
Suma i oraz j jest ltlt i j ltlt \n Sa tez
funkcje get(c) f.get(c) put (c) f.put (c) eof
() f.eof () cout, cin, f - to sa obiekty klasy
iostream. Klasa fstream obsluguje pliki dyskowe
(jest podklasa klasy iostream). Obiekty klas
ifstream i ofstream sa plikami otwieranymi
domyslnie do czytania i pisania. ifstream input
(dane.txt) // tworzy strumien zwiazany
// z plikiem dane.txt //
otwartym do czytania ofstream output
(wynik.txt) // do pisania
13Struktura programu i widocznosc nazw Program
jest ciagiem deklaracji typów, stalych, zmiennych
i funkcji. Program moze byc wieloplikowy. Plik
pelni role czegos w rodzaju modulu (grupuje
deklaracje typów, zmiennych i funkcji na nich
dzialajacych). Nie ma zagniezdzania
funkcji. Wykonanie programu zaczyna sie od
wykonania funkcji main. Wszystkie typy i funkcje
sa nazwami zewnetrznymi. Nazwy globalne
zadeklarowane na poziomie pliku. Kazda nazwa
globalna jest widoczna od momentu
jej zadeklarowania do konca pliku. Nazwa zmiennej
lokalnej w funkcji jest widoczna od momentu jej
zadeklarowania do konca funkcji. Nazwa zmiennej
lokalnej w bloku jest widoczna od momentu
jej zadeklarowania do konca bloku. Deklaracja
funkcji int f (int x) // tylko naglówek extern
char g ( ) // Definicja funkcji int f (int
x) ...... // tresc funkcji Plik naglówkowy
zawiera deklaracje, które maja byc wspólne
dla wielu plików. include ltfstreamgt //
wlaczenie standardowego pliku naglówkowego includ
e "mojplik.h" // wlaczenie wlasnego pliku
naglówkowego
14Liczymy liczbe wystapien slów kluczowych na
pliku include ltfstreamgt char slowa
begin, end, if, while, record const
n 5 int licznik n char daj_slowo (
ifstream str) // deklaracja funkcji // daje
nastepne slowo ze strumienia NULL - jesli nie ma
juz slowa void wypisz_wynik ( ) // wypisuje
wynik - slowa i liczbe wystapien for ( int i
0 i lt n i) cout ltlt slowa i ltlt \t ltlt
licznik i ltlt \n void policz (char
slowo ) // dla danego slowa zwieksza licznik o 1
jesli jest to sl. kluczowe int i 0 while (
i lt n strcmp (slowo, slowa i ) ! 0)
i if ( i lt n ) licznik i void main
( ) char s fstream str ( ... ) //
.zwiazanie strumienia str z plikiem while ((s
daj_slowo( str )) ! NULL) policz (s
) wypisz_wynik ()
15Liczymy, ile jest róznych slów na pliku. Przez
slowo rozumiemy ciag znaków nie zawierajacych
bialych znaków. W wyniku wypisujemy slowa i
liczbe ich wystapien w kolejnosci alfabetycznej.
Plik o nazwie czyt.h include ltfstreamgt //
funkcja czyta slowo (ciag znaków róznych
"bialych" znaków extern char daj_slowo
(ifstream f)
Plik o nazwie tree.h // typy danych okreslajace
strukture do przechowywania slów include
ltfstreamgt struct wezel char slowo
int ile wezel lewy // wskaznik do
lewego poddrzewa wezel prawy //
wskaznik do prawego poddrzewa typedef wezel
drzewo extern void wstaw(char s, drzewo D)
// wstawia slowo do drzewa extern void
wypisz(drzewo D, ofstream wy) // obchodzi
drzewo
Plik o nazwie slowa.h include ltfstreamgt // ltgt
dla bibliotek standardowych include "tree.h"
// " " dla bibliotek prywatnych extern
void pisz_wyniki( ofstream wynik) //
wypisuje wynik extern void licz (ifstream
dane) // czyta i liczy slowa
16Plik zawierajacy tresc funkcji czytajacej
slowo include ltfstream.hgt include
ltstring.hgt include "czyt.h" static const MAX
50 // maksymalna dlugosc slowa static
char bufMAX // bufor do
przechowywania slowa static inline int BIALE
(char c) return (c ' ' c '\t' c
'\n') // funkcja zwraca wskaznik do
przeczytanego slowa lub NULL, // jesli slowa
juz nie bylo char daj_slowo (istream f)
int i char c char s c
while (!f.get(c).eof() BIALE (c)) //
pomijanie spacji if (BIALE (c) f.eof () )
return(NULL) // nie ma kolejnego
slowa // czytaj slowo do bufora i 0
do buf i c while (
!f.get(c).eof () (! BIALE (c)) (i lt
MAX-1)) // zwracamy przeczytane slowo
bufi '\0' s new char i1 strcpy
(s, buf) return(s)
17Plik zawierajacy operacje na drzewie
BST include ltfstream.hgt include "tree.h" //
funkcja wstawia slowo s do drzewa D, zwieksza
licznik void wstaw(char s, drzewo D) //
parametr przekazany przez ref. int b
if (D NULL) // nie bylo jeszcze tego
slowa D new wezel D -gt slowo s D -gt ile
1 D -gt lewy D -gt prawy NULL
else b strcmp (D -gt slowo, s) if (b
gt 0) // idziemy w lewo wstaw(s, D
-gt lewy) else if (b lt 0) // idziemy w
prawo wstaw(s, D -gt prawy) else (D
-gt ile) return // koniec
funkcji // wypisanie slów z drzewa D na plik wy
void wypisz(drzewo D, ofstream wy) if
(D NULL) return wypisz (D -gt lewy,
wy) wy ltlt D -gt slowo ltlt " " ltlt D -gtile
ltlt "\n" wypisz (D -gt prawy, wy)
18Plik zawierajacy tresci funkcji liczacych liczbe
slów include ltfstreamgt include
"czyt.h" include "tree.h" include
slowa.h static drzewo Slowa NULL
// drzewo slow // funkcja wypisuje
czestosci wystspien slów w porzadku
alfabetycznym // na plik wy void pisz_wyniki(
ofstream wynik) wypisz(Slowa,
wynik) // funkcja liczy czestotliwosc
wystepowania slów na pliku we / void licz
(ifstream dane) char s while ((s
daj_slowo(dane)) ! NULL) wstaw (s, Slowa)
Program glówny include ltfstreamgt include
slowa.h void main ( int argc, char argv
) // utworzenie obiektów dane i wynik ifstream
dane (argv 1) ofstream wynik (argv2)
licz (dane ) pisz_wyniki (wynik)