Instrukcja jest współfinansowana przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
w projekcie:
"Innowacyjna dydaktyka bez ograniczeń
- zintegrowany rozwój Politechniki Łódzkiej zarządzanie Uczelnią,
nowoczesna oferta edukacyjna
i wzmacniania zdolności do zatrudniania,
także osób niepełnosprawnych".
Ewa
Dyka
Marek
Mończyk
Instrukcja do laboratorium
Podstawy informatyki
Podstawy informatyki
3
1.
Wstęp. ................................................................................................................................ 4
2.
Programowanie w trybie tekstowym. .................................................................................. 4
2.1.
Zasięg zmiennych, przesłanianie zmiennych. .............................................................. 4
2.2.
Zmienne globalne, lokalne automatyczne, lokalne statyczne........................................ 5
2.3.
Niejawna konwersja typów. ........................................................................................ 6
2.4.
Tablice wprowadzanie i odczytywanie elementów. ..................................................... 7
2.5.
Wykorzystanie pętli for do wylistowania elementów tablicy. ...................................... 8
2.6.
Struktury. .................................................................................................................... 8
2.7.
Inkrementacja.............................................................................................................. 9
2.8.
Prosty kalkulator - instrukcja sterująca Switch. ......................................................... 10
2.9.
If i While - sprawdzenie parzystości liczby................................................................ 11
2.10.
While - wyznaczanie silni wykorzystanie zmiennej lokalnej i globalnej................. 12
2.11.
Funkcja. ................................................................................................................ 12
2.12.
Funkcja w pliku zewnętrznym. .............................................................................. 13
2.13.
Wskaźniki. ............................................................................................................ 14
2.14.
Tablice znakowe, deklaracja tablic. ....................................................................... 15
2.15.
Tablice znakowe, pobieranie z klawiatury, rozpoznawanie liter............................. 16
2.16.
Tablice znakowe, wyszukiwanie fragmentów tekstu, praca ze wskaźnikiem do
tablicy znakowej. .................................................................................................. 16
2.17.
Klasy..................................................................................................................... 18
2.17.1.
Klasy, przykładowa klasa. ................................................................................. 18
2.17.2.
Klasy, konstruktor i destruktor........................................................................... 19
2.17.3.
Klasy, stopnie ochrony. ..................................................................................... 20
2.17.4.
Klasy, stopień ochrony protected. ...................................................................... 21
2.17.5.
Klasy, klasy pochodne (dziedziczenie). ............................................................. 22
2.17.6.
Klasy, metody wirtualne. ................................................................................... 24
2.18.
Zapis do pliku. ...................................................................................................... 25
2.19.
Odczyt tekstu z pliku. ............................................................................................ 27
3.
Programowanie w Windows ............................................................................................. 28
3.1.
Prosta animacja – uciekający klawisz. ....................................................................... 28
3.2.
Rzutowanie typów – jedna funkcja do obsługi wielu zdarzeń. ................................... 29
3.3.
Rzutowanie typów – wykorzystanie zmiennej lokalnej statycznej.............................. 31
3.4.
Prosta animacja – wykorzystanie przerwania zegarowego, przekazywanie parametrów
do metody poprzez referencje.................................................................................... 32
3.5.
Gra „Refleks” – wykorzystanie funkcji losowej random(). ........................................ 34
3.6.
Wykorzystanie funkcji z biblioteki DLL dołączanej dynamicznie.............................. 38
3.7.
Wykorzystanie funkcji z biblioteki DLL dołączanej statycznie.................................. 40
3.8.
Propozycje zajęć powtórkowych. .............................................................................. 40
3.8.1.
Rozwiązanie równania kwadratowego. .............................................................. 40
3.8.2.
Gra zręcznościowa – auta. ................................................................................. 43
3.8.3.
Gra w odbijanie piłki o ścianę............................................................................ 46
3.8.4.
Gra logiczna – patyczki. .................................................................................... 50
3.8.5.
Gra – strzelanie do celu. .................................................................................... 53
4.
Literatura:......................................................................................................................... 56
Podstawy informatyki
4
Elementy programowania w C++
1. Wstęp.
Prezentowany skrypt jest uzupełnieniem wykładu z przedmiotu "Podstawy informatyki"
dla studiów niestacjonarnych I-go stopnia kierunku "Energetyka". Skrypt nie omawia teorii
języka C++ a jedynie zawiera szereg przykładów, które mogą zostać wykorzystane na zajęciach
laboratoryjnych. Student przed zapoznaniem się z materiałami zawartymi w tym skrypcie
powinien zatem uzupełnić wiadomości teoretyczne dotyczące programowania i składni języka
C++.
2. Programowanie w trybie tekstowym.
2.1. Zasięg zmiennych, przesłanianie zmiennych.
W omawianym przykładzie dzięki odpowiedniemu ustawieniu bloków funkcyjnych {}
możemy zaobserwować zależności pomiędzy zmiennymi lokalnymi i globalnymi, ocenić ich
zasięg oraz zapoznać się ze zjawiskiem przesłaniania zmiennych.
Kod programu:
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
int k = 0;
int main()
{
// blok main
clrscr();
cout << "Przeslanianie zmiennych";
cout << "\n\nlokalizacja: blok main\nwartosc k: " << k;
{
// blok 1
int k = 1;
cout << "\n\nlokalizacja: blok #1\nwartosc k: " << k;
{
// blok 2
int k = 2;
cout << "\n\nlokalizacja: blok #2\nwartosc k: " << k;
// koniec bloku 2
}
cout << "\n\nlokalizacja: znowu blok #1\nwartosc k: " << k;
cout << "\n\nlokalizacja: blok #1 (ale po odslonieciu)\nwartosc k: " << ::k;
//koniec bloku 1
Podstawy informatyki
5
}
getch();
return 0;
// koniec bloku main
}
Po wykonaniu programu na ekranie zobaczymy:
*** Przeslanianie zmiennych ***
lokalizacja: blok main
wartosc k: 0
lokalizacja: blok #1
wartosc k: 1
lokalizacja: blok #2
wartosc k: 2
lokalizacja: znowu blok #1
wartosc k: 1
lokalizacja: blok #1 (ale po odsłonięciu)
wartosc k: 0
2.2. Zmienne globalne, lokalne automatyczne, lokalne statyczne.
Kod programu:
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
int zm_globalna;
int main(int argc, char **argv)
{
clrscr();
cout << "Inicjalizacja zmiennych";
cout << "\nzmienna globalna: " << zm_globalna;
{
int zm_lokalna_aut;
cout << "\nzmienna lokalna automatyczna: " << zm_lokalna_aut;
}
{
static int zm_lokalna_sta;
Podstawy informatyki
6
cout << "\nzmienna lokalna statyczna: " << zm_lokalna_sta;
}
getch();
return 0;
}
Po wykonaniu programu na ekranie zobaczymy:
Inicjalizacja zmiennych
zmienna globalna: 0
zmienna lokalna automatyczna: 9642460
zmienna lokalna statyczna: 0
Można zauważyć, że zmienna globalna oraz lokalna statyczna są zerowane po ich
utworzeniu natomiast zmienna lokalna automatyczna inicjowana przez funkcje w obszarze stosu
(przestaje istnieć po zakończeniu działania funkcji) posiada wartość przypadkową. W związku
z tym zaleca się podstawienie wartości początkowej do zmiennej w momencie jej deklaracji lub
tuż po. W przypadku zadeklarowania zmiennych w pliku nagłówkowym, bądź w obiekcie
dobrze jest podstawić wartości do zmiennych wykorzystując np. konstruktor obiektu lub inną
automatycznie wywoływaną funkcje (np. main w przypadku programowania proceduralnego).
2.3. Niejawna konwersja typów.
Kod programu:
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
void main()
{
cout << 3/2;
cout << "\n" << 3.0/2;
getch();
}
Po wykonaniu programu otrzymamy dwa wyniki dzielenia 1 i 1.5, w przypadku pierwszym
ponieważ w sposób jawny nie zadeklarowaliśmy typu zmiennych kompilator uznał, że dzielimy
liczby całkowite stąd też nastąpiła konwersja wyniku do liczby całkowitej. W drugim przypadku
wynikiem dzielenia jest liczba rzeczywista, co jest zgodne z typem dzielnej.
Podstawy informatyki
7
2.4. Tablice wprowadzanie i odczytywanie elementów.
Kod programu:
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
int t[4] = {0, 1, 2, 3};
int dd[2][3] = {{1, 2, 3}, {4, 5, 6}};
int id1, id2;
int main(int argc, char **argv)
{
clrscr();
cout << "Pokaz wartosc elementu tablicy t (0-3) nr: ";
cin >> id1;
cout << "\nt[" << id1 << "] = " << t[id1];
cout << "\n\nPokaz wartosc elementu tablicy dd (0-1,0-2), gdzie\nnr kolumny: ";
cin >> id1;
cout << "\nnr wiersza: ";
cin >> id2;
cout << "\n\ndd[" << id1 << "][" << id2 << "] = " << dd[id1][id2];
getch();
return 0;
}
Rys. 1: Przykładowy wynik na ekranie.
Korzystając z tablic w języku C należy pamiętać o tym, że:
elementy tablicy indeksowane są od zera,
wpisanie do tablicy o danej nazwie elementu o indeksie z poza zakresu nie powoduje
błędu w programie może natomiast spowodować uszkodzenie bloku pamięci
zajmowanego przez inne fragmenty kodu programu,
Podstawy informatyki
8
poprzez nazwę tablicy mamy dostęp do elementu tablicy o indeksie zerowym.
2.5. Wykorzystanie pętli for do wylistowania elementów tablicy.
Kod programu:
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
#pragma argsused
void main()
{
int i;
int tab[5] = {5,4,3,2,1};
for (i=0; i<sizeof(tab)/sizeof(tab[0]); i++) cout << "tab[" << i << "] = " << tab[i] <<"\n";
int s=0;
getch();
}
Na ekranie zobaczymy:
tab[0] = 5
tab[1] = 4
tab[2] = 3
tab[3] = 2
tab[4] = 1
Wyrażenie sizeof(tab)/sizeof(tab[0]) pozwala na ustalenie liczby elementów tablicy
poprzez podzielenie całkowitej wielkości tablicy przez wielkość pojedynczego jej elementu.
2.6. Struktury.
Struktura w przeciwieństwie do tablicy pozwala na przechowywanie zmiennych różnych
typów w jednym bloku. Dostęp do pól struktury uzyskujemy w taki sam sposób jak do pól
obiektów podając nazwę zmiennej reprezentującej strukturę oraz nazwę pola rozdzielone kropką.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
Podstawy informatyki
9
#pragma argsused
struct miasto
{
char kraj[60];
long ludnosc;
};
struct miasto lodz = {"Polska", 800000};
void main()
{
clrscr();
cout << "Dane dla miasta Lodz:";
cout << "\n\nLodz dane: ";
cout << "\n\nkraj: " << lodz.kraj;
cout << "\n\nludnosc: " << lodz.ludnosc;
getch();
}
Na ekranie zobaczymy:
Dane dla miasta Lodz:
Lodz dane:
kraj: Polska
ludnosc: 800000
2.7. Inkrementacja.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
int i =0;
void main()
{
cout << i++ <<", ";
cout << i <<", ";
cout << (i += 1) <<", ";
cout << (i -= 1) <<", ";
cout << (++i) <<", ";
cout << i;
Podstawy informatyki
10
getch();
}
Na ekranie zobaczymy:
0, 1, 2, 1, 2, 2
Można zauważyć, że chwila zwiększenia wartości indeksu zależy od położenia znaków ++
w stosunku do zmiennej indeksowanej. Mówimy o postinkrementacji, w której najpierw zostanie
wykonana instrukcja przy wykorzystaniu aktualnej wartości indeksu a potem jego zwiększenie
lub preinkrementacji, w przypadku której najpierw zostanie zwiększona wartość indeksu
a następnie wykonana instrukcja go zawierająca.
2.8. Prosty kalkulator - instrukcja sterująca Switch.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
void main()
{
char str;
float x, y;
cout << "wprowadz dwie liczby i znak operacji +,-,*,/ \n";
cin >> x >> y >> str;
switch (str)
{
case '+':
cout << (x+y);
break;
case '-':
cout << (x-y);
break;
case '*':
cout << (x*y);
break;
case '/':
cout << (x/y);
break;
default:
cout << " Nieprawidlowe dzialanie ";
}
cout << endl << "Nacisnij klawisz...";
getch();
}
Podstawy informatyki
11
Na ekranie zobaczymy:
wprowadz dwie liczby i znak operacji +,-,*,/
234
345
/
0.678261
Nacisnij klawisz...
Należy pamiętać, że parametrem instrukcji switch może być dowolna zmienna
reprezentowana przez liczbę całkowitą np.: integer, char, enum.
2.9. If i While - sprawdzenie parzystości liczby.
W języku C przyjmuje się, że każda wartość liczby z wyjątkiem 0 w warunku instrukcji
logicznej if odpowiada prawdzie. Ta właściwość języka wykorzystana została w przykładzie do
stwierdzenia, czy liczba od której wielokrotnie odejmowano liczbę 2 (do momentu w którym
wynik nie był większy od jedności) jest liczbą parzystą czy też nie.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
void main()
{
int liczba, druga;
cout << "wprowadz liczbe \n";
cin >> liczba;
druga = liczba;
while (druga>1) druga = druga-2;
{
if (druga) cout << "liczba1 " <<liczba << " jest nieparzysta";
else cout << "liczba2 " <<liczba << " jest parzysta";
}
getch();
}
Na ekranie zobaczymy:
wprowadz liczbe
377
liczba1 377 jest nieparzysta
Podstawy informatyki
12
2.10. While - wyznaczanie silni wykorzystanie zmiennej lokalnej
i globalnej.
W przykładzie tym należy zwrócić uwagę na wykorzystanie zmiennej globalnej i lokalnej
przesłaniającej w bloku funkcyjnym zmienną globalną. Zmienna lokalna „licz” przechowuje
w bloku funkcyjnym wartość chwilową silni w pętli while i jednocześnie po odsłonięciu wartości
zmiennej globalnej o tej samej nazwie wykorzystana zostaje w instrukcji warunkowej
przerywającej pętle.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
long int licz;
void main()
{
int i = 1;
cout <<"Program oblicza silnie liczby. Wprowadz liczbe > 1: ";
cin >> licz;
{
long int licz = 1;
while (i<=::licz) licz = licz * i, i++;
cout <<"\nSilnia liczby " <<::licz <<" wynosi: " <<licz;
}
getch();
}
Na ekranie zobaczymy:
Program oblicza silnie liczby. Wprowadz liczbe > 1: 14
Silnia liczby 14 wynosi: 1278945280
2.11. Funkcja.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
int pole_kw(int bok);
void main()
Podstawy informatyki
13
{
int bok;
cout <<"Podaj dlugosc boku kwadratu: ";
cin >> bok;
cout <<"\nPole kwadratu o boku " << bok << " wynosi: " <<pole_kw(bok);
getch();
}
int pole_kw(int bok)
{
return bok *= bok;
}
Po wykonaniu na ekranie zobaczymy:
Podaj dlugosc boku kwadratu:
Pole kwadratu o boku 23 wynosi: 529
2.12. Funkcja w pliku zewnętrznym.
W przykładzie tym funkcja t() zdefiniowana jest poza plikiem głównym programu
i dołączona za pomocą deklaracji zawartej w pliku nagłówkowym, jest to prosty przykład
programu składającego się z wielu plików bibliotecznych. W takim przypadku biblioteka zostaje
dołączona do programu wykonywalnego na etapie kompilacji i nie jest potem potrzebna jako
samodzielny plik.
Biblioteka zawierająca definicje funkcji (Unit2.cpp):
#pragma hdrstop
#include "Unit2.h"
#pragma package(smart_init)
void t(int tabl[], int elementy)
{
int i;
for(i=0; i<elementy; i++) tabl[i]+=10;
}
Plik nagłówkowy biblioteki zawierający deklaracje funkcji (Unit2.h):
#ifndef Unit2H
#define Unit2H
void t(int tabl[], int elementy);
#endif
Plik programu zawiera instrukcje #include dołączającą plik nagłówkowy Unit2.h z
deklaracją funkcji t() oraz jej wywołanie.
Podstawy informatyki
14
Kod programu:
#include <condefs.h>
#include <conio.h>
#include <iostream.h>
#include "Unit2.h"
int main()
{
int i;
int tablica[3]={1,2,3};
for(i=0; i<3; i++) cout << tablica[i] <<" ";
cout << endl;
t(tablica, 3);
for(i=0; i<3; i++) cout << tablica[i] <<" ";
getchar();
}
2.13. Wskaźniki.
W przykładzie tym możemy zobaczyć w jaki sposób można zadeklarować zmienną
wskaźnikową oraz w jaki sposób można przypisać jej wartość. Widać, że do zmiennej intiger x
można odwołać się bezpośrednio poprzez jej nazwę lub poprzez jej adres przypisany do
zmiennej wskaźnikowej *w. Inaczej mówiąc zmienna x oraz wskaźnik *w są tożsame ponieważ
odnoszą się do tego samego obszaru pamięci. Stosowanie zmiennych wskaźnikowych jest
szczególnie przydatne w przypadku operowania dużymi strukturami danych (tablice, struktury,
funkcje). Operując wskaźnikiem nie ma konieczności kopiowania całej struktury danych
w przypadku np. przekazania jej do funkcji, wystarczy jedynie przekazać poprzez wskaźnik jej
adres początkowy. Zmienne wskaźnikowe są bardzo ważnym elementem języka C i będą
wielokrotnie pojawiały się w kolejnych przykładach.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
void main()
{
int *w;
int x;
cout <<"wpisz wartosc zmiennej x:";
cin >>x;
cout <<"\t\t x =" << x;
w=&x;
cout <<"\n a dla w=&x \t*w =" <<*w;
Podstawy informatyki
15
*w=15;
cout <<"\n a dla *w=15 \t*w =" <<*w;
x=25;
cout <<"\n a dla x=25 \t*w =" <<*w;
getch();
}
Wynik wykonania:
wpisz wartosc zmiennej x: 7
x =7
a dla w=&x
*w =7
a dla *w=15
*w =15
a dla x=25
*w =25
2.14. Tablice znakowe, deklaracja tablic.
Kolejne przykłady pokazują w jaki sposób należy korzystać z tablic znakowych. Należy
pamiętać, że tablica znakowa, która ma spełniać rolę łańcucha tekstowego musi mieć dodatkowo
jedno miejsce na znak NULL przyjmowany w języku C jako znak końca łańcucha tekstowego.
Brak znaku NULL na końcu tablicy znakowej może powodować błędne działanie funkcji
bibliotecznych operujących na łańcuchach (string).
Kod programu:
#include<iostream.h>
#include<conio.h>
#pragma hdrstop
void main()
{
char *string = "Politechnika";
printf("char *string = \"Politechnika\" - string ma %d znakow\n", strlen(string));
char zdanie[20]= "Politechnika";
printf("char zdanie[20]= \"Politechnika\" - zdanie ma %d znakow i rozmiar %d \n",
strlen(zdanie), sizeof(zdanie));
char slowo[]="Politechnika";
printf("char slowo[]= \"Politechnika\" - slowo ma %d znakow i rozmiar %d \n",
strlen(slowo), sizeof(slowo));
getch();
}
W wyniku działania programu na ekranie zobaczymy:
char *string = "Politechnika" - string ma 12 znakow
char zdanie[20]= "Politechnika" - zdanie ma 12 znakow i rozmiar 20
Podstawy informatyki
16
char slowo[]= "Politechnika" - slowo ma 12 znakow i rozmiar 13
2.15. Tablice znakowe, pobieranie z klawiatury, rozpoznawanie liter.
Kod programu:
#include<iostream.h>
#include<conio.h>
#pragma hdrstop
void main()
{
int i,y;
char x;
char znaki[20];
cout << "Program sprawdzi czy wpisany ciag znakow to litery" << endl;
cout << "Wpisz ciag znakow: ";
gets(znaki);
y = strlen(znaki);
for (i=0;i<y;i++)
{
if (!isalpha(znaki[i]))break;
}
f ((i)==y)
{
cout << "Wszystkie to litery";
}
else
{
cout << "Na " << i+1 << " pozycji nie ma litery";
}
getch();
}
W wyniku działania programu na ekranie zobaczymy:
Program sprawdzi czy wpisany ciag znakow to litery
Wekjiusejd3ioskd
Wpisz ciag znakow: Na 11 pozycji nie ma litery
2.16. Tablice znakowe, wyszukiwanie fragmentów tekstu, praca ze
wskaźnikiem do tablicy znakowej.
Kod programu:
#include <conio.h>
Podstawy informatyki
17
#include <iostream.h>
#include <string.h>
void main()
{
char string1[] = "Ala, Magda, Adam, Alfons, Jasiek, Alfons, As";
char *pointer;
clrscr();
cout << "Lista:\n" << string1;
pointer = strstr(string1, "Alfons");
cout << "\nTekst 'Alfons' wystapil po raz pierwszy:\n";
cout << " " << pointer << '\n';
pointer = strstr(pointer, "Jasiek");
cout << "Tekst 'Jasiek' wystapil po raz pierwszy:\n";
cout << " " << pointer << '\n';
pointer = strstr(pointer, "As");
cout << "Tekst 'As' wystapil:\n";
cout << " " << pointer << '\n' << "\n\nNacisnij cokolwiek";
getch();
}
Po wykonaniu na ekranie zobaczymy:
Lista:
Ala, Magda, Adam, Alfons, Jasiek, Alfons, As
Tekst 'Alfons' wystapil po raz pierwszy:
Alfons, Jasiek, Alfons, As
Tekst 'Jasiek' wystapil po raz pierwszy:
Jasiek, Alfons, As
Tekst 'As' wystapil:
As
Nacisnij cokolwiek
Funkcja strstr() przestawia wskaźnik pointer na pierwszy znak znalezionego tekstu, przez
co każde następne przeszukiwanie tablicy znakowej w przykładzie rozpoczyna się od miejsca
zakończenia poszukiwań. Należy zwrócić uwagę na to, że w przypadku nie znalezienia tekstu
pointer przyjmuje wartość NULL (oznaczający koniec tablicy znakowej) i dalsze poszukiwania
przestają mieć sens.
Podstawy informatyki
18
2.17. Klasy.
2.17.1. Klasy, przykładowa klasa.
Definicja klasy, żeby była dostępna w całym projekcie, który składa się z kilku plików
powinna się znajdować w którymś z plików nagłówkowych. Dobrze też jest definicje metod
danej klasy umieszczać w osobnym pliku.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
// Deklaracja klasy TypKlasa
class TypKlasa
{
public:
int pole_int;
double pole_double;
void MetodaKlasy();
};
// Definicja metody MetodaKlasy() klasy TypKlasa
void NAZWA::MetodaKlasy()
{
pole_double+=pole_int;
}
// Wykorzystanie klasy
void main()
{
// Utworzenie obiektu NowyObiekt klasy TypKlasa
TypKlasa NowyObiekt;
// Zainicjowanie wartości pól obiektu
NowyObiekt.pole_int=3;
NowyObiekt.pole_double=3.13;
// Wywołanie metody obiektu
NowyObiekt.MetodaKlasy();
cout<< NowyObiekt.pole_double;
getch();
}
Podstawy informatyki
19
2.17.2. Klasy, konstruktor i destruktor.
Konstruktor klasy to specjalna metoda która jest wywoływana zawsze gdy klasa jest
inicjowana. Można to wykorzystać do przydzielenia polom wartości początkowych.
Konstruktor i destruktor nie zwracają żadnej wartości. Nazwa konstruktora jest dokładnie
taka sama jak nazwa klasy
Destruktor jest wywoływany gdy klasa nie będzie więcej używana. Nazwa destruktora jest
taka sama jak nazwa klasy ale poprzedzona znakiem tyldy (~).
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
class KLASA
{
public:
int x;
KLASA(); //konstruktor
~KLASA(); //destruktor
};
// Konstruktor i destruktor
KLASA::KLASA()
{
x=10;
}
KLASA::~KLASA()
{
x=1;
}
void funkcja()
{
KLASA klasa;
cout<<klasa.x;
}
void main()
{
KLASA klasa;
funkcja();
cout<<klasa.x;
getch();
}
Podstawy informatyki
20
2.17.3. Klasy, stopnie ochrony.
Są trzy stopnie ochrony tworzące sekcje klasy:
public,
protected,
private.
Najbardziej rygorystyczną ochronę daje sekcja private. Można do danych i metod
chronionych tym stopniem odwoływać się tylko poprzez inne metody tej klasy, w której te dane
zostały zdefiniowane. Nie mogą z tych danych korzystać klasy pochodne W stopniu ochrony
protected, klasy pochodne mogą już korzystać z pól i metod klasy bazowej. Stopień ochrony
public w ogóle nie ogranicza dostępu do danych.
W przykładowym programie nie jest dozwolony dostęp do pola X oraz metody odczytajx(),
ze względu na umieszczenie ich w sekcji klasy o typie ochrony private. Można uzyskać do nich
dostęp poprzez metody odczytaj_x() oraz zapisz(int), które zostały umieszczone w sekcji o typie
publicznym czyli ogólnie dostępnym. Należy pamiętać, że jeśli nie zadeklarujemy w deklaracji
klasy żadnego stopnia ochrony, to wszystkie pola i metody w klasie będą miały nadany
domyślnie typ ochrony private.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
class X
{
public:
int odczytaj_x();
void zapisz_x(int wej);
private:
int X;
int odczytajx();
};
int X::odczytajx()
{
return X;
}
int X::odczytaj_x()
{
return odczytajx();
}
void X::zapisz_x(int wej)
Podstawy informatyki
21
{
X=wej;
}
void main()
{
X obiekt;
obiekt.X=15;
//błąd brak dostępu
obiekt.zapisz_x(15);
//poprawnie mamy dostęp
cout<<obiekt.odczytajx();
//błąd brak dostępu
cout<<obiekt.odczytaj_x(); //poprawnie mamy dostęp
getch();
}
2.17.4. Klasy, stopień ochrony protected.
W tym przykładzie można zauważyć, że do pól i metod klasy X umieszczonych w sekcji
protected można się dostać poprzez utworzenie klasy Y, dla której klasą bazową jest klasa X.
Klasa Y ma zadeklarowane metody publiczne pozwalające na dostęp do sekcji protected klasy
X. Próba bezpośredniego odczytania wartości pola X lub wywołania metody odczytajx() z klasy
X kończy się błędem, i dlatego dla poprawnego działania programu wiersze z tymi poleceniami
powinny zostać „zakomentowane”.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
class X
{
protected:
int X;
int odczytajx();
};
class Y: public X
{
public:
void ZapiszDoX(int);
int PokazX();
int PokazX_bezp();
};
Podstawy informatyki
22
int X::odczytajx()
{
return X;
};
int Y::PokazX_bezp()
{
return X;
};
void Y::ZapiszDoX(int y)
{
X=y;
}
int Y::PokazX()
{
return odczytajx();
}
void main()
{
X klasax;
Y klasay;
klasay.ZapiszDoX(5);
//poprawnie
cout<<klasay.PokazX();
//poprawnie
cout<<klasay.PokazX_bezp();
//poprawnie
cout<<klasax.odczytajx();
//błąd brak dostępu
cout<<klasax.X;
//błąd brak dostępu
getch();
}
2.17.5. Klasy, klasy pochodne (dziedziczenie).
W przykładzie na bazie klasy FIGURA konstruujemy klasy, które będą obliczały pola
figury geometrycznych koła, prostokąta i kwadratu. Klasy pochodne będą miały pole klasy
bazowej, oraz pola i metodę. Potrzebne do obliczeń dla wybranej figury geometrycznej. Klasy
można dziedziczyć wielokrotnie. Tzn., klasa pochodna może być klasą bazową dla innej klasy.
Każda klasa bazowa musi być zdefiniowana przed definicją klasy pochodnej. Klasę bazową
można deklarować jako publiczną, chronioną lub prywatną. Pola i metody dostępne w klasie
bazowej będą miały taki sam stopień ochrony w klasie pochodnej.
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
Podstawy informatyki
23
class FIGURA // klasa bazowa
{
public:
double pole;
};
class KOLO: public FIGURA
{
public:
double promien;
void pole_powierzchni();
};
class TROJKAT: public FIGURA
{
public:
double a,h;
void pole_powierzchni();
};
class KWADRAT: public FIGURA
{
public:
double a;
void pole_powierzchni();
};
// Metody klas pochodnych.
void KOLO::pole_powierzchni()
{
pole=3.1415*promien*promien;
}
void TROJKAT::pole_powierzchni()
{
pole=0.5*a*h;
}
void KWADRAT::pole_powierzchni()
{
pole=a*a;
}
void main()
{
KWADRAT kwadrat;
TROJKAT trojkat;
KOLO kolo;
kwadrat.a=2.0;
trojkat.a=4.0;
trojkat.h=2.0;
Podstawy informatyki
24
kolo.promien=4.0;
kolo.pole_powierzchni();
kwadrat.pole_powierzchni();
trojkat.pole_powierzchni();
cout <<"Pole powierzchni kola: "<<kolo.pole<<endl;
cout <<"Pole powierzchni kwadratu: "<<kwadrat.pole<<endl;
cout <<"Pole powierzchni trójkąta: "<<trojkat.pole<<endl;
getch();
}
Na ekranie zobaczymy:
Pole powierzchni kola: 50.264
Pole powierzchni kwadratu: 4
Pole powierzchni trojkata: 4
2.17.6. Klasy, metody wirtualne.
Jako funkcje wirtualne można deklarować tylko metody klas. Taka deklaracja zawsze
poprzedzona jest słowem virtual. W przykładzie definiujmy klasę FIGURA, ale zamiast pola
pole_powierzchni definiujmy metodę która będzie je liczyła. Metoda pole() będzie występowała
we wszystkich klasach pochodnych, ale dla każdej z nich zostanie oddzielnie zdefiniowana.
To oznacza, że metody liczące pole figury będą wykorzystywać wzory odpowiadające
poszczególnym figurą. W klasie bazowej widzimy, że do metoda pole() jest przyrównana do
zera. Jest to sygnał dla kompilatora, że metoda dla klasy bazowej nie będzie definiowana.
Oznacza to, iż metody o tej nazwie zostaną zdefiniowane i użyte w klasach pochodnych. Metody
wirtualne dla poszczególnych klas definiuje się tak samo jak zwykłe metody, natomiast w
wywołaniu funkcji jako parametr podaje się nazwę obiektu. W prezentowanym przykładzie
obiekt musi należeć do którejś klasy pochodnej klasy FIGURA wtedy program sam wybierze
sobie odpowiednią metodę pole().
Kod programu:
#pragma hdrstop
#include <condefs.h>
#include <iostream.h>
#include <conio.h>
#pragma argsused
class FIGURA
{
public:
virtual double pole()=0;
};
class KWADRAT: public FIGURA
{
public:
int bok;
Podstawy informatyki
25
virtual double pole();
};
class KOLO: public FIGURA
{
public:
int promien;
virtual double pole();
};
//Definicje metody pole w klasach pochodnych.
double KWADRAT::pole()
{
return bok*bok;
}
double KOLO::pole()
{
return 3.1415*promien*promien;
}
// Definicja funkcji
double pole(FIGURA& figura)
{
return figura.pole();
}
void main()
{
KOLO kolo;
KWADRAT kwadrat;
kolo.promien=2;
kwadrat.bok=2;
cout<<"Pole kola o promieniu " << kolo.promien <<" wynosi: " << pole(kolo);
cout<<endl;
cout<<"Pole kwadratu o boku " << kwadrat.bok <<" wynosi: " << pole(kwadrat);
getch();
}
Na ekranie zobaczymy:
Pole kola o promieniu 2 wynosi: 12.566
Pole kwadratu o boku 2 wynosi: 4
2.18. Zapis do pliku.
Skrócony opis programu znajduje się w komentarzach dołączonych do programu. Tworząc
wskaźnik do pliku należy pamiętać o ustaleniu sposobu dostępu do niego (zapis, odczyt itp.).
Podstawy informatyki
26
Plik programu:
#include<iostream.h>
#include<conio.h>
#pragma hdrstop
int main()
{
char tekst[100];
float x;
FILE *plik;
// otwarcie pliku
plik = fopen("dane.txt","w");
// zapis tekstu do pliku z mozliwoscia formatowania
fprintf(plik,"Tekst: ");
cout << "Podaj tekst, ktory zostanie wpisany do pliku:" << endl;
// wpisanie tekstu
gets(tekst);
// zapis tekstu do pliku
fputs(tekst,plik);
cout << "Podaj liczbe, ktora zostanie wpisana do pliku:" << endl;
cin >> x;
fprintf(plik,"\nWprowadzona liczba: %1.2f",x);
// zamkniecie pliku
fclose(plik);
getche();
}
Rys. 2: Widok okna programu.
Podstawy informatyki
27
2.19. Odczyt tekstu z pliku.
W prezentowanym przykładzie plik tekstowy zostaje odczytany znak po znaku przy
wykorzystaniu instrukcji pętli while. Pętla pobiera znak z pliku i sprawdza czy nie jest to znak
końca pliku EOF, jeśli nie jest wypisuje znak na standardowym wyjściu w tym przypadku na
ekranie.
Plik programu:
#include<iostream.h>
#include<conio.h>
#pragma hdrstop
int main()
{
char znak;
FILE *plik;
plik = fopen("dane.txt","r");
while ((znak = getc(plik)) != EOF) cout << znak;
fclose(plik);
getche();
}
Rys. 3: Widok danych wczytanych z pliku.
Podstawy informatyki
28
3. Programowanie w Windows
3.1. Prosta animacja – uciekający klawisz.
Przykład pokazuje jak zmieniając parametry opisujące położenie obiektu w oknie
graficznym programu można uzyskać efekt ruchu. Korzystamy tu ze zdarzenia MouseMove,
które zachodzi w momencie przemieszczenia się kursora myszy nad obiektem. Jeżeli obiekt
posiada zdefiniowaną metodę obsługującą to zdarzenie to możliwe będzie wykonanie w tej
metodzie operacji pozwalającej na przesunięcie obiektu.
W przykładzie tym w zależności od położenia myszy nad obiektem wykonywany jest ruch
w prawą (+) lub lewą stronę (-). Należy pamiętać, że w oknie graficznym oś 0Y jest skierowana
do dołu.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y);
private:
// User declarations
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Kod programu:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
Podstawy informatyki
29
void __fastcall TForm1::Button1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
// Wyświetlenie informacji o położeniu klawisza na belce tytułowej okna
Caption=X;
if (abs(Button1->Width/2-X)>2)
{
if ((X)>(Button1->Width-X))
{
Button1->Left+=2;
}
else
{
Button1->Left-=2;
}
}
}
Rys. 4: Widok okna programu.
3.2. Rzutowanie typów – jedna funkcja do obsługi wielu zdarzeń.
W przykładzie posłużymy się klasą TControl będącą klasą bazową dla wszystkich
komponentów mających reprezentacje wizualną w uruchomionym programie. Parametr Sender,
który jest rzutowany na zmienną wskaźnikową x wskazującą klasę TControl, zawiera informacje
o adresie obiektu odpowiedzialnego za wywołanie zdarzenia (w przykładzie są to trzy klawisze
zmieniające sposób wyrównywania tekstu w okienku Memo). Dzięki temu funkcja zachowuje
się inaczej dla każdego wywołującego ją elementu dostarczanego w parametrze Sender
(wyrównuje do lewej, prawej lub centruje tekst w oknie). Program wykorzystuje także
komponent ImageList pozwalający na przechowywanie elementów graficznych wyświetlanych
na przyciskach komponentu ToolBar stanowiącego element wykonawczy programu.
Plik nagłówkowy:
#ifndef U1H
#define U1H
#include <Classes.hpp>
#include <Controls.hpp>
Podstawy informatyki
30
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ToolWin.hpp>
#include <ImgList.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
TToolBar *ToolBar1;
TToolButton *ToolButton1;
TToolButton *ToolButton2;
TToolButton *ToolButton3;
TImageList *ImageList1;
void __fastcall ToolButton1Click(TObject *Sender);
private:
// User declarations
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Rys. 5: Komponenty wykorzystane w programie.
Kod programu:
#include "U1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
Podstawy informatyki
31
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::ToolButton1Click(TObject *Sender)
{
TControl *x = (TControl*)(Sender);
Memo1->Alignment = (TAlignment)x->Tag;
}
3.3. Rzutowanie typów – wykorzystanie zmiennej lokalnej statycznej.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TButton *Button3;
TButton *Button4;
TButton *Button5;
TButton *Button6;
TButton *Button7;
TButton *Button8;
TButton *Button9;
void __fastcall Button1Click(TObject *Sender);
private:
// User declarations
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Kod programu:
#include <vcl.h>
#pragma hdrstop
Podstawy informatyki
32
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
static int i;
TButton *x = (TButton*)(Sender);
if (i % 2) x->Caption='x' ;
else x->Caption='o';
x->Enabled=false;
i++;
}
Rys. 6: Widok okna programu.
3.4. Prosta animacja – wykorzystanie przerwania zegarowego,
przekazywanie parametrów do metody poprzez referencje.
W programie piłka pokazana na ekranie porusza się od dołu do góry ekranu. Do animacji
piłki wykorzystane zostało przerwanie zegarowe związane z obiektem Timer1.
Plik nagłówkowy biblioteki:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
Podstawy informatyki
33
class TForm1 : public TForm
{
__published: // IDE-managed Components
TTimer *Timer1;
TShape *s;
void __fastcall Timer1Timer(TObject *Sender);
private:
// User declarations
public:
// User declarations
void __fastcall Zmiana(int *Y);
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Plik
nagłówkowy
zawiera
metodę
publiczną
Zmiana
z
jednym
parametrem
przekazywanym przez referencje (wskaźnik do liczby całkowitej). Jako referencja przekazywany
jest do metody adres pola Top animowanego kształtu.
Rys. 7: Komponenty wykorzystane w programie.
Plik biblioteki:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
void __fastcall TForm1::Zmiana(int *Y)
{
*Y=*Y-1;
}
Podstawy informatyki
34
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Zmiana(&(s->Top));
// s->Top=s->Top-1; możliwe jest bezpośrednie modyfikowanie położenia kształtu „s”.
Caption=IntToStr(s->Top);
Repaint();
}
3.5. Gra „Refleks” – wykorzystanie funkcji losowej random().
Proponowana gra polega na sprawdzeniu refleksu gracza. W trakcie gry na ekranie
w stałych odstępach czasu w losowej kolejności pojawiają się obiekty, które trzeba „kliknąć”
myszką w określonym czasie. Liczba szans jest ograniczona. Wynikiem gry jest procentowa
liczba trafień wyświetlana na pasku tytułowym okna.
Rys. 8: Komponenty wykorzystane w programie.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
Podstawy informatyki
35
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TShape *Shape1;
TShape *Shape2;
TShape *Shape3;
TShape *Shape4;
TShape *Shape5;
TShape *Shape6;
TShape *Shape7;
TButton *Button1;
TTimer *Timer1;
TTimer *Timer2;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Timer2Timer(TObject *Sender);
void __fastcall Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y);
private:
// User declarations
public:
// User declarations
int liczba_szans, trafienia;
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
W części publicznej deklaracji klasy TForm1 znajdują się deklaracje dwóch zmiennych:
int liczba_szans – przechowująca informacje o liczbie możliwych pród,
int trafienia – przechowującej informacje o liczbie trafień.
Plik biblioteki:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
randomize();
Podstawy informatyki
36
Timer1->Enabled=false;
Timer2->Enabled=false;
liczba_szans=10;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Timer1->Enabled=true;
trafienia=0;
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int i=0;
if (liczba_szans-i)
{
switch (random (7))
{
case 0:
Shape1->Visible=true;
break;
case 1:
Shape2->Visible=true;
break;
case 2:
Shape3->Visible=true;
break;
case 3:
Shape4->Visible=true;
break;
case 4:
Shape5->Visible=true;
break;
case 5:
Shape6->Visible=true;
break;
case 6:
Shape7->Visible=true;
break;
}
Timer2->Enabled=true;
i+=1;
}
else
{
Timer1->Enabled=false;
Timer2->Enabled=false;
i=0;
Caption=FloatToStr(100*trafienia/liczba_szans);
}
Podstawy informatyki
37
}
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
Shape1->Visible=false;
Shape2->Visible=false;
Shape3->Visible=false;
Shape4->Visible=false;
Shape5->Visible=false;
Shape6->Visible=false;
Shape7->Visible=false;
Timer2->Enabled=false;
}
void __fastcall TForm1::Shape1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
trafienia+=1;
}
Rys. 9: Widok okna programu w trakcie gry.
W grze animację obsługują dwa zegary Timer1 oraz Timer2. Timer1 odpowiedzialny jest
za wyświetlanie na ekranie losowo wybranych obiektów co pewien ustalony w jego
właściwościach czas, jednocześnie włącza Timer2, który po nastawionym czasie ukrywa
w wyświetlany obiekt. Losowość wyświetlania obiektów zapewnia funkcja random()
wyznaczająca numer obiektu do pokazania będąca parametrem instrukcji wyboru switch. Należy
pamiętać o zainicjowaniu procesu losowania przed pierwszym użyciem funkcji random(). Służy
do tego funkcja randomize(), która w programie jest jednokrotnie uruchamiana w konstruktorze
obiektu Form1 klasy TForm1. Bez zainicjowania startowej liczby losowej funkcja random()
Podstawy informatyki
38
będzie zwracała przy każdym uruchomieniu programu taki sam ciąg liczb co spowoduje
wyświetlanie obiektów w tej samej kolejności. Trafienia są zliczane przy wykorzystaniu metody
Shape1MouseDown, która jest wykonywana w momencie kliknięcia myszką któregokolwiek
z pokazujących się obiektów.
3.6. Wykorzystanie funkcji z biblioteki DLL dołączanej dynamicznie.
Plik biblioteki:
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
//deklaracja funkcji eksportowanej z dll do programu
extern "C" __declspec(dllexport) double KelToCel(double _value);
//uchwyt do biblioteki
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//definicja funkcji eksportowanej
double KelToCel(double _value)
{
return (_value - 273.15);
}
Uwaga: bibliotekę należy skompilować za pomocą polecenia Build. Po skompilowaniu
powstaną dwa pliki pierwszy z rozszerzeniem *.dll, drugi z rozszerzeniem *.lib.
Jeśli decydujemy się na dynamiczne odwołanie do funkcji bibliotecznej kopiujemy plik
z rozszerzeniem *.dll do katalogu programu, lub umieszczamy go w katalogu objętym ścieżką
poszukiwań. W przeciwnym wypadku ścieżka do biblioteki musi być podana przy tworzeniu
uchwytu jako parametr polecenia LoadLibrary.
Program główny (wywołujący funkcję z biblioteki):
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
//deklaracja funkcji exportowej
extern "C" __declspec(dllexport) double KelToCel(double _value);
TForm1 *Form1;
Podstawy informatyki
39
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//zdarzenie wciśnięcia klawisza Oblicz w oknie programu
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Tworzenie uchwytu. Należy podać ścieżkę dostępu do biblioteki
// Project1dll.dll, może być względna lub bezwzględna
HANDLE DllHandle = LoadLibrary("Project1dll.dll");
// sprawdzenie czy biblioteka istnieje
if (DllHandle != NULL)
{
// zdefiniowanie typu funkcyjnego o parametrach
// zgodnych z parametrami funkcji exportowanej
typedef double(*TFunc)(double);
// Pobranie i przypisanie do zmiennej Func adresu funkcji _KelToCel
TFunc Func = (TFunc)GetProcAddress(DllHandle,"_KelToCel");
// Sprawdzenie czy funkcja została znaleziona
if (Func != NULL)
{
double dblvalue;
dblvalue = StrToFloat(Edit1->Text);
// Użycie funkcji
Panel1->Caption = FloatToStr(Func(dblvalue));
}
// Zwolnienie uchwytu do biblioteki
FreeLibrary(DllHandle);
}
}
Rys. 10: Widok okna programu.
Podstawy informatyki
40
3.7. Wykorzystanie funkcji z biblioteki DLL dołączanej statycznie.
Uwaga: wykorzystamy tą samą bibliotekę w tym wypadku należy skopiować pliki
z rozszerzeniem *.dll oraz *.lib do katalogu programu.
Program główny (wywołujący funkcję z biblioteki):
#include <vcl.h>
#pragma hdrstop
#include "glowny.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
//deklaracja funkcji exportowej
extern "C" __declspec(dllexport) double KelToCel(double _value);
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double dblvalue;
dblvalue = StrToFloat(Edit1->Text);
// Użycie funkcji
Panel1->Caption = FloatToStr(KelToCel(dblvalue));
}
Uwaga: Łatwo zauważyć, że w tym wypadku uzyskanie dostępu do funkcji jest o wiele
prostsze, płacimy jednak za to większym wykorzystaniem pamięci, gdyż wszystkie funkcje
biblioteczne dołączane są do pliku wykonywalnego w momencie kompilacji i ładowane są do
pamięci niezależnie od potrzeby ich użycia.
3.8. Propozycje zajęć powtórkowych.
3.8.1.
Rozwiązanie równania kwadratowego.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
Podstawy informatyki
41
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TEdit *ed_a;
TEdit *ed_b;
TEdit *ed_c;
TPanel *pa_x1;
TPanel *pa_x2;
TLabel *Label1;
TLabel *Label2;
TLabel *Label3;
TButton *Button1;
TLabel *Label4;
TLabel *Label5;
void __fastcall Button1Click(TObject *Sender);
private:
// User declarations
double a,b,c,x1,x2;
int __fastcall rown();
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
W pliku nagłówkowym w deklaracji klasy TForm1 w sekcji private zadeklarowane zostały
pola a,b,c pozwalające na wprowadzenie współczynników równania oraz x1 i x2 dla wyników
obliczeń. Metoda rown() wyznacza rozwiązanie równania i zapisuje wynik do pól x1, x2
natomiast pod swoją nazwą zwraca informacje o liczbie wyznaczonych pierwiastków równania.
Informacja ta wykorzystana zostaje do sformatowania wyjścia i wyświetlenia wyniku.
Plik programu:
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
Podstawy informatyki
42
int __fastcall TForm1::rown()
{
double delta;
delta=b*b-4*a*c;
if (delta)
{
if (delta>0)
{
x1=(-b-sqrt(delta))/2*a;
x2=(-b+sqrt(delta))/2*a;
return 2;
}
else return 0;
}
else
{
x1=-b/2*a;
return 1;
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
a=StrToFloat(ed_a->Text);
b=StrToFloat(ed_b->Text);
c=StrToFloat(ed_c->Text);
switch (rown())
{
case 0:
pa_x1->Caption="";
pa_x2->Caption="";
MessageDlg("Brak rozwiązania.", mtConfirmation, TMsgDlgButtons() <<
mbYes, 0);
break;
case 1:
pa_x1->Caption=FloatToStr(x1);
pa_x2->Caption="";
break;
case 2:
pa_x1->Caption=FloatToStr(x1);
pa_x2->Caption=FloatToStr(x2);
break;
}
}
Podstawy informatyki
43
Rys. 11: Wygląd okna programu.
3.8.2.
Gra zręcznościowa – auta.
Rys. 12: Plansza do gry w auta.
W proponowanej grze należy przejechać plansze unikając zderzeń z przeszkodami.
Każde zderzenie jest zliczane, przeszkoda na chwilę staje się czerwona a samochód odbija się od
przeszkody. Liczba zderzeń wyświetlana jest na belce tytułowej okna.
Plik nagłówkowy biblioteki:
class TForm1 : public TForm
{
__published: // IDE-managed Components
TScrollBar *ScrollBar1;
Podstawy informatyki
44
TTimer *Timer1;
TTimer *Timer2;
TShape *Shape1;
TShape *Shape2;
TImage *Image1;
TShape *Shape3;
TShape *Shape4;
TShape *Shape5;
TShape *Shape6;
TShape *Shape7;
TShape *Shape8;
TShape *Shape9;
TShape *Shape10;
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall Timer2Timer(TObject *Sender);
private:
// User declarations
public:
// User declarations
int licznik;
void __fastcall zderzenie(TShape *s, TShape *x);
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Plik nagłówkowy wprowadza do klasy TForm1 zmienną całkowitą „licznik”, która będzie
przechowywać informacje o liczbie zderzeń, oraz metodę „zderzenie” badające wzajemne
położenie samochodu i przeszkód (czyli dwóch dowolnych obiektów typu TShape adresy
których przekazane zostają jako parametry metody). Należy zauważyć, że na obiekt Shape2
nałożony został obiekt Image1 zawierający grafikę przedstawiającą samochód. Obiekty te
animowane są w ten sam sposób i jednocześnie przemieszczają się na planszy.
Plik biblioteki:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
licznik=0;
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
zderzenie(Shape2, Shape1);
zderzenie(Shape2, Shape3);
Podstawy informatyki
45
zderzenie(Shape2, Shape4);
zderzenie(Shape2, Shape5);
zderzenie(Shape2, Shape6);
zderzenie(Shape2, Shape7);
zderzenie(Shape2, Shape8);
zderzenie(Shape2, Shape9);
zderzenie(Shape2, Shape10);
Shape2->Left+=3;
Image1->Left+=3;
Shape2->Top+=ScrollBar1->Position;
Image1->Top+=ScrollBar1->Position;
}
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
Shape1->Brush->Color=clWhite;
Shape3->Brush->Color=clWhite;
Shape4->Brush->Color=clWhite;
Shape5->Brush->Color=clWhite;
Shape6->Brush->Color=clWhite;
Shape7->Brush->Color=clWhite;
Shape8->Brush->Color=clWhite;
Shape9->Brush->Color=clWhite;
Shape10->Brush->Color=clWhite;
Timer2->Enabled=false;
}
void __fastcall TForm1::zderzenie(TShape *s, TShape *x)
{
if (((s->Left+s->Width>=x->Left) && (s->Left<x->Left+x->Width)) &&
((s->Top+s->Height>=x->Top) && (s->Top<x->Top+x->Height)))
{
s->Left-=25;
//odskok po zderzeniu
Image1->Left-=25;
//licznik zderzen
licznik+=1;
Caption=IntToStr(licznik);
//zmiana barwy slupka
x->Brush->Color=clRed;
//po tym czasie kolor zmieni sie na poprzedni
Timer2->Enabled=true;
}
}
Za ruch samochodu i kontrole zderzeń odpowiedzialny jest zegar Timer1, natomiast
Timer2 odświeża kolor przeszkód po zderzeniach. Zderzenie jest wykrywane poprzez badanie
wzajemnego położenia obiektu odwzorowującego samochód i kolejno każdej przeszkody.
Podstawy informatyki
46
3.8.3.
Gra w odbijanie piłki o ścianę.
Zadaniem gracza jest jak najdłuższe odbijanie piłki paletką od ścian, gra kończy kiedy
piłka nie zostanie odbita (przekroczy linię paletki).
Rys. 13: Forma z wymaganymi obiektami.
Elementy okna spełniają następujące funkcje:
zegar – steruje animacją paletki i piłki (Timer1 TTimer),
suwak – pozwala wpływać na interwał zegara (Predkosc TTrackBar),
wskaźnik – pokazuje prędkość piłki (SkalaPredkosci TProgressBar),
paletka – sterowany myszką element odbijający piłkę (Paletka Panel),
piłka – obiekt poruszający się po polu gry (Pilka TShape).
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
enum TSciana {paletka,lewa,prawa,gora};
typedef int TWektorXY[2];
Podstawy informatyki
47
class TForm1 : public TForm
{
__published: // IDE-managed Components
TPanel *Paletka;
TShape *Pilka;
TTrackBar *Predkosc;
TProgressBar *SkalaPredkosci;
TTimer *Timer1;
void __fastcall Timer1Timer(TObject *Sender);
void __fastcall PaletkaClick(TObject *Sender);
void __fastcall PredkoscChange(TObject *Sender);
void __fastcall PaletkaMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y);
private:
int StartX;
int LewyKlawisz;
int PozycjaMyszy;
TWektorXY WektorXY;
void __fastcall Koniec(void);
void __fastcall ZmianaWektoraXY(TSciana Sciana, int *WekX, int *WekY);
void __fastcall RuchPaletkiXY(int LewyK, int PozycjaK);
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
W nagłówku wprowadzone zostały dwa własne typy zmiennych:
enum TSciana {paletka,lewa,prawa,gora} – typ wyliczeniowy opisujący obiekty,
w kontakt z którymi wchodzić może piłka,
typedef int TWektorXY[2] – typ tablicowy przechowujący informacje o kierunku
aktualnego wektora ruchu. Wartości wektora to ±1 odpowiednio dla osi X i Y.
W deklaracji klasy TForm1 pojawiają się następujące zmienne i metody prywatne:
int StartX – pamięta połowę szerokości paletki, położenie kursora myszy względem tego
punktu determinuje kierunek ruchu paletki,
int LewyKlawisz – przechowuje stan lewego klawisza myszy,
nt PozycjaMyszy - współrzędna X kursora myszy w momencie naciśnięcia jej lewego
klawisza,
TWektorXY Wektory - położenie piłki,
void __fastcall Koniec(void) – metoda uruchamiana w przypadku przegranej,
void __fastcall ZmianaWektoraXY(TSciana Sciana, int *WekX, int *WekY) – metoda
zmieniająca kierunek wektora ruchu piłki,
void __fastcall RuchPaletkiXY(int LewyK, int PozycjaK) – metoda ustala kierunek ruchu
paletki i przesuwa ją w tym kierunku.
Podstawy informatyki
48
Kod biblioteki programu:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
WektorXY[0]=1;
WektorXY[1]=-1;
}
void __fastcall TForm1::Koniec(void)
{
Timer1->Interval=0;
MessageDlg("Gra skończona", mtConfirmation, TMsgDlgButtons() << mbOK, 0);
Form1->Close();
}
//Zmiana wektora ruchu WektorXY po odbiciu od sciany
void __fastcall TForm1::ZmianaWektoraXY(TSciana Sciana, int *WekX, int *WekY)
{
switch (Sciana)
{
case paletka :
*WekY=-*WekY;
break;
case lewa :
*WekX=-*WekX;
break;
case prawa :
*WekX=-*WekX;
break;
case gora :
*WekY=-*WekY;
}
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
TWektorXY PozPocz = {Pilka->Left, Pilka->Top};
if (PozPocz[1]<2) ZmianaWektoraXY(gora, &WektorXY[0], &WektorXY[1]);
if (PozPocz[1]>Paletka->Top-15)
Podstawy informatyki
49
if (!((PozPocz[0]+Pilka->Width/2 > Paletka->Left)
& (PozPocz[0]+Pilka->Width/2 < Paletka->Left+Paletka->Width))) Koniec();
else ZmianaWektoraXY(paletka, &WektorXY[0], &WektorXY[1]);
if (PozPocz[0]<2) ZmianaWektoraXY(lewa, &WektorXY[0], &WektorXY[1]);
if (PozPocz[0]>Form1->Width-34) ZmianaWektoraXY(prawa, &WektorXY[0],
&WektorXY[1]);
Pilka->Top=PozPocz[1]+WektorXY[1];
Pilka->Left=PozPocz[0]+WektorXY[0];
Caption=IntToStr(Pilka->Left) + " " + IntToStr(Pilka->Top);
RuchPaletkiXY(LewyKlawisz, PozycjaMyszy);
}
void __fastcall TForm1::PaletkaClick(TObject *Sender)
{
StartX = Paletka->Width/2;
}
void __fastcall TForm1::PredkoscChange(TObject *Sender)
{
Timer1->Interval= 100 / Predkosc->Position;
SkalaPredkosci->Position= Predkosc->Position ;
}
void __fastcall TForm1::PaletkaMouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
LewyKlawisz = Shift.Contains(ssLeft);
PozycjaMyszy=X;
}
void __fastcall TForm1::RuchPaletkiXY(int LewyK, int PozycjaK)
{
if (LewyK) // make sure button is down
{
if (PozycjaK > StartX)
{
if (Paletka->Left+Paletka->Width+15<Form1->Width)
Paletka->Left=Paletka->Left+5;
}
else
{
if (Paletka->Left-10>0)Paletka->Left=Paletka->Left-5;
}
}
}
Podstawy informatyki
50
3.8.4.
Gra logiczna – patyczki.
Zasady proponowanej gry są następujące:
gra przeznaczona jest dla dwóch osób,
na planszy znajduje się 21 patyczków po 7 w trzech rzędach,
gracze wykonują ruchy naprzemiennie,
w jednym ruchu można zdjąć z planszy dowolną liczbę leżących obok siebie patyczków
(jedną grupę z jednego rzędu),
grę przegrywa gracz zdejmujący z planszy ostatni patyczek.
Rys. 14: Przykładowa plansza w trakcie rozgrywki.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
class TForm1 : public TForm
{
Podstawy informatyki
51
__published: // IDE-managed Components
TPanel *Panel1;
TPanel *Panel2;
TPanel *Panel3;
TPanel *Panel4;
TPanel *Panel5;
TPanel *Panel6;
TPanel *Panel7;
TPanel *Panel8;
TPanel *Panel9;
TPanel *Panel10;
TPanel *Panel11;
TPanel *Panel12;
TPanel *Panel13;
TPanel *Panel14;
TPanel *Panel15;
TPanel *Panel16;
TPanel *Panel17;
TPanel *Panel18;
TPanel *Panel19;
TPanel *Panel20;
TPanel *Panel21;
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Panel1Click(TObject *Sender);
private:
// User declarations
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall ZmianaStanu(TObject *Sender);
int __fastcall Znikanie(int Tag);
int min,max;
};
extern PACKAGE TForm1 *Form1;
#endif
Do odwzorowania patyczków wykorzystane zostały obiekty klasy TPanel ze względu na
przestrzenny wygląd, można też użyć innych obiektów, np.: z klasy TButton lub TShape.
W sekcji publicznej klasy TForm1 znajdujemy:
void __fastcall ZmianaStanu(TObject *Sender) – metoda ta sprawdza czy wybrany
patyczek znajduje się w wierszu z którego pobrany był patyczek poprzedni, wywołuje
metodę sprawdzającą czy patyczek przylegał do poprzednio zdjętych i jeśli tak to go
usuwa z planszy.
int __fastcall Znikanie(int Tag) – sprawdza przyleganie do grupy poprzednio wybranych
patyczków, rozszerza granice grupy i zwraca 1 jeśli ruch jest prawidłowy.
int min,max – zapamiętuje granice grupy dla każdego ruchu.
Plik programu:
#include <vcl.h>
#pragma hdrstop
Podstawy informatyki
52
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
min=0; //granica lewa wybranych patyczkow
max=0; //granica prawa wybranych patyczkow
}
int __fastcall TForm1::Znikanie(int Tag)
{
if (Tag==min-1) //sprawdzenie czy patyczek przylega do wybranej grupy
{
min=min-1;
return 1;
}
if (Tag==max+1) //sprawdzenie czy patyczek przylega do wybranej grupy
{
max=max+1;
return 1;
}
return 0;
}
void __fastcall TForm1::ZmianaStanu(TObject *Sender)
{
TControl *x = (TControl*)(Sender);
if ((min==0) & (max==0)) // dla pierwszego patyczka ustalamy granice i znikamy
{
min=x->Tag;
max=x->Tag;
x->Visible=0;
}
else
{
//pierwszy wiersz
if (((min>=1) & (min<=7)) & ((x->Tag>=1) & (x->Tag<=7)))
{
if (Znikanie(x->Tag)) x->Visible=0;
}
//drugi wiersz
if (((min>=8) & (min<=14)) & ((x->Tag>=8) & (x->Tag<=14)))
{
if (Znikanie(x->Tag)) x->Visible=0;
}
Podstawy informatyki
53
//trzeci wiersz
if (((min>=15) & (min<=21)) & ((x->Tag>=15) & (x->Tag<=21)))
{
if (Znikanie(x->Tag)) x->Visible=0;
}
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
min=0;
max=0;
}
void __fastcall TForm1::Panel1Click(TObject *Sender)
{
ZmianaStanu(Sender);
}
Uwagi:
dla prawidłowego działania programu wymagane jest ponumerowani patyczków liczbami
z zakresu 1-21. Wykorzystać do tego można pola Tag obiektów odwzorowujących
patyczki,
naciśnięcie dowolnego patyczka wywołuje metodę Panel1Click, która to z kolei
wywołuje metodę ZmianaStanu, metoda rozróżnia patyczki dzięki przekazanej zmiennej
Sender będącej adresem wskazującym na obiekt, którego dotyczy zdarzenie kliknięcia
myszką.
3.8.5.
Gra – strzelanie do celu.
W proponowanej zabawie celem gracza jest trafienie z działa do poruszającego się celu.
Prędkość celu może być ustawiana suwakiem natomiast prędkość pocisku jest stała. Trafienie
sygnalizowane jest najpierw zmianą kształtu i koloru obiektu a potem jego zniknięciem. Zegar
timer_samolotu pobiera wartość nastawioną na suwaku i z zadaną częstotliwością modyfikuje
położenie samolotu. Zegar timer_kuli sprawdza czy nastąpił strzał (zmienna ztrzal ustawiana
przez przycisk spust) jeśli tak to oblicza położenie przestrzenne samolotu i kuli, sprawdza ich
wzajemne położenie i w przypadku trafienia uruchamia animacje wybuchu. W proponowanym
przykładzie fakt oddania strzału rejestrowany jest poprzez zmianę wartości zmiennej strzał.
Klawisz wyzwalający strzał mógłby też powodować uruchomienie zegara timer_kuli, gdyż przed
strzałem sprawdzanie wzajemnego położenia obiektów nie ma większego sensu. Obie metody
mają wady i zalety i wybór jednej z nich zależy od doświadczeń programisty.
Plik nagłówkowy:
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
Podstawy informatyki
54
#include <ExtCtrls.hpp>
#include <ComCtrls.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TTimer *timer_samolotu;
TShape *samolot;
TTrackBar *TrackBar1;
TShape *lufa;
TShape *kula;
TButton *spust;
TTimer *timer_kuli;
TShape *wybuch;
void __fastcall timer_samolotuTimer(TObject *Sender);
void __fastcall spustClick(TObject *Sender);
void __fastcall timer_kuliTimer(TObject *Sender);
private:
// User declarations
int strzal;
public:
// User declarations
__fastcall TForm1(TComponent* Owner);
};
extern PACKAGE TForm1 *Form1;
#endif
Rys. 15: Widok planszy w trakcie gry.
Plik programu:
#include <vcl.h>
#pragma hdrstop
Podstawy informatyki
55
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::timer_samolotuTimer(TObject *Sender)
{
samolot->Left+=TrackBar1->Position;
}
void __fastcall TForm1::spustClick(TObject *Sender)
{
strzal=1;
}
void __fastcall TForm1::timer_kuliTimer(TObject *Sender)
{
if (strzal)
{
int S1L=samolot->Left;
int S1R=samolot->Left+samolot->Width;
int S3L=kula->Left;
int S3R=kula->Left+kula->Width;
int S1H=samolot->Top;
int S1D=samolot->Top+samolot->Height;
int S3H=kula->Top;
int S3D=kula->Top+kula->Height;
kula->Top-=1;
wybuch->Top-=1;
if ((((S1R)>S3L) && ((S3R)>S1L)) && (((S3H)<S1D) && ((S3D)>S1H)))
{
kula->Visible=0;
wybuch->Visible=1;
samolot->Visible=0;
strzal=0;
}
}
else
{
wybuch->Visible=0;
}
}
Podstawy informatyki
56
4. Literatura:
1
J. Grębosz: Symfonia C++, Oficyna Kallimach, Kraków 1999
2
J. Grębosz: Pasja C++, Oficyna Kallimach, Kraków 1999
3
Pliki pomocy dołączone do C++ Builder 6.0
4
Dowolny podręcznik z opisem języka C++
5
Dowolny podręcznik z opisem środowiska C++ Builder w wersji 6 (ewentualnie
nowszej)
6
Serwisy internetowe dotyczące C++
Instrukcja jest współfinansowana przez Unię Europejską
w ramach Europejskiego Funduszu Społecznego
w projekcie:
"Innowacyjna dydaktyka bez ograniczeń
- zintegrowany rozwój Politechniki Łódzkiej zarządzanie Uczelnią,
nowoczesna oferta edukacyjna
i wzmacniania zdolności do zatrudniania,
także osób niepełnosprawnych".