Przeładowanie nazw funkcji
Przy kilku funkcjach umiszcza się je w nawiasach klamrowych.
Jeżeli deklaracje funkcji o tej samej nazwie mają różne z
Zakres ważności nazw obiektu
Czas życia obiektu to okres od momentu gdy zostaje on zdefiniowany (definicja przydziela obiektowi miejsce w pamięci ) do momentu, gdy przestaje isnieć.
Zakres ważności obiektu to ta część programu, w której nazwa znana jest kompilatorowi. W zależności od definicji obiektu, rozróżniamy następujące zakresy ważności nazwy obiektu:
- zakres lokalny - gdy zdefiniowany jest w bloku ograniczonym zawiasami klamrowymi.
- zakres bloku funkcji -
- zakres obszaru pliku - są to nazwy globalne deklarowane na zewnątrz pliku przed funkcją main(). Nazwa taka nie jest automatycznie znana i winych plikach a jedynie w pliku w którym zadeklarowana (od miejsca deklaracji do końca pliku).
- zakres obszaru klasy
+ Nazwy lokalne zasłaniają w obrębie bloku nazwy globalne.
+ Po wyjściu z bloku zmienne lokalne przestają istnieć - kończy się życie obiektu oraz zakres ważności nazwy.
+Do zasłoniętej zmiennej globalnej można się za pomocą operatora zakresu ::zmienna
+Jeżeli nazwa lokalna zasłoni nazwę lokalna, to przy pomocy operatora zakresu nie można do niej dotrzeć.
Typy obiektów
Rozróżniamy następujące typy obiektu (z wz na zasięg - globalne loalne)(różnią się umiejscowieniem w pamięci) (adres logiczny zmiennej globalnej stały zawsze 0)
Obiekty automatyczne są to zmienne lokalne przechowywane na stosie. Przestają one automatycznie istnieć w momencie, gdy kończymy blok, w którym powołuje się je do życia.
Obiekty automatyczne typu całkowitego - można zamiast na stosie przechowywać w rejestrze a więc w komórce pamięci bardzo szybkim dostępie.
Szybki dostęp do obiektu automatycznego umożliwia modyfikator „register”, np.
Register int k;
Obiekty stałe definiuje modyfikator const. PÓŹNIEJ NIE MOŻNA MU NADAĆ LUB ZMIENIĆ WARTOŚCI
Const float pi=3.14
Ale przypisanie później nawet pi = 3.14 jest błędne
Modyfikator volatile informuje kompilator że obiekt jest ulotny może się w sposób niezauważalny zmienić no
Volatile int temperatura:
Obiekty lokalne statyczne zachowują wartość jaką miały w chwili unicestwienia. Deklarujemy je za pomocą słowa kluczowego „static”
Static Typ_zmiennej Nazwa _zmiennej ;
Modyfikator static modyfikuje definicję obiektu lokalnego tak, że staje się on nieśmiertelny, Obiekty te są przechowywane podobnie jak obiekty globalne ni na stosie ale w normalnej pamięci a w bezpośrednio po definicji mają wartość równą zetu. Można im jednak przypisać w definicji inną wartość początkową:
Stator Typ_z,oemmek Nazwa_zmiennej = wartość_początkowa
Obiektyy satyczne po wyjściu z funkcji stają się niezmienne.
Podział programu na kilka plików
Dyrektywy procesora
Preprocesor jest to program wywoływany bezpośrednio przed uruchomieniem kompilatora. Przetwarza on instrukcje zwane dyrektywami
Dyrektywa #define
Dyrektywa #define np.
#define pi 3.14
Zmienia nazwę obiektu stałego na stałą dosłowną
- nazwa tego obiektu stałego pozostaje dla kompilatora nieznana a więc kompilator nie jest w stanie sprawdzić czy została ona użyta w swoim zakresie ważności
- satałą tak zdefiniowana jest znana od linijki wystąpienia dyrektywy do końca pliku lub linijki z dyrektywą #undef ale nie ma toni wspólnego z ej zakresem ważności.
Dyrektywa ta ma postać #define wyraz zatęprzy ciąg znaków
+dyrektywa #undef nazwa pozwala anulować dyrektywę #define nazwa w dowolnym miejscu w programie
+występujący w dyrektywie #define zastępczy ciąg znakó może być instrukcją, np.
#define DZIALANIE (Chile (liczba !=0) dziel) () ; )
Długi zastępczy ciąg znakó można pisać w kilku liniach sawiając na końcu każdej linii znak
+dyrektywa #define pozwala rónież tworzyć makrodefinicje np.
#define KWADR(a)((a)*(a))
+Tak utworzona makrodefinicja jest automatyczną zamianą jednego łańcucha na inny bz sprawdzenia typów parametrów oraz zakresów ważności wżytych nazw. Dlatego zamiast takich makrodefinicji lepiej używać funkcje inline,
Tablice
+tablica jest to ciąg obiektów tego samego typu zajmujących ciągły obszar w pamięci. Jestona typem pochodnym.
+rozmiar tablicy musi być satą znaną podczas kompilacji a więc musi zostać zadeklarowany w definicji tablicy np.
Int r [20]
+w definicji tablicy można nadać elementom tablicy wartości początkowe metodą tzw inicjalizacji zbiorczen
Int dane[4] = {23 2}
Podczas inicjalizacji sprawdzany jest rozmiar tablicy
Można zdefiniować i zainicjalizować tablicę bez podania w sposób jawny jej rozmiaru
Dane 1[] = {23,2}
Dla takiej tablicy zostanie przyjęty rozmiar domyślny
Elementy tablicy mogą być:
- typu fundamentalnego (z wyjątkiem viod)
Char tekst [40]
Float liczby [10]
Unsinded long [23333]
- typu wyliczeniowego (enum)
- wskaźnikami
- innymi tablicami
- obiektami typu zdefiniowanego przez użytkownika (klasami)
- wskaźnikami wskazującymi na składniki klasy.
Int *wskaźniki [15]; //15elementowa tablica wskaźników
//do obiektów typu int
Numeracja elementów tablicy zaczyna się od zera a więc tablica „n” - elementowa ma elementy o indeksach od 0 do n-1.
Przykłady tablicy do funkcji
+tablicę przesyłą się do funkcji podając jej adres początkowy tavlicy (adres zerowego elementu).
+W wywołaniu funkcji wystarczy podać tylko nazwę tablicy, bo jest ona jednocześnie adresem jej zerowego elementu, np.:
Int dane [4] = {23,2,33,12}; //definicja tablicy (tam wyzej też jest 4 elementy w klamrach)
Funkcja (dane) //wywołanie funkcji - przekazanie org przez adres
+Adres k- tego elementu tablicy określa zapis:
dane + k lub &dane [k]
+poszczególne elementy tablicy mogą być argumentami funkcji tak jak liczby , np. funkcja
Vioid Funk (int x)
Może mieć argument będący elementem tablicy typu int
int k ;
Funk (k); //wywołanie funkcji od zwykłej zmiennej
Definicja tablicy o elementach typu int
Int tabl [10];
Funk (tabl[5]
//wywołanie funkcji od elementu nr 5 tablicy - przekazanie Arg przez wartość.
TABLICE ZNAKOWE
+Przechowują znaki alfanumeryczne w postaci kodu ASCII, przy czym można je zainicjalizować jak inne zmienne no
Char wyraz [10] = {„samolot”}
+W tym przypadku elementach tablicy od 0 do 6 będą poszczególne znaki natomiast w 7 elemencie- znak NULL. Pozostałe elementy będą inicjalizowane zrami.
+Przy inicjalizowaniu tablicy stringiem jej rozmiar musi być co najmniej o jeden większy od długości łańcucha ze względu na znak NULL
+Tablicę można też zainicjalizować inaczej no:
Chat wyraz [10] = {`s','a','m','o','l','o','t',};
+W tym przypadku nie wystąpi w sposób jawny znak NULL ale ponieważ posotałe elementy będą inicjalizowane zerami więc ciąg znaków będzie traktowany jako string.
+Przy deklarowaniu tablicy znaków bez podania jej rozmiaru przy deklaracji:
Char wyraz [] = {`s','a','m','o','l','o','t',};
Tablica zostanie potraktowana jako 7 elementowy ciąg znaków natomiast przy deklaracji:
Char wyraz [] = {„samolot”}
Kompilator dołączy 8-my element
+Rozmiar tablicy zwraca funkcja sieof (wyraz);
+W podany sposób można było wpisać string do tablicy TYLKO NA ETAPIE INICJALIZACJI
+Chcąc wpisać łańcuch do tablicy już istniejącej trzeba było zrobić to przez skopiowanie kolejnych znaków z tablicy źródłowej do tablicy docelowej łącznie z znakiem NULL.
+ W nowym standardzie C++ działania na tablica znakowych zostały zastąpione działaniami na instancjach obiektów klasy string.
TABLICE WIELOWYMIAROWE
+Są to tablice których elementami są inne tablice.
+Definicja, będąca jednocześnie deklaracją tablicy 4-elementowej w której każdy element jest tablicą 2-elementową o elementach typu int ma postać:
Int WSP [2] [2] = {5,10,15,20];
Zawiera ona elementy
wsp [0] [0] = 5; wsp [0] [1] = 10;
wsp [1] [0] = 15; wsp [1] [1] = 20;
+Pierwszy wymiar to liczba wierszy, drugi - liczba kolumn
+Przy przesyłaniu tablicy wielowymiarowej do funkcji wystarczy przesłać tylko jej nazwę która jest jej adresem początkowym np.
funk (wsp);
+Deklaracja funkcji powinna zawierać typ elementów tablicy oraz liczbę kolumn tej tablicy np.
void funk (int t [] [2]);
+Przy tablicach wielowymiarowych należy podawać wszystkie rozmiary z wyjątkiem lewego skrajnego np.:
void funk4 (int [] [2] [5] [3]);
14.11.2007
Wskaźniki przechowuje adres obiektu. W celu nadania wskaźnikowi wartości początkowej używamy jednoargumentowego operatora &. Operator ten oblicza adres obiektu, który stoi po jego prawej stronie
Do odczytania zawartości obiektu lub zapisania czegoś do obiektu wskazanego oprzez wskaźnik służy jednoargumentowy operator odniesienia*. Przy takim zapisie wskaźnik *w został przypisany do obiektu w
+W definicji wskaźnika można nadać mu wartość początkową (przypisać adres), np.:
Int )w = &k; //nadanie w definicji wartości początkowej
+ do obiektu można odnosić się na dwa sposoby:
- używając jego nazwy, np. k=5
- używając wskaźnika który obiekt pokazuje np. *w=5
+w programie można ustawić ten sam wskaźnik na różne obiekty no: w = & a;
+Wskaźnik może wskazywać miejsce w pamięci obiektu nieokreślonego typu np.:
void )w;
+do takiego wskaźnika można przypisać wskaźnik do obiektu każdego (niestałego) typu z wyjątkiem obiektu typu const.
+nie można typuvoid przypisać wskaźnikowi określonego typu. Trzeba się wówczas posłużyć operatorem rzytowania (konwersji typu), np.
int )w1, )w2 ; //definicja wskaźników do obiektów typu int
float )wf; // definicja wskaźnika do obiektów typu float
void )vw //definicja wskaźnika typu void
vw = w1 ; // przypisanie do wskaźnika typu cvoid
vw + wf ; //bez rzutowania typów
wf +(float *)w1; //przypisanie wskaźnika do obiektu typu int
// do wskaźnika do obiektu typu float (z rzytowaniem typu)
wf + (float*)vw; // przypisanie wskaźnika typu void do wskaźnika obiektu typu float (z rzutowaniem typu)
+wskaźniki stosowane są do:
- pracy z tablicami
- w funkcjach zmieniających wartość przesyłanych argumentów,
- w celu dostępu do specjalnych komórek pamięci
- do rezerwacji obszraów pamięci
ZASTOSOWANIE WSKAŹNIKÓW DO PRACY Z TABLICAMI
+Wskaźniki mogą służyć do wskazywania elementów tablicy,
Int *wsk; //deklaracja wskaźnika do obiektu typu int
Int tab [10]; //deklaracja tablicy o elementach typu int
Wsk = &tab [n]; //ustawienie wskaźnika na elemencie n tablicy (wstawienie do wskaźnika adresu ntego elementu)
+POnieważnazwa tablicy jest jednocześnie adresem jej pierwszego (zerowego) element to instrukcja:
Wsk = tab
Ustawia wskaźnik na początku tablicy (na jej zerowym elemencie)….
+ Jeśli ustawiamy wskaźnik na n elemencie tablicy instrukcją
Wsk = & tab [n];
To w celu przesunięcia go tak aby wskazywał na następny element tablicy można do niego dodać 1 , np.:
Wsk = wsk + 1 lub wsk ++
+wskaźnik możńa przesunąć o n elementów tablicy (niezależnie od typu elementów) instrukcją
+ Wsk += n; //rónoznaczne z wsk = wsk + n
+przy dodawaniu (i odejmowaniu) do wskaźników liczb całkowitych, należy uważać żeby nie wkaza na miejsce poza tablicą w którym znajduje się coś innego lub przypadkowego bo można to zniszczyć.
+Wskaźniki wskazujące elementy należące do tej samej tablicy można odejmować. W wyniku czego otrzymuje się liczbę (dodatnią lub ujemną) dzielących elementów tablicy.
+Wskaźniki można porównywać przy użyciu operatorów = != <> <= >=
+równość wskaźników oznacza że wskazują one na ten sam obiekt np.:
Int *wsk1, *wsk2;
If (wsk1 == wsk2) cout <<”wskaźniki pokazują to samo”;
+różne wskaźniki wskazują różne obiekty.
+Jeśli dwa wskaźniki pokazują na dwa różne elementy tej samej tablicy, to wskaźnikmniejszy pokazuje na element o niższym indeksie, np.;
Int tab [5];
Int *wsk1, *wsk2;[i];
Wsk1 + &tab [3]; wsk2 = &tab
If (wsk2 < wsk1) cout <<”tab[i] jest elementem tablicy o indeksie mniejszym od 3”;
+można porównywać wskaźniki wskazujące na obiekty tego samego tyu, nawet jeśli nie należą one do tej samej tablicy. Pozwala to określić jak w pamięci komputera ulokowane są względem siebie te obiekty.
+Każdy wskaźnik można porównywać z adresem zero (NULL), np.; wsk = 0 lub wsk = null;
+Pry przekazywaniu argumentów do funkcji przez wartość , funkcja otrzymuje kopię zmiennej, która po wyjściu z funkcji jest niszczona no:
Int funkcja1 (int z); //deklaracja funkcji
Int x, y = 3;
X = funkcja1 (y); //deklaracja zmiennych i wywołanie funkcji
+Definicja funkcji ma postać:
Int funkcja (int z);
{ z +=150;
+Wywołanie funcji postaci:
Int m = 20; funkcja 1(m);
Nie powoduje w programie zmiany obiektu m.
+Jeśli chcemy zmienić ten obiekt, to można w definicji funkcji wykorzystać instrukcję return,
Int funkcja1 (int z);
{z += 150 ;
Return (z); }
….
+W tym przypadku do funkcji zostaje przekazana przez wartość zmienna m i na stosie tworzony jest lokalny obiekt automatyczny typu int , do którego dodawana jest wartość 150. Funkcja kończy się instrukcją return(z) gdzie z jest wyrażeniem, którego wartość stanowi rezultat funkcji. Jest on podstawiony do obiektu m, powodując jego modyfikację.
+Jeżeli byśmy przekazali do funkcji argument wskaźnika to nastąpiło by przekazanie przez adres i wtedy bez funkcji liter ta funkcja zostałaby zmieniona
+ gdy funkcja ma zmienić więcej niż jeden obiekt można jako argument funkcji wykorzystać wskaźnik do obiektu określonego typu np.:
Void funkcja2 (INT *WSK_Z);
{ *wsk_z=20;} //do wskazywanego o obiektu wsawiane jest 20
Funkcja wywołujemy przesułając adres do zmiennej, który służy tej funkcji do inicjalizacji wskaźnika do obiektu int:
Int x= 5;
Funkcja 2 (&x);
+ funkcja ta wstawi wartość 20 do obiektu x. Po wyjściu z funkcji zniszczony zostaje przechowywany na stosie wskaźnik do obiektu natomiast obiekt zachowuje zmienną wartość.
+Funkcję tę można wywołać w programie wielokrotnie, dla tóżnych adresów innch obiektów typu int, np.:
Int y=7;
Funkcja2 (&y) //funkcja wstawi 20 do obiektu y
+Można również wywołać funkcję dla elementu tablicy, np.:
Int tab [10]
Funkcja2 (&tab [4]);
Lub w pętli, dla elementów od 3 do &
For (int i = 3 ; i<=7 ; i++
{
Funkcja2 (&tab [i]);
}
+Jeśli wysyłamy do funkcji konkretne elementy funkcji tablicy, to są one przesyłane przez wartość jak inne obiekty i funkcja otrzymuje do dyspozycji ich kopię.
+Jeśli wyłamy do funkcji tablicę jako całość to nie są wysyłane kopie wszystkich jej elementów tylko jej adres a więc funkcja może pracować na oryginałach elementów i je zmieniać, np.:
Int tablica [20] // deklaracja tablicy
Void funkcja3 (int tab1 []);
// nazwa tablicy jet adresem jej początku
Funkcja3 (tab1ica);
// wywołanie funkcji z argumentem - cała tablica
+Jest to wywołanie funcji z argumentem będącym adresem jej zerowego elementu.
+Tablicę można wysłać do funkcji jako tablicę a odebrać jako tablicę lub jako wskaźnik, np.:
#include <iostream.h>
Void funkcja4 (int tab2 [], int rozmiar);
// do funkcji wysłana jest tablica - jej nazwa
Void funkcja5 (int *wsk, int rozmiar);
//do funkcji wylany jest wskaźnik
Main()
Int tab2 [5] = {3,5,7,2,9};
{ funkcja4 (tab2, 5); //wywołanie z argumentem - cała tablica
Funkcja 5 (tab2, 5); } //wywołanie z argumentem - wskaźnik
+W tym 2 przypadku przesłany adres tablicy inicjalizuje lokalny wskaźnik, wewnątrz funkcji int *wsk = tab2 ;
+Odebranie przez funkcję tablicy jako całej tablicy jest czytelniejsze ale odebranie tablicy jako wskaźnika przyśpiesza działanie funkcji która szybciej znajduje według wskaźnika potrzebne elementy.
+Przy przesyłaniu tablicy do funkcji przez przesłanie jej adresu funkcja pracuje na oryginale tablicy i może zmieniać jej elementy. Jeśli chcemy, żeby funkcja tylko czytałą elementy tablicy, ale ich nie zmienia posługujemy się wskaźnikiem do stałego obiektu.
Taki wskaźnik definiowany jest przy pomocy słowa const, np.:
Const int *wsk = tablica;
Wtedy deklaracj adunkcji może mieć np.: postać:
Void funkcja (const int *wsk, int liczba);
Natomiast wywołanie funkcji będzie : funkcja (tablica,5);
+Wskaźnik do stałego obiektu uniemożliwia jakąkolwiek modyfikację obiektu na który wskazuje.
+obiekt (tablica) wskazywany przez wskaźnik do stałego obiektu nie jest obiektem stałym ale nie może być w funkcji zmieniony.
+Taki wskaźnik może również służyć do skazywania na obiekt stały np.:
Const int wartość = 10];
Const int *wsk_st;
Wsk_st = wartość;
+Na obiekt stały nie można ustawić zwykłego wskaźnika.
ZASTOSOWANIE WSKAŹNIKÓW DO DOSTĘPU DO OKREŚLONYCH KOMÓREK PAMIĘCI
+wskaźniki umożliwiają bezpośredni Dostęp do określonych komórek pamięci, bez podawania jej nazwy. W tymcelu ustaqiwamy wskaźnik na daną komórkę wpisując do niego adres np.:
Wsk = 25432
+należy w tym przypadku uwzględnić sposób adresowania dla konkretnego typu komputera. Określone to jest w kompilatorze.
+Po ustawieniu wksaźńika można go normalnie wykorzystywać np.:
Cout <<”Wartość zapisana w komórce wynosi”<<wsk;
REZERWACJA OBSZRÓW PAMIĘCI
+wskaźniki służą do dynamicznej alokacji )rezerwacji) tablic. Służy do tego operator New wykorzystywany d o tworzenia obiektów.
+Stosowane to jest wtedy gdy:
- nie znamy rozmiaru tablicy
- rozmiar tablicy ylega zmianie
- tablica jest zbyt duża (linker akceptuje łączny rozmiar komórek z danymi nie przekraczającymi 64kB)
+Operator New służy do trorzenia obiektow np.:
Chra *wsk; //definicja ws
27.11.2007
REZERWACJA OBSZARÓW PAMIĘCI
+tworzony obiekt typu char nie ma nazwy a jedynie jego adres przekazywany jest wskaźnikowi
Char *wsk1;
Wsk1=New chat [10];
Delete [];
+tak utworzone obiekty mają czas życia od chwili utorzenia do chili ich usunięcia
+nie obowiązują ich zasady zakresu ważności ; są one zawsze ważne, jeśli dostępny jest wskaźnik który na nie wskazuje.
+… Obiekty te jeśli są tworzone w funkcji znikają po wyjściu z funkcji ponieważ nie są tworzone na stosie ale w obszarze pamięci przeznaczonym do swobodnego używania a informacja o ich adresie przesyłana jest jako rezultat fukcji.
+obiekt tworzony operatorem New istnieje aż do momentu instrukcją delete.
+Obiekty te jeśli nie są zainicjalizowane nie będą tak jak zwykłe obiekty zainicjalizowane zerami ale zawierają śmieci.
+Można go zainicjalizować w chwili tworzenia np.:
Int * wsk ;
Wsk = New int [32];
Wsk = adr new int (32);
+taki obiekt można tówniez umieścić w zapasie pamięci w określonym miejscu wskazanym wskaźnikiem adr ustawionym na określony adres instrukcją
Wsk = adr new int (32);
Dynamiczna alokacja tablic
+Za pomocą operatora new można tworzyć także tablice, np.:
Int *wsk_tab;
Wsk_tab = new int [rozmiar];
+Rozmiar tablicy nie miusi być stałą, a jest definiowany dynamicznie w trakcie wykonywania programu np.:
Int rozm;
Cout <<”Podaj rozmiar tablicy\n”;
Cin >>rozm;
Int *wsk_tab = new int [ rozm ];
*wsk_tab = 10; // wpisanie wartości do zerowego elementu tablicy
Wsk_tab [0] = 10;
*( wsk_tab + 4 ) = 20 // wpisanie do elementu 5-ego (o indeksie 4)
Wsk_tab [4] = 20;
+Tablicę likwidujemy instrukcją
Delete [] wsk_tab;
+Wynik działania operatora delete jest typu void (nie zwracany jest żaden typ)
+Nie należy dwukrotnie kasować obiektu. Aby się przed tym ustrzec, można wraz z kasowaniem obiektu ustawic wskaźnik na obiekt NULL (nie wskazuje) np.;
Wsk_tab = NULL;
+Należy uważać aby nie utracić kontaktu z obiektem np. przez przypisanie do siebie dwóch wskaźników bo wówczas jego skasowanie będzie niemożliwe.
+Może to prowadzić do wyczerpania zapasu pamięci. Wówczas próba utworzenia nowego obiektu da w rezultacie nie adres obiektu ale NULL (zero).
+Można to sprawdzać za pomocą instrukcji warunkowej:
If (wsk) //if (wsk == NULL)
{
Error (“brak pamięci”)
}
+Istnieją funkcje standardowe w bibliotece <new.h> praz <stdlib.h> które w momencie wyczerpania zapasu pamięci spowodują wyjście z programu.
+Oprócz wskaźników traktujących obiekt jako stały (którego nie można zmienić) istnieją jeszcze wskaźniki stałe to znaczy wskazujące zawsze na stały adres w pamięci. Definiujemy go następująco:
Int obiekt_1;
Int *const wsk = &obiekt_1;
+Wskaźnik stały powinien być w definicji inicjalizowany, to znaczy ustawiany na adres obiektu który ten wskaźnika wskazuje.
+Stały wskaźnik a więc taki , który zawsze pokazuje na to samo można połączyć ze wskaźnikiem do stałego obiektu to znaczy takim który pokazywany obiekt traktuje jako stały i nie może go modyfikować.
+Definicja nieruchomego wskaźnika do niezmiennego dla tego wskaźnika obiektu ma przykładową postać:
Const float * const wsk_2;
W tym przypadku stały wskaźnik wsk_2 pokazuje na obiekt typu float, którego nie może zmienić
+Wskaźniki stałe domyślnie inicjalizowane są zerami (wskazują na adres zerowy - NULL)
+Wskaźniki nie stałe trzeba koniecznie inicjalizować, gdyż inaczej mogą pokazywać na przypadkowe miejsce w pamięci wprowadzając błędy logiczne.
INICJALIZACJA WSKAŹNIKÓW
Rozróżnia się następujące sposoby inicjalizacji wskaźników:
+Przez wstawienie do niego adresu wybranego obiektu np.:
Wsk = & obiekt;
+Przy pomocy operacji przypisania wskaźników np.:
Wsk = wsk1;
+Przez wstawienie do niego adresu tablicy lub jej elementu np.:
Wsk = tablica; wsk = &tab[0]; wsk=&tab[2];
+Wskaźnik może wskazywać także na funkcję np.:
Wsk_fun = funkcja ;
+Wskaźnik może wskazywać na adres nowego obiektu utworzonego operatorem new, np.:
Float *wsk;
Wsk = new float;
+Wskaźnik może wskazywać jakieś konkretne miejsce w pamięci.
Wsk = 2005305
+W komputerach IBM PC do takiego ustawienia wskaźnika słyży makrodefinicja
Wsk = MK_FP ( segment, offset);
+Wskaźnik może wskazywać na ciąg znakó (string), to znaczy na adres początku tego ciągu np:
Wsk = „to jest ciąg znaków”
Nie można tego stosować do tablic.
TABLICE WSKAŹNIKÓW
+Tablica wskaźników jest to ciąg adresów zajmujący ciągły obszar w pamięci wskazujących na zmienne tego samego typu, np.: 7 - elementowa tablica wskaźników, wskazujących obiekty typu float ma postać:
Float *tabwsk [7]
+definicję tę można zapisać przy użyciu nawiasów (wówczas jest konieczna znajomość kolejności działania operatorów) w postaci:
Float *( tabwsk [7] );
WSKAŹNIKI FUNKCJI
+Wskaźnik kofunkcji wskazuje adres miejsca w pamięci, w który zaczyna się kod danej funkcji.
+Definicja przykładowego wskaźnika do funkcji bez argumentów ma postać:
Int funkcja (); //definicja funkcji
Int (*wsk_fun) (); //definicja wskaźnika do tej funkcji
+Zapis int *wf (); oznaczałoby dekalację funkcji wf bez argumentów a zwracających wskaźnika do tej funkcji typu int dlatego, że nawiasy są silniejsze niż gwiazdka.
+W przypadku funkcji z argumentami , zwracającej wartość typu float np.:
Float funkcja1 (int, int);
Definicja wskaźnika do tej funkcji ma postać:
Float (*wsk_fun1)(int, int);
+Typ wskaźnika do funkcji musi się zgadzać z typem funckji. Na wskaźnikach do funkcji nie wolno robić operacji arytmetycznych.
+W instrukcji switch do wskaźnika zostaje wpisany adres funkcji, to znaczy nazwa funkcji (bez nawiasów), która jest jednocześnie jej adresem.
+ Wpisanie funkcji z nawiasami np.:
Wsk_fun = fun_pierwsza ();
Oznaczałoby wywołanie funkcji i wstawienie jej rezultatu do wskaźnika wsk_fun.
+Nawiasy są operatorem wywołania funkcji.
Funkcję można wywołać za pomocą jej nazwy np.:
Fun_pierwsza();
Oraz dwoma sposobami za pomocą wskaźnika
(*wsk_fun)(); lub
Wsk_fun ();
Wskaźniki do funkcji stosujemy:
przy przesyłaniu argumentów do funkcji
do tworzenia tablic ze wskaźników do funkcji
Przesyłanie argumentów do funkcji ilustruje przykładowy program wsk_fun2:……………..(Grębosz albo strona)
Tworzenie tablic ze wskaźników do funkcji można wykorzystywać do tworzenia listy działań. Przykładowa 5-cio elementowa tablica wskaźników do funkcji wywoływanej bez argumentów, nic nie zawierającej (typu void) ma postać:
Void (*(tab_wsk {5}))();
Można ją zapisać w sposób uproszczony:
Void (*tab_wsk[5] )();
Ilustruje to przykłądowy program wsk_fun3:……………………(Grębosz)
Tablica wskaźników do funkcji pozwala tworzyć menu, oraz zmieniać je podczas wykonywania programu przez przypisanie jakiemuś wskaźnikowi innej funkcji niż na początku programu.
C++ ARGUMENTY W LINII WYWOŁĄNIA PROGRAMU
+Istnieją cztery możliwości deklaracji funkcji main()
main()
main(int argc) - dopuszczalne aczkolwiek rzadko stosowane
main(int argc, char *Arg[]) - najczęściej stosowane
main(int argc, char *Arg[], char *en[])
+Poszczególne parametry oznaczają:
- arge (argument counter) - jest to licznik argumentów, mówiący ile argumentów system operacyjny wysłał do programu (co najmniej jeden - nazwa programu)
- Arg (argument Vector) - tablica argumentów. Jest to tablica wskaźników do ciągów znaków, w której kolejnymi argumentami są adresy stringów (są one kolejnymi parametrami wywołania programu). W wierszy poleceń muszą być one oddzielone od siebie spacją.
- en (argument environ) - tablica wskaźników do stringów zdefiniowane no. W pliku autoexec.bat np. takie jak PATH, PROMPT, BLASTER).
+Jeśli przykładowo chcemy uruchomić program Test z parametrami param1 oraz 15.5 to piszemy:
Test param1 15.5
+Wtedy argument argc = 3, natomiast poszczególne parametry zostaną zapisane w postaci ciągów znaków pod następującymi adresami:
*Arg [0] - „test”
*Arg [1] - „param1”
*Arg [2] - „15.5”
+W programie o nazwie Test.exe jest to realizowane następująco:
#include <iostream.h>
<stdlib.h>
<string.h>
<math.h>
……………………..
(wywoływanie funkcji - wskaźnik tablice)
(WWW.janiny.com/Bruce-eckel/ grembosz (funkcji tablic wskaźników po tym semestrze)