Podstawy
programowania
Wykład 6: Struktury. Złożone
projekty
Zachodniopomorska Szkoła Biznesu
Podstawy programowania - Struktury. Złożone
projekty
Struktura (rekord)
Często w programie buduje się zestaw danych
opisujących pewien obiekt za pomocą zbioru zmiennych
o zróżnicowanych typach.
Przydatne jest utworzenie złożonego typu danych
grupującego wszystkie informacje o takim obiekcie
Typ taki nazywa się zwykle rekordem, choć w C++
mówi się raczej o strukturze ze względu na stosowane
do jej definicji słowo kluczowe
struct
. Każdą z danych
wchodzących w skład rekordu nazywa się polem
Rekord jest jednym z podstawowych elementów, z
jakich złożona jest większość współczesnych baz danych
Rekord
pole 1
pole 2
pole 3
Podstawy programowania - Struktury. Złożone
projekty
Deklaracja zmiennej - rekordu
Składnia:
struct
{
deklaracje zmiennych - pól
...
} nazwa_zmiennej_rekordowej;
Przykład:
struct {
char nazwisko[20];
long telefon;
} kontakt;
Inicjalizacja:
struct {
char nazwisko[20];
long telefon;
} kontakt = {"Kowalski", 601111111};
zmienna: kontakt
pole: nazwisko
pole: telefon
Podstawy programowania - Struktury. Złożone
projekty
Deklaracja typu - rekordu
Składnia:
struct nazwa_struktury
{
deklaracje zmiennych - pól
...
};
Przykład:
struct Kontakt
{
char nazwisko[20];
long telefon;
};
struct Kontakt kolega;
// Zmienne - rekordy
Kontakt kolezanka;
// można pominąć 'struct'
Kontakt policja = { "Numer alarmowy", 112 };
Podstawy programowania - Struktury. Złożone
projekty
Deklaracja typu i zmiennej naraz
Składnia:
struct nazwa_struktury
{
deklaracje zmiennych - pól
...
} nazwy_zmiennych;
Przykład:
struct Kontakt
{
char nazwisko[20];
long telefon;
} kolega1, kolega2;
Kontakt k;
// Użycie nowego typu
Podstawy programowania - Struktury. Złożone
projekty
Korzystanie z rekordu
Każde pole rekordu jest osobną zmienną, do której
dostęp uzyskuje się poprzez: nazwę zmiennej
rekordowej, operator
.
oraz nazwę pola
Do zmiennej rekordowej jako całości można użyć
operatora przypisania (
=
) oraz porównania (
==,!=
)
wobec wartości, która ma typ rekordowy o tej samej
strukturze
Przypisanie powoduje skopiowanie wszystkich pól z
rekordu po prawej stronie znaku
=
Rekordy uznaje się za równe (
==
) jeżeli wszystkie ich
pola są równe.
Rekordy są różne (
!=
) jeżeli różnią się co najmniej
jednym polem
Podstawy programowania - Struktury. Złożone
projekty
Przykład użycia rekordu
struct Zespolona
// liczba zespolona
{
float Re, Im; };
// dwa pola naraz
Zespolona z1,z2 = {1,2};
// z2= 1 + 2i
z1.Re=5;
z1.Im=-1'
// z1= 5-i
Zespolona suma;
suma.Re = z1.Re + z2.Re;
suma.Im = z1.Im + z2.Im;
z2=z1;
// przypisanie
if (z1==z2)
// porównanie
cout << "Liczby jednakowe" << endl
Podstawy programowania - Struktury. Złożone
projekty
Dostęp do rekordu przez
wskaźnik
Dla typu rekordowego można utworzyć odpowiedni
wskaźnik służący do pokazywania na takie rekordy
Dostęp do pól w zmiennej pokazywanej przez wskaźnik
odbywa się z użyciem operatora
->
Przykład:
struct Zesp
{
float Re, Im; };
Zesp z1,z2;
Zesp *wsk
;
// deklaracja wskaźnika
wsk=&z1;
// 'wsk' pokazuje na 'z1'
wsk
->
Re= 0;
// dostęp do pól
wsk
->
Im= 1;
(*wsk).Re=0;
// można też tak ale po co?
(*wsk).Im=1;
z2=
*wsk
;
// pobranie wartości spod wskaźnika
wsk=&z2
// teraz 'wsk' pokazuje na 'z2'
Podstawy programowania - Struktury. Złożone
projekty
Wskaźnik do rekordu jako
parametr
Często podczas przekazywania do i z funkcji danych w
postaci rekordu stosuje się wskaźnik
Znacznie przyspiesza to działanie programu, ponieważ do
funkcji przesyłany jest tylko adres zamiast całego rekordu
Przykład:
void wstawzero(Zesp *wsk)
{
wsk->Re=0;
// funkcja wypełnia rekord
wsk->Im=0;
// wskazany przez 'wsk'
}
void main()
{
Zesp z;
wstawzero(&z);
}
Podstawy programowania - Struktury. Złożone
projekty
Tablica rekordów
Dla typu rekordowego można utworzyć tablicę
Dostęp do konkretnego pola wymaga wtedy podania:
nazwy tablicy, indeksu oraz nazwy pola.
Przykład:
struct Grupa
// deklaracja struktury
{
int numer;
float srednia };
Grupa grupy[3];
// tablica rekordów
grupy[0].numer
=11;
grupy[1].numer=21;
grupy[2].numer=41;
for (i=0; i<3; i++)
grupy[i].srednia
=5.0;
Przykład: STUDENT.CPP
Podstawy programowania - Struktury. Złożone
projekty
Pola bitowe
Pola bitowe pomagają oszczędzać pamięć
Są również przydatne w komunikacji ze sprzętem
Jest to rodzaj pola w strukturze, który pozwala zapisać
informację na małej grupie bitów
Każde pole bitowe musi być zmienną całkowitoliczbową
Przykład:
struct pogoda
{
int deszcz:1;
int wiatr :1;
int slonce:1;
int temp :2; // załóżmy, że są 4 przedziały
}; // razem 5 bitów zamiast 16
Podstawy programowania - Struktury. Złożone
projekty
Unie
Unie tworzy się dla oszczędności miejsca w pamięci. Jest
to kontener, w którym można zapisać zmienne o różnych
typach, przy każda z nich zapisywana jest w tym
samym miejscu niszcząc poprzednią wartość
Unia ma rozmiar równy rozmiarowi największego z typów
składowych
Na programiście spoczywa obowiązek pamiętania jakiego
typu wartość zapisana była ostatnio
Przykład:
union intfloat
{
int calkowita;
float rzeczywista; };
intfloat unia;
unia.calkowita=5;
unia.rzeczywista=4.5;
// calkowita jest zniszczona!
cout << unia.calkowita << endl;
// to nie będzie 5!
Podstawy programowania - Struktury. Złożone
projekty
Parametry funkcji
main
Wiele programów pozwala użytkownikowi podać parametry
wywołania, np. w linii komend lub we właściwościach skrótu
W programie w C++ można te parametry odczytać definiując
parametry wywołania dla funkcji
main
Zakłada się, że cały tekst wywołania programu podzielony
jest na części oddzielone spacjami
Pierwszy parametr (
int argc
) podaje liczbę takich części
łącznie z samą nazwą programu
Drugi z parametrów (
char *argv[]
)
jest tablicą stringów
zawierającą poszczególne części
Przykład:
void main(int argc, char *argv[])
{
for (int i=0; i<argc; i++)
cout << argv[i] << endl;
// wypisanie param.
}
Podstawy programowania - Struktury. Złożone
projekty
Projekty (1)
Język C++ umożliwia budowę programu złożonego z
wielu osobnych plików CPP
Pozwala to bardziej efektywnie zarządzać kodem
źródłowym oraz skrócić czas kompilacji
Zazwyczaj podział kodu na części, tzw. moduły, odbywa
się na zasadzie funkcjonalnej: fragmenty dotyczące
określonej dziedziny umieszczane są w osobnym pliku
Integrację plików zapewnia system SDK dzięki tzw.
projektowi, do którego należy dodać wszystkie moduły,
z których złożony jest program
System SDK sam dba o to by skompilować te moduły,
które uległy zmianom od ostatniej kompilacji, a następnie
dokonuje ich konsolidacji
W przypadku kompilacji z linii komend - budowy programu
dokonuje program make w oparciu o plik makefile
Podstawy programowania - Struktury. Złożone
projekty
Projekty (2)
Kompilacja każdego z modułów odbywa się niezależnie
W przypadku, gdy moduł korzysta ze zmiennych lub
funkcji zdefiniowanych w innym module, należy
zamieścić w nim odpowiednią deklarację
Zazwyczaj dokonuje się tego poprzez napisanie i
włączenie odpowiedniego pliku nagłówkowego .H
Użycie funkcji z drugiego modułu wymaga włączenia jej
prototypu (nagłówka)
Użycie zmiennej zdefiniowanej w innym module wymaga
umieszczenia jej deklaracji z użyciem słowa
extern
Przykład:
void funkcja (int param);
// prototyp
extern int zmienna;
// zmienna zewnętrzna
Podstawy programowania - Struktury. Złożone
projekty
Przykład projektu - 2 moduły
MAIN.CPP:
#include <iostream.h>
void funkcja();
extern int zmienna;
int globalna;
void main()
{
cout << "Main.cpp, ";
cout << "main().\n";
funkcja();
cout <<
zmienna
; // 10
}
MODUL.CPP:
#include <iostream.h>
extern int globalna;
void funkcja()
{
cout << "Modul.cpp, ";
cout << "funkcja().\n";
zmienna=10;
}
Podstawy programowania - Struktury. Złożone
projekty
Przykład - 2 moduły i zbiór .H
MAIN.CPP:
#include <iostream.h>
#include "modul.h"
void main()
{
cout << "Main.cpp, ";
cout << "main().\n";
funkcja();
cout << zmienna; // 10
}
MODUL.CPP:
#include <iostream.h>
void funkcja()
{
cout << "Modul.cpp, ";
cout << "funkcja().\n";
zmienna=10;
}
MODUL.H:
void funkcja();
extern int zmienna;
Podstawy programowania - Struktury. Złożone
projekty
Wielokrotna inkluzja
Czasem zdarza się, że plik nagłówkowy jest włączany do
pewnego modułu kilkakrotnie: raz bezpośrednio oraz
dodatkowo pośrednio przez inne pliki nagłówkowe
Niepotrzebnie wydłuża to kompilację i może
spowodować błąd powielenia tej samej deklaracji, np.
zmiennej globalnej.
Zwykle stosuje się w tym celu zabezpieczenie w postaci
kompilacji warunkowej:
#ifndef NAZWA_H
// kompilacja warunkowa
#define NAZWA_H
// definicja stałej
...
(treść zbioru nagłówkowego)
...
#endif
// koniec kompilacji warunkowej
Podstawy programowania - Struktury. Złożone
projekty
Wielokrotna inkluzja - przykład
MAIN.CPP:
#include "punkt.h"
#include "wektor.h"
#include "trojkat.h"
WEKTOR.H:
#include "punkt.h"
(deklaracje - wektor)
TROJKAT.H:
#include "punkt.h"
(deklaracje - trójkąt)
PUNKT.H:
(deklaracje - punkt)
MAIN.CPP po inkluzjach:
(deklaracje - punkt)
(deklaracje - punkt)
(deklaracje - wektor)
(deklaracje - punkt)
(deklaracje - trójkąt)
Podstawy programowania - Struktury. Złożone
projekty
Wielokrotna inkluzja -
rozwiązanie
MAIN.CPP:
#include "punkt.h"
#include "wektor.h"
#include "trojkat.h"
WEKTOR.H:
#include "punkt.h"
(deklaracje - wektor)
TROJKAT.H:
#include "punkt.h"
(deklaracje - trójkąt)
PUNKT.H:
#ifndef PUNKT_H
#define PUNKT_H
(deklaracje - punkt)
#endif
MAIN.CPP po inkluzjach:
#ifndef PUNKT_H
// prawda
#define PUNKT_H
(deklaracje - punkt)
#endif
#ifndef PUNKT_H
// fałsz
#define PUNKT_H
// pominięte
(deklaracje - punkt)
#endif
(deklaracje - wektor)
#ifndef PUNKT_H
#define PUNKT_H
// pominięte
(deklaracje - punkt)
#endif
(deklaracje - trójkąt)
Podstawy programowania - Struktury. Złożone
projekty
Modyfikatory typów (1)
Przed deklaracją zmiennej lub funkcji może stać kilka
możliwych modyfikatorów, mogących wpływać na znaczenie
deklaracji. Są to:
extern
oznacza deklarację symbolu zdefiniowanego na
zewnątrz, domyślne dla prototypu funkcji
auto
oznacza utworzenie zmiennej nietrwałej na stosie,
domyślne dla zmiennych wewnątrz funkcji. Dla globalnych -
niedostępne.
static
oznacza utworzenie zmiennej w pamięci, czas życia
równy czasowi działania programu, domyślne dla zmiennych
globalnych. Użyte wewnątrz funkcji skutkuje tym, że przy
kolejnych wywołaniach zmienna pamięta poprzednią wartość.
const
oznacza zmienną, której wartości nie można zmieniać,
można nadać ją wyłącznie przy inicjalizacji. Użyte w odniesieniu
do parametru funkcji - informuje, że funkcja nie może zmieniać
wartości tej zmiennej
Podstawy programowania - Struktury. Złożone
projekty
Modyfikatory typów (2)
typedef
oznacza, że nie deklarujemy zmiennej ale nazwę
nowego typu danych. Typu tego można potem użyć do
tworzenia zmiennych.
volatile
oznacza zmienną, której wartość może być
zmieniana z zewnątrz programu, kompilator nie umieści jej
w rejestrze procesora
register
oznacza, że zmienna będzie tak często
wykorzystywana, że chcemy aby kompilator przechowywał
ją w rejestrze procesora
inline
używa się dla deklaracji funkcji, oznacza sugestię
aby przy każdym wywołaniu tej funkcji kompilator wklejał jej
kod maszynowy w całości zamiast organizować skok do
podprogramu. Ma to sens dla bardzo krótkich funkcji,
działają wtedy szybciej
To już jest koniec++
Dziękuję za uwagę