podstawy projektowania w C++ - wykład, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, informatyka


Podstawy programowania w języku C++.

Różnice pomiędzy jeżykiem programowania Turbo Pascal, a C++ przedstawia tabela:

Turbo Pascal

C++

+, - , *, /

+, - , *, /

mod

/

div

brak

: =

=

=

= =

<>

!=

<, >, <=, >=

<, >, <=, >=

Język C++ jest językiem znormalizowanym według norm ISO z lipca 1998 roku.

0x08 graphic

W schemacie tym preprocesor dołącza do programu niezbędne pliki z biblioteki C++, np.: pliki IOSTREAM, STRING, zawierające funkcje wejścia / wyjścia oraz funkcje na łańcuchach. W programie na początku podaje się dyrektywy dla preprocesora.

Kompilator tłumaczy instrukcje C++ na instrukcje języka wewnętrznego zrozumiałe przez procesor.

Identyfikatorem nazywa się dowolny ciąg liter ( A, a, B, b ), cyfr ( 0 - 9 ) lub podkreśleń, który zaczyna się od litery ( lub podkreślenia ) oraz nie jest słowem kluczowym, które z definicji są zakazane ( end, double, float, if, itp. ). Uwaga: w języku C++ są rozpoznawane małe i duże litery.

Schemat deklaracji zmiennej ma postać:

TypZmiennej Zmienna1, Zmienna2, ... ;

W C++ w porównaniu z Turbo Pascalem rozróżniamy zmienne:

  1. char

  2. int ( odpowiednik Integer w Turbo Pascalu )

  3. float ( Real )

  4. string

Uwaga: deklaracja zmiennej jest instrukcją zakończoną średnikiem i może się znajdować w dowolnym miejscu programu ( niekoniecznie w jego części opisowej ). Zakres działania zadeklarowanej zmiennej jest od miejsca deklaracji do końca danego bloku. W C++ można nadać wartość początkową deklarowanej zmiennej zgodnie ze schematem:

TypZmiennej Zmienna = Wartość Początkowa;

gdzie wartość początkowa może być stałą lub stałym wyrażeniem.

W C++ wyróżniamy dwa rodzaje komentarzy oznaczane /* lub //. Różnicą jest to, że przy komentarzu // koniec wiersza jest zarówno końcem komentarza.

W C++ każda instrukcja nie musi być kończona „;” - zależy to od jej rodzaju.

Instrukcja złożona ( Blok ) jest dowolnym ciągiem instrukcji, które są ujęte w nawiasy klamrowe { }, będące odpowiednikiem BEGIN i END w Turbo Pascalu.

{ Instrukcja 1

:

Instrukcja Ostatnia}

Instrukcja wyjścia ma składnię:

cout << Wyrażenie1 << ... << Wyrażenie ostatnie;

gdzie wyrażenia mogą być w szczególności zmiennymi, bądź stałymi np.:

cout << ”Do widzenia” << endl; cout << ”Jan Kowalski” ;

wyświetlą: Do widzenia

Jan Kowalski

Instrukcja przypisania ma postać:

Zmienna = Wyrażenie;

Przy tej instrukcji musimy pamiętać, że zmienna jak i wyrażenie muszą być tego samego typu, gdyż inaczej następuje konwersja wyrażenia do typu zmiennej i mogą nastąpić błędy.

W związku z tym, że znak = jest znakiem przypisania, więc znakiem równości jest = =. Zaprzeczeniem równości jest znak != .

Definicja funkcji w C++ ma postać:

Nagłówek funkcji

Blok funkcji ( Instrukcja złożona)

Nagłówek funkcji składa się z nazwy funkcji poprzedzonej identyfikatorem typu. Wśród identyfikatorów wyróżnia się identyfikator void - pusty. Funkcje takie nie zwracają wartości i są odpowiednikami procedur w Turbo Pascalu.

Wszystkie inne funkcje są poprzedzone identyfikatorami takimi jak, int, float, char, itd. W funkcjach musi występować instrukcja return Wyrażenie, która przypisuje nazwie funkcji wartość wyrażenia.

Po nazwie funkcji podaje się deklarację parametrów ( formalnych ). Gdy funkcja nie posiada parametrów, po nazwie funkcji występują jedynie dwa nawiasy okrągłe ( ).

Program w C++ jest funkcją o nazwie main typu int, przy czym typ int można opuszczać i pisać funkcję bez parametrów, która zazwyczaj zwraca wartość 0 do systemu operacyjnego. Zatem przy końcu jej umieszczamy instrukcję return 0;. Instrukcja ta powoduje wyjście sterowania z funkcji.

Każdy program jest poprzedzony zazwyczaj co najmniej jedną dyrektywą kompilatora oraz dyrektywą using namespace std;

Ex. 1.

Napisać program wyświetlający wizytówkę na ekranie.

#include <iostream>

using namespace std;

int main()

{

cout<<"**************************"<<endl

<<"*******Jan Kowalski********"<<endl

<<"**************************";

return 0;

}

W języku prestandardowym dwie pierwsze linie można zastąpić wyrażeniem

#include <iostream.h>.

Deklaracje funkcji definiowanych w programie ( tzn. skrócone nagłówki funkcji ) podajemy po dyrektywach programu, zaś ich definicję podaje się na końcu programu.

Ex. 2.

Napisz program składający się z trzech funkcji, wyświetlający kwadrat i sześcian podanej liczby.

#include <iostream>

using namespace std;

int Kwadrat(int); // skrócony nagłówek funkcji

int Szescian(int);

int main()

{

int x;

cout<<"X="; cin>>x; endl;

cout<<"Kwadrat liczby "<<x<<" wynosi "<<Kwadrat(x)

<<", a jej szescian wynosi "<<Szescian(x)<<endl;

return 0;

}

int Kwadrat(int x)

{ return x*x; }

int Szescian(int x)

{ return Kwadrat(x)*x; }

W C++ w odróżnieniu od Turbo Pascala nie można definiować funkcji wewnątrz innych funkcji. W związku z tym po dyrektywach preprocesora podajemy tyle nagłówków funkcji ile zamierzamy ich zdefiniować.

Zasięgiem każdej funkcji jest blok programu. W związku z tym funkcje mogą wywoływać inne funkcje zadeklarowane wcześniej.

Ogólny schemat instrukcji wejścia jest następujący:

cin >> Zmienna1 >> ... >> Zmienna ostatnia

Działanie tej instrukcji sprowadza się do wprowadzenia z klawiatury jednej danej i przypisania jej zmiennej jeden, wprowadzeniu drugiej i przypisaniu jej zmiennej 2, itd.

W C++ są dwa typy instrukcji warunkowych:

if ( Wyrażenie Logiczne )

Instrukcja 1

else

Instrukcja 2

lub

if ( Wyrażenie Logiczne )

Instrukcja 1

Działanie pierwszej instrukcji sprowadza się do:

  1. obliczenia wartości wyrażenia logicznego w nawiasach po słowie kluczowym IF

  2. wykonania Instrukcji 1, jeżeli obliczoną wartością jest TRUE lub Instrukcji 2 jeśli jest nią FALSE

  3. przejścia do następnej instrukcji po instrukcji warunkowej

Opis działania drugiej instrukcji jest identyczny, jeśli przyjmiemy, że Instrukcja 2 jest instrukcją pustą.

Ex. 3.

Napisać funkcję obliczającą tygodniowe wynagrodzenie znając przepracowaną liczbę

Godzin, stawkę za godzinę oraz wiedząc, że godziny nadliczbowe są o 50 % lepiej płatne od obowiązkowych 40 h / tydzień.

float Wynagrodzenie ( float stawka, float liczba_godzin )

{

if ( liczba_godzin <= 40 )

return stawka * liczba_godzin ;

else

return (40.0 + ( liczba_godzin - 40.0 ) * 1.5 ) * stawka;

}


Tak jak w Turbo Pascalu, tak i w C++ do organizacji pętli można wykorzystać instrukcję WHILE mającą postać:

while ( Wyrażenie Logiczne )

Instrukcja

Pętla ta wykonuje instrukcje dopóki wartość wyrażenia logicznego jest TRUE. Jeśli jest nią FALSE, to sterowanie zostaje przekazane do następnej instrukcji po WHILE. Schemat działania tej instrukcji jest następujacy:

0x08 graphic

F

T

Do często używanego rodzaju pętli zalicza się pętle ze zmienną sterującą ( z licznikiem ) postaci:

k = wp;

while ( k <= wk )

{

Instrukcja 1

:

Instrukcja Ostatnia

k = k + 1;

}

Ostatnia instrukcja przypisania jest równoważna instrukcji k++, więc korzystając z tego faktu zdefiniowano w C++ pętlę FOR o identycznym działaniu do podanej pętli WHILE:

for ( k = wp; k<= wk; k++ )

{

Instrukcja 1

:

Instrukcja Ostatnia

}

Tą pętlę często zapisujemy też w postaci:

for ( int k = wp; k<= wk; k++ )

{ Instrukcja 1

:

Instrukcja Ostatnia }

Ex. 4.

Napisz instrukcję wyświetlającą liczby od 1 do n

cin >> n ;

for ( k=1; k<=n; k++ )

cout<<k<<endl;

Wyświetlenie w odwrotnej kolejności można zrealizować pętlą:\

cin >> n ;

for ( k=n; k>=1; k++ )

cout<<k<<endl;

Instrukcja WHILE może w szczególnym przypadku nie mieć żadnego cyklu, dlatego często wygodniejsza jest instrukcja:

do

Instrukcja

while ( Wyrażenie Logiczna );

Działanie tej instrukcji jest następujące:

0x08 graphic

F

T

Z instrukcjami pętli związane są zmienne typu tablicowego definiowane następująco:

TypDanych NazwaWektora [ cons int ]

gdzie TypDanych jest typem współrzędnych wektora np.: int

Ta deklaracja definiuje wektor o wpółrzędnych:

NazwaWektora [0], NazwaWektora [1], ... , NazwaWektora [cons int - 1]

Do tych współrzędnych można w programie się odwoływać pisząc:

NazwaWektora [indeks]

gdzie indeks ∈ { 0, 1, ..., cons int - 1 }


Ex. 5.

Napisać program zapisujący do wektora dane[0..999] 1000 wpisywanych z klawiatury liczb, a następnie wyświetla je w odwrotnej kolejności.

#include <iostream>

using namespace std;

int main()

{

int Wektor[1000];

for (int k=0; k<=999; k++)

cin>>Wektor[k];

for (k=999; k>=0; k--)

cout<<Wektor[k]<<endl;

return 0;

}

W instrukcjach WHILE, DO WHILE I FOR można używać instrukcji BREAK i CONTINUE, które bezwarunkowo przekazują kierowanie do:

  1. następnej instrukcji po bieżącej pętli

  2. do końca bieżącego cyklu pętli

Ex. 6.

Napisz pętlę wyświetlającą i przetwarzającą jedynie dodatnie liczby z wypisywanego z klawiatury ciągu 500 liczb.

for ( k = 1; k<=500 ; k++)

0x08 graphic
0x08 graphic
{

cin>>liczba;

0x08 graphic
0x08 graphic
if ( liczba <= 0 ) continue; // break ;

else

cout<<liczba<<endl;

0x08 graphic
}

Wyrażenia logiczne i priorytety.

Do budowy wyrażeń arytmetycznych i logicznych oprócz stałych, zmiennych i wywołań funkcji używa się operatorów arytmetycznych i logicznych, które są wymienione poniżej z uwzględnieniem ich priorytetów.

Operatory o niższym priorytecie wykonywane są najpierw ( od 1 w górę ), przy czym kolejność wykonywania się operatorów może ulec zmianie poprzez użycie nawiasów.

Operator

Odpowiednik w TP

Przykład zastosowania

++ ; --

k++ ; k--

! ; - ; +

NOT ; - ; + (jednoargumentowe)

!p ; -k ; +k

* ; / ; %

* ; / lub DIV ; MOD

5/2 = 2 ; 5%2=5

+ ; -

+ ; - ( dwuargumentowe )

a+b ; a-b

<< ; >>

cin>>n ; cout<<”Text”

<; <=; >; >=

2<3 ; 5>=2

= = ; !=

= ; <>

n= =2

&&

AND

p && q

||

OR

p || q

=

: =

A=2

Funkcje w języku C++.

Funkcje w C++ definiuje się następująco:

Nagłówek funkcji

Blok funkcji

gdzie Nagłówek funkcji ma postać

Typ wyniku funkcji Nazwa funkcji ( Lista deklaracji parametrów formalnych )

zaś Blok funkcji jest instrukcją złożoną.

Definicję funkcji będziemy podawali po bloku programu głównego. W tym przypadku pomiędzy dyrektywami kompilatora i programem głównym podaje się skrócony nagłówek funkcji, w którym opuszczone są nazwy parametrów formalnych występujących w liście deklaracji parametrów formalnych.

Typ wyniku funkcji piszemy przed nazwą funkcji w nagłówku. Typ wyniku może być słowem kluczowym void ( czyli typem pustym ) lub dowolnym innym typem różnym od typu tablicowego.

Funkcje poprzedzone słowem void są odpowiednikami procedur w Turbo Pascalu, tzn. nie zwracają one żadnej wartości pod swoją nazwą.

W programie funkcje wywołuje się pisząc:

Nazwa funkcji ( Lista argumentów funkcji )

Jeżeli funkcja nie jest typu void, to zwraca ona wartość pod swoją nazwą, która jest tego samego typu co typ wyniku funkcji. W związku z tym w bloku funkcji musi pojawić się instrukcja: return wyrażenie; , która ma następujące działanie:

  1. poleca obliczyć wartość wyrażenia napisanego po słowie return

  2. przypisuje obliczoną wartość nazwie funkcji ( musi ona być tego samego typu co typ wyniku funkcji, gdyż w przeciwnym wypadku następuje konwersja do typu wyniku )

  3. przekazuje sterowanie z funkcji do programu ( do następnej instrukcji po instrukcji wywołania funkcji )

W funkcjach nie zwracających wartości nie wolno używać podanej instrukcji return, lecz można używać skoku bezwarunkowego postaci return; który nakazuje sterowaniu opuścić funkcję i przejść do programu.

Nazwą funkcji podawaną po typie wyniku funkcji może być dowolny ciąg liter, cyfr i podkreśleń zaczynający się od litery.

Lista deklaracji parametrów formalnych podawana w nawiasach może być listą pustą. Jeżeli nie jest ona listą pustą, to zgodnie z nazwą zawiera ona dowolną liczbę deklaracji parametrów ( zmiennych ) oddzielonych od siebie przecinkami. Po każdym typie zmiennych możemy napisać znak &. Jest to deklaracja zmiennej przez referencję:

Typ zmiennej& Nazwa zmiennej;

Specyfikowanie parametru przez referencję oznacza, że odpowiadający mu parametr aktualny jest przekazywany do funkcji jako adres zmiennej, np.: jeżeli taki parametr jest tablicą składającą się z 20.000 bytów to podczas wywołania do funkcji przekazuje się jedynie adres tej tablicy, będący liczbą całkowitą.

Parametry deklarowane bez & są specyfikowane przez wartość. W tym przypadku podczas wywołania tworzona jest kopia parametru aktualnego specyfikowanego przez wartość, na której wykonuje się obliczenia.

Parametry specyfikowane przez referencję zachowują się tak jak parametry specyfikowane przez zmienną w Turbo Pascalu ( z VAR ), tzn. mogą one być zarówno wynikami, jak i danymi funkcji.

W bloku funkcji można deklarować zmienne ( zmienne lokalne ). Tych zmiennych można używać jedynie w bloku funkcji, ale nie poza nią. Nazwy parametrów formalnych funkcji nie mogą się pokrywać z nazwami zmiennych lokalnych tej funkcji.

Funkcje zwracające wartość, tzn. nie poprzedzone słowem void wywołuje się jedynie w wyrażeniach, gdyż takie wywołanie jest liczbą, łańcuchem, rekordem a nie instrukcją. Zauważmy, że wywołanie funkcji zwracającej lub nie zwracającej wartości powoduje:

  1. przekazanie sterowania do funkcji o podanej nazwie zdefiniowanej po programie

  2. przesłanie do parametrów formalnych wartości lub adresów odpowiednich argumentów z listy argumentów zaczynając od lewego ( obliczając wartości argumentów, gdy są one wyrażeniami )

  3. wykonanie wszystkich instrukcji podanych w bloku funkcji

  4. przekazanie sterowania do następnej instrukcji po instrukcji wywołania funkcji

Argumentów musi być tyle samo co parametrów formalnych funkcji.

Typ wektorowy deklaruje się w programie pisząc:

typedef typ elementów tablicy nazwa tablicy [liczba wierszy][liczba kolumn]

gdzie typedef jest słowem kluczowym.

Po zdefiniowaniu typu macierzowego parametry funkcji tego typu deklarujemy w nagłówku podając nazwę typu i nazwę zmiennej np.: Tmacierz a;

Jeżeli nie chcemy deklarować typu, to parametry typu tablicowego deklaruje się zgodnie ze schematem:

Typ składników Nazwa macierzy [liczba wierszy][liczba kolumn]

Ex. 1.

Napisać funkcję kopiującą dane z tablicy jednowymiarowej o nazwie Źródło do tablicy o nazwie Kopia, przy czym obowiązuje założenie, że n jest mniejsze od rozmiaru obu tablic. Słowo const przed deklaracją parametru tablicowego oznacza, że próba przypisania elementom tej tablicy ich wartości zakończ się błędem kompilatora. Pomimo, że przy deklaracji zmiennych typu tablicowego nie piszemy znaku &, to parametry tego typu są zawsze specyfikowane przez referencję w języku C++.

void Copy ( const int Źródło[], int Kopia[], int n )

{

for ( int i = 0 , i < n, i++ )

Kopia[i] = Źródło[i];

}

Ex. 2.

Napisać program z funkcją rekurencyjną wyświetlającą łańcuch zakończony znakiem '\n'( równoznacznym z Enter) w odwrotnej kolejności.

#include<iostream.h>

#include<conio.h>

void inwersja( );

void main( )

{ inwersja( );

cout<<endl;

getch( );

}

void inwersja( )

{ char ch;

cin.get(ch); // wczytuje pojedynczy znak, nie pomijając znaków niewidocznych

if (ch!='\n')

{ inwersja( );

cout<<ch;

}

}

Ex. 3.

Napisać funkcję, która oblicza numer dnia w roku określonego przez datę w formacie dd-mm-rrrr ( np.:08-02-2002 to wartość funkcji powinna być równa 30+1+8=39 ) ze wzoru Dzień = (miesiąc - 1)*30 + poprawka + dzień miesiąca. ( poprawka ++, gdy rok przestępny ).

Miesiąc

I

II

III

IV

V

VI

VII

VIII

IX

X

XI

XII

Poprawka

0

1

-1

0

0

1

1

2

3

3

4

4

int Dzień ( int miesiąc, int dzień miesiąca, int rok )

{ int poprawka=0;

if ( miesiąc = = 3 )

poprawka = poprawka-1;

else if ( miesiąc = = 2 || miesiąc = = 6 || miesiąc = = 7 )

poprawka = poprawka + 1;

else if ( miesiąc = = 8 )

poprawka = poprawka + 2;

else if ( miesiąc = = 9 || miesiąc = = 10 )

poprawka = poprawka + 3;

else if ( miesiąc = = 11 || miesiąc = = 12 )

poprawka = poprawka + 4 ;

if ( rok%4 = = 0 && ( rok%100 != 0 || rok%400 = = 0))

if ( miesiąc >=3 )

poprawka + +;

return ( miesiąc - 1 )*30 + poprawka + dzień miesiąca;

}

Powyższa wielokrotnie zagnieżdżona instrukcja if może być zapisana przy pomocy instrukcji switch, która działa tak samo jak instrukcja CASE w Turbo Pascalu z jedną różnicą: po wybraniu jednej z wielu instrukcji i jej wykonaniu nie następuje automatyczny skok do końca instrukcji switch, tylko wykonuje się następna instrukcja wyboru. Automatyczny skok uzyskuje się dzięki instrukcji break. Etykiety wyboru w instrukcji switch mają postać:

case stałe: lub default

Instrukcja poprzedzona słowem default wykonuje się jeżeli wartość selektora jest różna od każdej stałej wyboru. Składnia instrukcji switch jest następująca:

switch ( selektor )

{

1 - sza Etykieta wyboru: 1 - sza Instrukcja;

:

Ostatnia Etykieta wyboru: Ostatnia Instrukcja

}

switch (miesiąc )

{case 3: poprawka--; break;

case 2,6,7: poprawka++; break;

case 8 : poprawka = poprawka + 2 ; break;

case 9,10: poprawka = poprawka + 3 ; break;

case 11,12: poprawka = poprawka + 4; }

Pliki wejścia, wyjścia ( I/O ).

Pliki są strukturami danych, z których można odczytywać poszczególne składniki i do których można zapisywać składniki. Każdy odczyt i zapis przesuwa wskaźnik pliku za odczytany ( zapisany ) element. Innymi słowy poniżej będziemy mogli jedynie odczytywać element za elementem, zaczynając od pierwszego elementu i zapisywać elementy na końcu pliku.

Wprowadzanie danych do programu z pliku lub wyprowadzanie danych do innego pliku jest korzystniejsze od wprowadzania danych z klawiatury i wyprowadzania wyników na ekran monitora. Jeżeli program korzysta z dużej ilości danych, to łatwiej wprowadzić te dane do pliku przy pomocy dowolnego edytora w celu ich późniejszego użycia w programie, niż wprowadzać je w czasie działania programu. Wprowadzone dane do pliku mogą być później poprawiane, modyfikowane, rozszerzane i używane przez program wielokrotnie, bez potrzeby ich ponownego pisania. Ponieważ pliki są przechowywane w pamięciach zewnętrznych (dyski, dyskietki ) więc dane nie muszą być napisane od razu lub w czasie 1 sesji przy komputerze. Wyniki zapamiętane w plikach mogą być:

  1. wyświetlane na ekranie lub wydrukowane

  2. przeglądane i analizowane wielokrotnie bez potrzeby ponownego uruchamiania programu

  3. wykorzystane jako dane przez inny program

Aby wykorzystać w programie pliki I/O należy wykonać następujące czynności ( zakładamy, że plik fizyczny jest na twardym dysku ):

  1. umieścić w programie dyrektywę dołączającą plik fstream ( #include<fstream> ), plik ten zawiera dwa typy kluczowe o nazwach ifstream i ofstream służące do odczyty i zapisu plików

  2. zadeklarować w programie zmienne plikowe typów ifstream i ofstream w ten sam sposób jak deklaruje się inne zmienne np.: ifstream DaneWe; ofstream DaneWy; które deklarują zmienne plikowe o nazwach DaneWe i DaneWy

  3. otworzyć pliki przy pomocy następujących wywołań funkcji open:

DaneWe.open ( ”dane.dat” );

DaneWy.open ( ”wynik.dat” );

,gdzie łańcuchy „dane.dat” i „wynik.dat” są plikami fizycznymi na dysku, zaś DaneWe i DaneWy są zmiennymi plikowymi zadeklarowanymi w punkcie 2. Po otwarciu plik Dane We jest skojarzony z plikiem dane.dat i jest gotowy do odczytu, przy czym może być odczytane pierwszy składnik pliku. Analogicznie po otwarciu plik DaneWy jest pusty i gotowy do zapisu.

  1. Korzystać z poznanych operacji wejścia np.: operatora >>, funkcji get i ignore oraz operacji wyjścia ( operatora <<, endl, setw, setprecision ). Obowiązuje przy tym jedno zastrzeżenie: należy zastąpić strumienie cin i cout odpowiednio przez DaneWe i DaneWy.

Szkic ilustrujący używanie plików I/O.

0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
cin cout

W programach użytecznych w praktyce należy testować, czy plik został otwarty. Jeżeli nie, należy wyświetlić odpowiedni komunikat. Zamykanie plików w języku C++ odbywa się automatycznie.

Do otwierania plików może posłużyć nam funkcja pytająca o podanie nazwy pliku fizycznego z klawiatury. Po każdym wywołaniu funkcji należy badać stan pliku będącego argumentem wywoływanej funkcji przy pomocy instrukcji if (!Nazwa Argumentu ) return 1;

void Otwórz Plik ( ifstream& PlikWe )

{ string Nazwa Pliku Fizycznego;

cout<< ”Podaj nazwę pliku dyskowego: ”;

cin>> Nazwa Pliku Fizycznego;

PlikWe.open( Nazwa Pliku Fizycznego . c_str( )); // c_str - zamienia łańcuch klasy

string na c - łańcuch

if (!PlikWe)

cout<< ”Nie można otworzyć pliku ”<< Nazwa Pliku Fizycznego<< endl; }

Ex.1

Napisać program pobierający daty zapisane w pliku w formacie mm/dd/rrrr i zapisujący je do pliku wyjściowego zgodnie z następującym schematem:

American Format (mm/dd/rrr) British Format (dd/mm/rrrr) ISO Format (rrrr/mm/dd).

Jeżeli data jest podana w postaci 1 / 9/199 9 to w pliku danych wyjściowych powinna ona być zapisana np.:01/09/1999.

#include<iostream>

#include<iomanip> //dla setw( ) - ustala szerokość

#include<fstream> //dla plików I/O

#include<string>

using namespace std;

void CzytajDwieCyfry(ifstream&, string&); // czyta dwie lub jedna cyfrę z pliku

//wejściowego, stopując czytanie na znaku'/' i zapisuje wynik pod zmienna

//typu string. Pojedyncza cyfra w łańcuch jest poprzedzana '0'.

void CzytajRok(ifstream&, string&); // czyta 4 cyfry roku i zapisuje je w łańcuchu

void OtworzPlikWe(ifstream&); //funkcja prosi o nazwę pliku fizycznego //i podejmuje próbę jego otwarcia

void OtworzPlikWy(ofstream&); //funkcja podejmuje próbę otwarcia pliku

//wyjściowego o nazwie podanej z klawiatury

void Zapisz(ofstream&, string, string, string); //funkcja zapisuje łańcuchy

//oznaczające odpowiednio miesiąc, dzień i rok we wszystkich formatach

void main()

{

string miesiac, dzien, rok;

ifstream DaneWe;

ofstream DaneWy;

OtworzPlikWe(DaneWe);

OtworzPlikWy(DaneWy);

DaneWy<<setw(20)<<"American Format"

<<setw(20)<<"British Format"

<<setw(20)<<"ISO Format"<<endl<<endl;

while (DaneWe)

{ CzytajDwieCyfry(DaneWe, dzien);

CzytajDwieCyfry(DaneWe, miesiac);

CzytajRok(DaneWe, rok);

Zapisz(DaneWy, miesiac, dzien, rok); }

}

// definicje zadeklarowanych funkcji.

void OtworzPlikWe ( ifstream& PlikWe)

{ string NazwaPlikuFiz;

cout<<"Podaj nazwe pliku fizycznego: ";

cin>>NazwaPlikuFiz;

PlikWe.open(NazwaPlikuFiz.c_str());

if (!PlikWe) cout<<"Nie mozna otworzyc pliku "<<NazwaPlikuFiz<<endl;

}

void OtworzPlikWy (ofstream& PlikWy)

{ string NazwaPlikuFiz;

cout<<"Podaj nazwe pliku wyjsciowego: ";

cin>>NazwaPlikuFiz;

PlikWy.open(NazwaPlikuFiz.c_str());

if (!PlikWy) cout<<"Nie mozna otworzyc pliku "<<NazwaPlikuFiz<<endl;

}

void CzytajDwieCyfry(ifstream& DaneWe, string& DwaZnaki)

{ char cyfra1,cyfra2,zn;

DaneWe>>cyfra1;

if (!DaneWe) return;

DaneWe>>cyfra2;

if (cyfra2= ='/')

{ cyfra2=cyfra1;

cyfra1='0';}

else DaneWe>>zn;

DwaZnaki=cyfra1;

DwaZnaki=DwaZnaki+cyfra2;

}

void CzytajRok(ifstream& DaneWe, string& Znaki)

{ char cyfra1,cyfra2,cyfra3,cyfra4,zn;

DaneWe>>cyfra1;

if (!DaneWe) return;

DaneWe>>cyfra2;

DaneWe>>cyfra3;

DaneWe>>cyfra4;

Znaki=cyfra1;

Znaki=Znaki+cyfra2;

Znaki=Znaki+cyfra3;

Znaki=Znaki+cyfra4;

}

void Zapisz(ofstream& DaneWy, string miesiac, string dzien, string rok)

{

DaneWy<<'\t'<<miesiac<<"/"<<dzien<<"/"<<rok<<'\t'<<'\t'

<<dzien<<"/"<<miesiac<<"/"<<rok<<'\t'<<'\t'

<<rok<<"/"<<miesiac<<"/"<<dzien<<endl;

}

Podstawowe typy w C++.

Typy w C++ dzielą się na proste, adresowe i strukturalne. Pierwsze z nich dzielą się na 4 grupy: typów całkowitych, całkowitych nieujemnych, wyliczeniowych i rzeczywistych, które łącznie zawierają 13 typów:

  1. typy całkowite: int, char, short, long, bool

  2. typy całkowite nieujemne (bezznakowe): unsigned int, unsigned char, unsigned short, unsigned long

  3. typy rzeczywiste: float, double, long double

  4. typy wyliczeniowe ( enum )

Rozważmy typ wyliczeniowy TDni zdefiniowany przez:

enum Tdni { nd, pn, wt, śr, cz, pt, so };

Zgodnie z definicją typu wyliczeniowego nazwą stałych nd, pn, ..., so zostały przypisane liczby całkowite 0, 1, ..., 6. Zatem ten typ jest typem porządkowym, gdyż nd < pn < ...

Jeżeli teraz zadeklarujemy zmienną TDni Dzień; to w petlach przebiegających przez wszystkie dni tygodnia używamy schematu:

for ( Dzień = nd; Dzień <= so; Dzień = TDni ( Dzień + 1 ) ) // nie wolno Dzień++

{

:

}

Kolejnym przykładem typu wyliczeniowego jest program kliniki weterynaryjnej rejestrujący i wypisujący pacjentów:

enum TZwierz { Gad, Gryzoń, Koń, Kot, Krowa, Owca, Pies, Ptak }

Wartości zmiennych tego typu są łańcuchami postaci Gad, Gryzoń, ... Nie wymagamy tu aby te łańcuchy były pisane z dużej litery. Program ma wyświetlić wartości tych zmiennych pisane małymi literami. Najwygodniej zrealizować to przy pomocy 2 funkcji:

TZwierz StrToAnimal ( string str )

{

switch ( toupper (str[0]) ) // użycie toupper wymaga pliku cctype

{ case `G': if (str[1] = ='a') return Gad;

else return Gryzoń;

case `K': if (str[1] = ='r') return Krowa;

else if (str[2] = ='ń') return Koń;

else return Kot;

case `O': return Owca;

case `P' : if (str[1] = ='i') return Pies;

else return Ptak;

}}

Następna funkcja zamienia zmienną typu TZwierz do odpowiedniego łańcucha pisanego małą literą i wyświetla go

void AnimalToStr ( TZwierz pacjent )

{

switch (pacjent)

{

case Gad: cout<<”gad”; break;

case Gryzoń: cout<<”gryzoń”; break;

:

:

}

}

Następną klasą typów są typy strukturalne, do których zaliczamy:

  1. typ tablicowy o identyfikatorze array

  2. typ rekordowy o identyfikatorze struct

  3. typ rekordowy z wariantami o identyfikatorze union

  4. typ klasowy o identyfikatorze class

Typ string jest szczególnym przykładem typu klasowego.

Omówimy typ rekordowy, który służy do przechowywania składników niekoniecznie tego samego typu, zwanych polami. W C++ często używa się terminologii struktura zamiast rekord oraz składnik zamiast pole.

Deklaracja typu rekordowego ma postać:

struct Nazwa Typu

{

Lista Deklaracji Składników

};

gdzie „ ; ” wliczany do deklaracji oznacza jej koniec, zaś Lista Deklaracji Składników składa się z dowolnej liczby deklaracji o postaci

Nazwa Typu Nazwa Składnika ;

Dostęp do składników rekordów jest możliwy przy pomocy selektorów składników o składni:

Nazwa Struktury . Nazwa Składnika

gdzie zmienna Nazwa Struktury powinna być zadeklarowana wcześniej w postaci:

Nazwa Typu Struktury Nazwa Struktury ;

Rozważmy typ rekordowy, który oprócz składników będących nazwiskami i imionami studentów zawiera średnią ocen za określony semestr studiów, 2 oceny za pracę magisterską, egzamin magisterski oraz ocenę końcową będącą średnią ważoną poprzednich ocen.

struct TStudent

{

string nazwisko, imię;

float średnia, rozprawa1, rozprawa2, egzamin;

int ocena_końcowa;

};

// Deklaracja zmiennej rekordowej

TStudent student;

Podajemy poniżej instrukcję wczytującą dane do rekordu student i podającą ocenę końcową przy użyciu funkcji

:

cin>> student.nazwisko>>student.imię>>...;

student.ocena_końcowa = ocena (student);

:

int ocena ( TStudent stu )

{

float sw;

sw = 0,5* stu.średnia + 0,25* stu.egzamin + 0,125* (stu.rozprawa1 + stu.rozprawa2);

if (stu.rozprawa1= =2,0 || stu.rozprawa2 = =2,0 || stu.egzamin = = 2,0 || sw<3,0 )

return 2;

else return int(sw); // zaokrąglenie

}

Pomimo tego, że w C++ jest możliwe deklarowanie zmiennych z jednoczesną deklaracją typów zgodnie ze schematem poniżej, to taki sposób deklaracji zmiennych nie jest zalecany

struct Nazwa Typu

{

Lista Deklaracji Składników

};

Lista Deklaracji Zmiennych;

Składnikami struktur mogą być inne struktury:

struct TData

{

int dzień, miesiąc, rok;

};

struct Tauto

{

int nr_silnika;

string model;

TData data_produkcji, data_sprzedaży;

float cena;

};

Przykładowymi selektorami składników dla zmiennej zadeklarowanej jako TAuto są auto.data_sprzedaży.rok, auto.data_produkcji.miesiąc, auto.cena, itd.

Rekordy z wariantami deklaruje się tak jak typ rekordowy bez wariantów pisząc union zamiast struct. W takim przypadku zmienna typu rekordowego z wariantami ( union ) służy do przechowywania tylko jednego pola, tzn. przypisanie jednemu polu określonej wartości kasuje inne pola np.:

union TWaga

{

long waga_w_gramach;

int waga_w_kilogramach;

float waga_w_tonach;

};

TWaga waga;

Dla zmiennej waga przypisanie wartości jednemu z trzech pól np.: waga.waga_w_kilogramach = 120 niszczy rezerwację pozostałych dwóch pól.


Klasy w C++.

Typ rekordowy jest pasywny, gdyż nie zawiera żadnych zdefiniowanych przez programistę operacji do przekształcania pól rekordów, które stanowiłyby jego integralną część. Typem aktywnym, którego składowe mogą być nie tylko prostymi lub strukturalnymi danymi, ale też funkcjami, konstrukcjami oraz destrukcjami zwanymi metodami jest typ klasowy. Oprogramowanie wykorzystujące klasy i obiekty nosi nazwę klienta klasy.

Schemat definicji typu klasowego jest podobny do definicji typu rekordowego i ma wygląd:

class Nazwa Typu Klasowego (Klasy)

{

public:

1-sza Lista deklaracji składników klasy

private:

2-ga Lista deklaracji składników klasy

};

Kolejność części oznaczonych słowami public i private jest dowolna. Dalej będziemy zakładali, że pierwsza jest część public, a druga private.

Listy deklaracji składników klasy są albo deklaracjami zmiennych (pól) albo deklaracjami metod.

Składniki klasy zadeklarowane między słowami kluczowymi public i private, czyli w liście pierwszej są dostępne dla klientów bezpośrednio, zaś te zadeklarowane po słowie private są niedostępne dla klientów. Dokładniej, jeżeli z zewnątrz klasy zostanie podjęta próba dostępu do składnika po słowie private, to kompilator zasygnalizuje błąd. Dostęp do składników po słowie private jest zastrzeżony dla metod danej klasy.

Zmienne typów klasowych (obiekty) definiuje się tak samo jak zmienne innych typów zgodnie ze schematem:

Nazwa typu klasowego Nazwa zmiennej klasowej (obiektu) ;

W jednej instrukcji możemy deklarować więcej niż 1 obiekt. Do obiektów klasowych odwołujemy się przy pomocy selektorów składników postaci:

Nazwa obiektu . Nazwa składnika klasy

gdzie Nazwa składnika klasy może być nazwą pola lub metody, np.: plik standardowy iostream zawiera definicję 2 typów klasowych: istream oraz ostream oraz obiektów cin oraz cout. Typ istream zawiera wiele metod np.: cin.get(ch) oraz cin.ignore(100, `\n');

Plik fstream zawiera deklarację 2 typów klasowych o identyfikatorach ifstream i ofstream. Następujące 2 instrukcje ifstream PlikWe i PlikWe.open(”dane.dat”) deklarujące obiekt PliikWe typu ifstream, a następnie wywołujące funkcję open będącą składnikiem klasy ifstream.

Określmy formalnie typ klasowy jako:

class Tczas

{

public:

void Ustaw( int, int, int );

void Zwiększ ( );

void Drukuj ( ) const;

bool Równy ( TCzas ) const;

bool MniejszyOd ( TCzas ) const;

private:

int godz, min, sek;

}

Słowo const po skróconym nagłówku oznacza, że deklarowana metoda nie ma prawa modyfikować pól w części prywatnej. Jeżeli podejmie taką próbę to wystąpi błąd kompilatora

Obiekt klasowy zadeklarowany jako TCzas Czas1 można zilustrować jako:

0x08 graphic

0x08 graphic

Ustaw

0x08 graphic

Zwiększ

0x08 graphic

Drukuj

0x08 graphic

Równy

0x08 graphic
MniejszyOd

0x08 graphic
0x08 graphic
0x08 graphic

0x08 graphic
Godz.

0x08 graphic
Min.

Sek.

Obiekty klasowe nie zawierają kodów metod, jedynie ich adresy, zatem rozmiar obiektu Czas1 jest równy ilości bajtów zajętych przez 5 zmiennych typu unsigned long oraz 3 zmienne typu int.

Obiekty mogą być:

    1. parametrami, argumentami i wartościami funkcji

    2. argumentami operatora selekcji składników, tzn. generatora „.

    3. przypisywane innym obiektom tego samego typu

Tak jak i inne zmienne obiekty mogą być automatyczne, tzn. tworzone za każdym razem, gdy sterowanie je deklaruje i niszczone gdy sterowanie opuszcza blok sterowania. Obiekty mogą być też statyczne, tzn. tworzone przy wykonywaniu się instrukcji ich deklaracji oraz niszczone w chwili kończenia pracy przez program.

21

15

22

7

Adres kodu

Adres kodu

Adres kodu

Adres kodu

Adres kodu

DaneWy

DaneWe

Pamięć operacyjna

Monitor

Klawiatura

Pliki fizyczne

Wyrażenie logiczne

Następna instrukcja

Instrukcja

Skok tutaj

Skok tutaj

Następna instrukcja

Instrukcja

Wyrażenie logiczne

Program wynikowy

Kompilator

Program rozumowany

Preprocesor

Program



Wyszukiwarka

Podobne podstrony:
Systemy operacyjne - wykłady, Administracja, Administracja, Administracja i samorząd, Polityka spole
Wykladp, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, informatyka
projektowanie systemów informacyjnych (6 str), Administracja, Administracja, Administracja i samorzą
projektowanie systemów informacyjnych-ściąga, Administracja, Administracja, Administracja i samorząd
projektowanie systemów (17 str), Administracja, Administracja, Administracja i samorząd, Polityka sp
projekt sieci komputerowej (9 str), Administracja, Administracja, Administracja i samorząd, Polityka
wprowadzenie do sztucznej inteligencji-wyk łady (10 str), Administracja, Administracja, Administracj
Forma wykorzystywanej informacji zewnetrznej, Administracja, Administracja, Administracja i samorząd
programowanie liniowe-ćwiczenia, Administracja, Administracja, Administracja i samorząd, Polityka sp
sciaga z C, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, informatyka
informatyka - ściąga1, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, i
Egzamin z informatyki, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, i
Sciaga z Sieci Komputerowych, Administracja, Administracja, Administracja i samorząd, Polityka spole
baza danych sciaga, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, info
Informatyka-zagadnienia, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna,
Telepraca1, Administracja, Administracja, Administracja i samorząd, Polityka spoleczna, Ochrona srod

więcej podobnych podstron